+ *
+ * @author Nicolas Grekas
+ */
+class Psr17Factory implements RequestFactoryInterface, ResponseFactoryInterface, ServerRequestFactoryInterface, StreamFactoryInterface, UploadedFileFactoryInterface, UriFactoryInterface
+{
+ private $requestFactory;
+ private $responseFactory;
+ private $serverRequestFactory;
+ private $streamFactory;
+ private $uploadedFileFactory;
+ private $uriFactory;
+
+ public function __construct(
+ RequestFactoryInterface $requestFactory = null,
+ ResponseFactoryInterface $responseFactory = null,
+ ServerRequestFactoryInterface $serverRequestFactory = null,
+ StreamFactoryInterface $streamFactory = null,
+ UploadedFileFactoryInterface $uploadedFileFactory = null,
+ UriFactoryInterface $uriFactory = null
+ ) {
+ $this->requestFactory = $requestFactory;
+ $this->responseFactory = $responseFactory;
+ $this->serverRequestFactory = $serverRequestFactory;
+ $this->streamFactory = $streamFactory;
+ $this->uploadedFileFactory = $uploadedFileFactory;
+ $this->uriFactory = $uriFactory;
+
+ $this->setFactory($requestFactory);
+ $this->setFactory($responseFactory);
+ $this->setFactory($serverRequestFactory);
+ $this->setFactory($streamFactory);
+ $this->setFactory($uploadedFileFactory);
+ $this->setFactory($uriFactory);
+ }
+
+ /**
+ * @param UriInterface|string $uri
+ */
+ public function createRequest(string $method, $uri): RequestInterface
+ {
+ $factory = $this->requestFactory ?? $this->setFactory(Psr17FactoryDiscovery::findRequestFactory());
+
+ return $factory->createRequest(...\func_get_args());
+ }
+
+ public function createResponse(int $code = 200, string $reasonPhrase = ''): ResponseInterface
+ {
+ $factory = $this->responseFactory ?? $this->setFactory(Psr17FactoryDiscovery::findResponseFactory());
+
+ return $factory->createResponse(...\func_get_args());
+ }
+
+ /**
+ * @param UriInterface|string $uri
+ */
+ public function createServerRequest(string $method, $uri, array $serverParams = []): ServerRequestInterface
+ {
+ $factory = $this->serverRequestFactory ?? $this->setFactory(Psr17FactoryDiscovery::findServerRequestFactory());
+
+ return $factory->createServerRequest(...\func_get_args());
+ }
+
+ public function createServerRequestFromGlobals(array $server = null, array $get = null, array $post = null, array $cookie = null, array $files = null, StreamInterface $body = null): ServerRequestInterface
+ {
+ $server = $server ?? $_SERVER;
+ $request = $this->createServerRequest($server['REQUEST_METHOD'] ?? 'GET', $this->createUriFromGlobals($server), $server);
+
+ return $this->buildServerRequestFromGlobals($request, $server, $files ?? $_FILES)
+ ->withQueryParams($get ?? $_GET)
+ ->withParsedBody($post ?? $_POST)
+ ->withCookieParams($cookie ?? $_COOKIE)
+ ->withBody($body ?? $this->createStreamFromFile('php://input', 'r+'));
+ }
+
+ public function createStream(string $content = ''): StreamInterface
+ {
+ $factory = $this->streamFactory ?? $this->setFactory(Psr17FactoryDiscovery::findStreamFactory());
+
+ return $factory->createStream($content);
+ }
+
+ public function createStreamFromFile(string $filename, string $mode = 'r'): StreamInterface
+ {
+ $factory = $this->streamFactory ?? $this->setFactory(Psr17FactoryDiscovery::findStreamFactory());
+
+ return $factory->createStreamFromFile($filename, $mode);
+ }
+
+ /**
+ * @param resource $resource
+ */
+ public function createStreamFromResource($resource): StreamInterface
+ {
+ $factory = $this->streamFactory ?? $this->setFactory(Psr17FactoryDiscovery::findStreamFactory());
+
+ return $factory->createStreamFromResource($resource);
+ }
+
+ public function createUploadedFile(StreamInterface $stream, int $size = null, int $error = \UPLOAD_ERR_OK, string $clientFilename = null, string $clientMediaType = null): UploadedFileInterface
+ {
+ $factory = $this->uploadedFileFactory ?? $this->setFactory(Psr17FactoryDiscovery::findUploadedFileFactory());
+
+ return $factory->createUploadedFile(...\func_get_args());
+ }
+
+ public function createUri(string $uri = ''): UriInterface
+ {
+ $factory = $this->uriFactory ?? $this->setFactory(Psr17FactoryDiscovery::findUriFactory());
+
+ return $factory->createUri(...\func_get_args());
+ }
+
+ public function createUriFromGlobals(array $server = null): UriInterface
+ {
+ return $this->buildUriFromGlobals($this->createUri(''), $server ?? $_SERVER);
+ }
+
+ private function setFactory($factory)
+ {
+ if (!$this->requestFactory && $factory instanceof RequestFactoryInterface) {
+ $this->requestFactory = $factory;
+ }
+ if (!$this->responseFactory && $factory instanceof ResponseFactoryInterface) {
+ $this->responseFactory = $factory;
+ }
+ if (!$this->serverRequestFactory && $factory instanceof ServerRequestFactoryInterface) {
+ $this->serverRequestFactory = $factory;
+ }
+ if (!$this->streamFactory && $factory instanceof StreamFactoryInterface) {
+ $this->streamFactory = $factory;
+ }
+ if (!$this->uploadedFileFactory && $factory instanceof UploadedFileFactoryInterface) {
+ $this->uploadedFileFactory = $factory;
+ }
+ if (!$this->uriFactory && $factory instanceof UriFactoryInterface) {
+ $this->uriFactory = $factory;
+ }
+
+ return $factory;
+ }
+
+ private function buildServerRequestFromGlobals(ServerRequestInterface $request, array $server, array $files): ServerRequestInterface
+ {
+ $request = $request
+ ->withProtocolVersion(isset($server['SERVER_PROTOCOL']) ? str_replace('HTTP/', '', $server['SERVER_PROTOCOL']) : '1.1')
+ ->withUploadedFiles($this->normalizeFiles($files));
+
+ $headers = [];
+ foreach ($server as $key => $value) {
+ if (0 === strpos($key, 'HTTP_')) {
+ $key = substr($key, 5);
+ } elseif (!\in_array($key, ['CONTENT_TYPE', 'CONTENT_LENGTH', 'CONTENT_MD5'], true)) {
+ continue;
+ }
+ $key = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', $key))));
+
+ $headers[$key] = $value;
+ }
+
+ if (!isset($headers['Authorization'])) {
+ if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
+ $headers['Authorization'] = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
+ } elseif (isset($_SERVER['PHP_AUTH_USER'])) {
+ $headers['Authorization'] = 'Basic '.base64_encode($_SERVER['PHP_AUTH_USER'].':'.($_SERVER['PHP_AUTH_PW'] ?? ''));
+ } elseif (isset($_SERVER['PHP_AUTH_DIGEST'])) {
+ $headers['Authorization'] = $_SERVER['PHP_AUTH_DIGEST'];
+ }
+ }
+
+ foreach ($headers as $key => $value) {
+ try {
+ $request = $request->withHeader($key, $value);
+ } catch (\InvalidArgumentException $e) {
+ // ignore invalid headers
+ }
+ }
+
+ return $request;
+ }
+
+ private function buildUriFromGlobals(UriInterface $uri, array $server): UriInterface
+ {
+ $uri = $uri->withScheme(!empty($server['HTTPS']) && 'off' !== strtolower($server['HTTPS']) ? 'https' : 'http');
+
+ $hasPort = false;
+ if (isset($server['HTTP_HOST'])) {
+ $parts = parse_url('http://'.$server['HTTP_HOST']);
+
+ $uri = $uri->withHost($parts['host'] ?? 'localhost');
+
+ if ($parts['port'] ?? false) {
+ $hasPort = true;
+ $uri = $uri->withPort($parts['port']);
+ }
+ } else {
+ $uri = $uri->withHost($server['SERVER_NAME'] ?? $server['SERVER_ADDR'] ?? 'localhost');
+ }
+
+ if (!$hasPort && isset($server['SERVER_PORT'])) {
+ $uri = $uri->withPort($server['SERVER_PORT']);
+ }
+
+ $hasQuery = false;
+ if (isset($server['REQUEST_URI'])) {
+ $requestUriParts = explode('?', $server['REQUEST_URI'], 2);
+ $uri = $uri->withPath($requestUriParts[0]);
+ if (isset($requestUriParts[1])) {
+ $hasQuery = true;
+ $uri = $uri->withQuery($requestUriParts[1]);
+ }
+ }
+
+ if (!$hasQuery && isset($server['QUERY_STRING'])) {
+ $uri = $uri->withQuery($server['QUERY_STRING']);
+ }
+
+ return $uri;
+ }
+
+ private function normalizeFiles(array $files): array
+ {
+ $normalized = [];
+
+ foreach ($files as $key => $value) {
+ if ($value instanceof UploadedFileInterface) {
+ $normalized[$key] = $value;
+ } elseif (!\is_array($value)) {
+ continue;
+ } elseif (!isset($value['tmp_name'])) {
+ $normalized[$key] = $this->normalizeFiles($value);
+ } elseif (\is_array($value['tmp_name'])) {
+ foreach ($value['tmp_name'] as $k => $v) {
+ $file = $this->createStreamFromFile($value['tmp_name'][$k], 'r');
+ $normalized[$key][$k] = $this->createUploadedFile($file, $value['size'][$k], $value['error'][$k], $value['name'][$k], $value['type'][$k]);
+ }
+ } else {
+ $file = $this->createStreamFromFile($value['tmp_name'], 'r');
+ $normalized[$key] = $this->createUploadedFile($file, $value['size'], $value['error'], $value['name'], $value['type']);
+ }
+ }
+
+ return $normalized;
+ }
+}
diff --git a/vendor/php-http/discovery/src/Psr17FactoryDiscovery.php b/vendor/php-http/discovery/src/Psr17FactoryDiscovery.php
new file mode 100644
index 000000000..a73c6414b
--- /dev/null
+++ b/vendor/php-http/discovery/src/Psr17FactoryDiscovery.php
@@ -0,0 +1,136 @@
+
+ */
+final class Psr17FactoryDiscovery extends ClassDiscovery
+{
+ private static function createException($type, Exception $e)
+ {
+ return new \Http\Discovery\Exception\NotFoundException(
+ 'No PSR-17 '.$type.' found. Install a package from this list: https://packagist.org/providers/psr/http-factory-implementation',
+ 0,
+ $e
+ );
+ }
+
+ /**
+ * @return RequestFactoryInterface
+ *
+ * @throws Exception\NotFoundException
+ */
+ public static function findRequestFactory()
+ {
+ try {
+ $messageFactory = static::findOneByType(RequestFactoryInterface::class);
+ } catch (DiscoveryFailedException $e) {
+ throw self::createException('request factory', $e);
+ }
+
+ return static::instantiateClass($messageFactory);
+ }
+
+ /**
+ * @return ResponseFactoryInterface
+ *
+ * @throws Exception\NotFoundException
+ */
+ public static function findResponseFactory()
+ {
+ try {
+ $messageFactory = static::findOneByType(ResponseFactoryInterface::class);
+ } catch (DiscoveryFailedException $e) {
+ throw self::createException('response factory', $e);
+ }
+
+ return static::instantiateClass($messageFactory);
+ }
+
+ /**
+ * @return ServerRequestFactoryInterface
+ *
+ * @throws Exception\NotFoundException
+ */
+ public static function findServerRequestFactory()
+ {
+ try {
+ $messageFactory = static::findOneByType(ServerRequestFactoryInterface::class);
+ } catch (DiscoveryFailedException $e) {
+ throw self::createException('server request factory', $e);
+ }
+
+ return static::instantiateClass($messageFactory);
+ }
+
+ /**
+ * @return StreamFactoryInterface
+ *
+ * @throws Exception\NotFoundException
+ */
+ public static function findStreamFactory()
+ {
+ try {
+ $messageFactory = static::findOneByType(StreamFactoryInterface::class);
+ } catch (DiscoveryFailedException $e) {
+ throw self::createException('stream factory', $e);
+ }
+
+ return static::instantiateClass($messageFactory);
+ }
+
+ /**
+ * @return UploadedFileFactoryInterface
+ *
+ * @throws Exception\NotFoundException
+ */
+ public static function findUploadedFileFactory()
+ {
+ try {
+ $messageFactory = static::findOneByType(UploadedFileFactoryInterface::class);
+ } catch (DiscoveryFailedException $e) {
+ throw self::createException('uploaded file factory', $e);
+ }
+
+ return static::instantiateClass($messageFactory);
+ }
+
+ /**
+ * @return UriFactoryInterface
+ *
+ * @throws Exception\NotFoundException
+ */
+ public static function findUriFactory()
+ {
+ try {
+ $messageFactory = static::findOneByType(UriFactoryInterface::class);
+ } catch (DiscoveryFailedException $e) {
+ throw self::createException('url factory', $e);
+ }
+
+ return static::instantiateClass($messageFactory);
+ }
+
+ /**
+ * @return UriFactoryInterface
+ *
+ * @throws Exception\NotFoundException
+ *
+ * @deprecated This will be removed in 2.0. Consider using the findUriFactory() method.
+ */
+ public static function findUrlFactory()
+ {
+ return static::findUriFactory();
+ }
+}
diff --git a/vendor/php-http/discovery/src/Psr18ClientDiscovery.php b/vendor/php-http/discovery/src/Psr18ClientDiscovery.php
new file mode 100644
index 000000000..dfd2dd1e7
--- /dev/null
+++ b/vendor/php-http/discovery/src/Psr18ClientDiscovery.php
@@ -0,0 +1,32 @@
+
+ */
+final class Psr18ClientDiscovery extends ClassDiscovery
+{
+ /**
+ * Finds a PSR-18 HTTP Client.
+ *
+ * @return ClientInterface
+ *
+ * @throws Exception\NotFoundException
+ */
+ public static function find()
+ {
+ try {
+ $client = static::findOneByType(ClientInterface::class);
+ } catch (DiscoveryFailedException $e) {
+ throw new \Http\Discovery\Exception\NotFoundException('No PSR-18 clients found. Make sure to install a package providing "psr/http-client-implementation". Example: "php-http/guzzle7-adapter".', 0, $e);
+ }
+
+ return static::instantiateClass($client);
+ }
+}
diff --git a/vendor/php-http/discovery/src/Strategy/CommonClassesStrategy.php b/vendor/php-http/discovery/src/Strategy/CommonClassesStrategy.php
new file mode 100644
index 000000000..8126e12b0
--- /dev/null
+++ b/vendor/php-http/discovery/src/Strategy/CommonClassesStrategy.php
@@ -0,0 +1,191 @@
+
+ *
+ * Don't miss updating src/Composer/Plugin.php when adding a new supported class.
+ */
+final class CommonClassesStrategy implements DiscoveryStrategy
+{
+ /**
+ * @var array
+ */
+ private static $classes = [
+ MessageFactory::class => [
+ ['class' => NyholmHttplugFactory::class, 'condition' => [NyholmHttplugFactory::class]],
+ ['class' => GuzzleMessageFactory::class, 'condition' => [GuzzleRequest::class, GuzzleMessageFactory::class]],
+ ['class' => DiactorosMessageFactory::class, 'condition' => [ZendDiactorosRequest::class, DiactorosMessageFactory::class]],
+ ['class' => DiactorosMessageFactory::class, 'condition' => [DiactorosRequest::class, DiactorosMessageFactory::class]],
+ ['class' => SlimMessageFactory::class, 'condition' => [SlimRequest::class, SlimMessageFactory::class]],
+ ],
+ StreamFactory::class => [
+ ['class' => NyholmHttplugFactory::class, 'condition' => [NyholmHttplugFactory::class]],
+ ['class' => GuzzleStreamFactory::class, 'condition' => [GuzzleRequest::class, GuzzleStreamFactory::class]],
+ ['class' => DiactorosStreamFactory::class, 'condition' => [ZendDiactorosRequest::class, DiactorosStreamFactory::class]],
+ ['class' => DiactorosStreamFactory::class, 'condition' => [DiactorosRequest::class, DiactorosStreamFactory::class]],
+ ['class' => SlimStreamFactory::class, 'condition' => [SlimRequest::class, SlimStreamFactory::class]],
+ ],
+ UriFactory::class => [
+ ['class' => NyholmHttplugFactory::class, 'condition' => [NyholmHttplugFactory::class]],
+ ['class' => GuzzleUriFactory::class, 'condition' => [GuzzleRequest::class, GuzzleUriFactory::class]],
+ ['class' => DiactorosUriFactory::class, 'condition' => [ZendDiactorosRequest::class, DiactorosUriFactory::class]],
+ ['class' => DiactorosUriFactory::class, 'condition' => [DiactorosRequest::class, DiactorosUriFactory::class]],
+ ['class' => SlimUriFactory::class, 'condition' => [SlimRequest::class, SlimUriFactory::class]],
+ ],
+ HttpAsyncClient::class => [
+ ['class' => SymfonyHttplug::class, 'condition' => [SymfonyHttplug::class, Promise::class, RequestFactory::class, [self::class, 'isPsr17FactoryInstalled']]],
+ ['class' => Guzzle7::class, 'condition' => Guzzle7::class],
+ ['class' => Guzzle6::class, 'condition' => Guzzle6::class],
+ ['class' => Curl::class, 'condition' => Curl::class],
+ ['class' => React::class, 'condition' => React::class],
+ ],
+ HttpClient::class => [
+ ['class' => SymfonyHttplug::class, 'condition' => [SymfonyHttplug::class, RequestFactory::class, [self::class, 'isPsr17FactoryInstalled']]],
+ ['class' => Guzzle7::class, 'condition' => Guzzle7::class],
+ ['class' => Guzzle6::class, 'condition' => Guzzle6::class],
+ ['class' => Guzzle5::class, 'condition' => Guzzle5::class],
+ ['class' => Curl::class, 'condition' => Curl::class],
+ ['class' => Socket::class, 'condition' => Socket::class],
+ ['class' => Buzz::class, 'condition' => Buzz::class],
+ ['class' => React::class, 'condition' => React::class],
+ ['class' => Cake::class, 'condition' => Cake::class],
+ ['class' => Zend::class, 'condition' => Zend::class],
+ ['class' => Artax::class, 'condition' => Artax::class],
+ [
+ 'class' => [self::class, 'buzzInstantiate'],
+ 'condition' => [\Buzz\Client\FileGetContents::class, \Buzz\Message\ResponseBuilder::class],
+ ],
+ ],
+ Psr18Client::class => [
+ [
+ 'class' => [self::class, 'symfonyPsr18Instantiate'],
+ 'condition' => [SymfonyPsr18::class, Psr17RequestFactory::class],
+ ],
+ [
+ 'class' => GuzzleHttp::class,
+ 'condition' => [self::class, 'isGuzzleImplementingPsr18'],
+ ],
+ [
+ 'class' => [self::class, 'buzzInstantiate'],
+ 'condition' => [\Buzz\Client\FileGetContents::class, \Buzz\Message\ResponseBuilder::class],
+ ],
+ ],
+ ];
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function getCandidates($type)
+ {
+ if (Psr18Client::class === $type) {
+ return self::getPsr18Candidates();
+ }
+
+ return self::$classes[$type] ?? [];
+ }
+
+ /**
+ * @return array The return value is always an array with zero or more elements. Each
+ * element is an array with two keys ['class' => string, 'condition' => mixed].
+ */
+ private static function getPsr18Candidates()
+ {
+ $candidates = self::$classes[Psr18Client::class];
+
+ // HTTPlug 2.0 clients implements PSR18Client too.
+ foreach (self::$classes[HttpClient::class] as $c) {
+ if (!is_string($c['class'])) {
+ continue;
+ }
+ try {
+ if (ClassDiscovery::safeClassExists($c['class']) && is_subclass_of($c['class'], Psr18Client::class)) {
+ $candidates[] = $c;
+ }
+ } catch (\Throwable $e) {
+ trigger_error(sprintf('Got exception "%s (%s)" while checking if a PSR-18 Client is available', get_class($e), $e->getMessage()), E_USER_WARNING);
+ }
+ }
+
+ return $candidates;
+ }
+
+ public static function buzzInstantiate()
+ {
+ return new \Buzz\Client\FileGetContents(MessageFactoryDiscovery::find());
+ }
+
+ public static function symfonyPsr18Instantiate()
+ {
+ return new SymfonyPsr18(null, Psr17FactoryDiscovery::findResponseFactory(), Psr17FactoryDiscovery::findStreamFactory());
+ }
+
+ public static function isGuzzleImplementingPsr18()
+ {
+ return defined('GuzzleHttp\ClientInterface::MAJOR_VERSION');
+ }
+
+ /**
+ * Can be used as a condition.
+ *
+ * @return bool
+ */
+ public static function isPsr17FactoryInstalled()
+ {
+ try {
+ Psr17FactoryDiscovery::findResponseFactory();
+ } catch (NotFoundException $e) {
+ return false;
+ } catch (\Throwable $e) {
+ trigger_error(sprintf('Got exception "%s (%s)" while checking if a PSR-17 ResponseFactory is available', get_class($e), $e->getMessage()), E_USER_WARNING);
+
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/vendor/php-http/discovery/src/Strategy/CommonPsr17ClassesStrategy.php b/vendor/php-http/discovery/src/Strategy/CommonPsr17ClassesStrategy.php
new file mode 100644
index 000000000..0a0b8c82a
--- /dev/null
+++ b/vendor/php-http/discovery/src/Strategy/CommonPsr17ClassesStrategy.php
@@ -0,0 +1,107 @@
+
+ *
+ * Don't miss updating src/Composer/Plugin.php when adding a new supported class.
+ */
+final class CommonPsr17ClassesStrategy implements DiscoveryStrategy
+{
+ /**
+ * @var array
+ */
+ private static $classes = [
+ RequestFactoryInterface::class => [
+ 'Phalcon\Http\Message\RequestFactory',
+ 'Nyholm\Psr7\Factory\Psr17Factory',
+ 'Zend\Diactoros\RequestFactory',
+ 'GuzzleHttp\Psr7\HttpFactory',
+ 'Http\Factory\Diactoros\RequestFactory',
+ 'Http\Factory\Guzzle\RequestFactory',
+ 'Http\Factory\Slim\RequestFactory',
+ 'Laminas\Diactoros\RequestFactory',
+ 'Slim\Psr7\Factory\RequestFactory',
+ ],
+ ResponseFactoryInterface::class => [
+ 'Phalcon\Http\Message\ResponseFactory',
+ 'Nyholm\Psr7\Factory\Psr17Factory',
+ 'Zend\Diactoros\ResponseFactory',
+ 'GuzzleHttp\Psr7\HttpFactory',
+ 'Http\Factory\Diactoros\ResponseFactory',
+ 'Http\Factory\Guzzle\ResponseFactory',
+ 'Http\Factory\Slim\ResponseFactory',
+ 'Laminas\Diactoros\ResponseFactory',
+ 'Slim\Psr7\Factory\ResponseFactory',
+ ],
+ ServerRequestFactoryInterface::class => [
+ 'Phalcon\Http\Message\ServerRequestFactory',
+ 'Nyholm\Psr7\Factory\Psr17Factory',
+ 'Zend\Diactoros\ServerRequestFactory',
+ 'GuzzleHttp\Psr7\HttpFactory',
+ 'Http\Factory\Diactoros\ServerRequestFactory',
+ 'Http\Factory\Guzzle\ServerRequestFactory',
+ 'Http\Factory\Slim\ServerRequestFactory',
+ 'Laminas\Diactoros\ServerRequestFactory',
+ 'Slim\Psr7\Factory\ServerRequestFactory',
+ ],
+ StreamFactoryInterface::class => [
+ 'Phalcon\Http\Message\StreamFactory',
+ 'Nyholm\Psr7\Factory\Psr17Factory',
+ 'Zend\Diactoros\StreamFactory',
+ 'GuzzleHttp\Psr7\HttpFactory',
+ 'Http\Factory\Diactoros\StreamFactory',
+ 'Http\Factory\Guzzle\StreamFactory',
+ 'Http\Factory\Slim\StreamFactory',
+ 'Laminas\Diactoros\StreamFactory',
+ 'Slim\Psr7\Factory\StreamFactory',
+ ],
+ UploadedFileFactoryInterface::class => [
+ 'Phalcon\Http\Message\UploadedFileFactory',
+ 'Nyholm\Psr7\Factory\Psr17Factory',
+ 'Zend\Diactoros\UploadedFileFactory',
+ 'GuzzleHttp\Psr7\HttpFactory',
+ 'Http\Factory\Diactoros\UploadedFileFactory',
+ 'Http\Factory\Guzzle\UploadedFileFactory',
+ 'Http\Factory\Slim\UploadedFileFactory',
+ 'Laminas\Diactoros\UploadedFileFactory',
+ 'Slim\Psr7\Factory\UploadedFileFactory',
+ ],
+ UriFactoryInterface::class => [
+ 'Phalcon\Http\Message\UriFactory',
+ 'Nyholm\Psr7\Factory\Psr17Factory',
+ 'Zend\Diactoros\UriFactory',
+ 'GuzzleHttp\Psr7\HttpFactory',
+ 'Http\Factory\Diactoros\UriFactory',
+ 'Http\Factory\Guzzle\UriFactory',
+ 'Http\Factory\Slim\UriFactory',
+ 'Laminas\Diactoros\UriFactory',
+ 'Slim\Psr7\Factory\UriFactory',
+ ],
+ ];
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function getCandidates($type)
+ {
+ $candidates = [];
+ if (isset(self::$classes[$type])) {
+ foreach (self::$classes[$type] as $class) {
+ $candidates[] = ['class' => $class, 'condition' => [$class]];
+ }
+ }
+
+ return $candidates;
+ }
+}
diff --git a/vendor/php-http/discovery/src/Strategy/DiscoveryStrategy.php b/vendor/php-http/discovery/src/Strategy/DiscoveryStrategy.php
new file mode 100644
index 000000000..1eadb145b
--- /dev/null
+++ b/vendor/php-http/discovery/src/Strategy/DiscoveryStrategy.php
@@ -0,0 +1,23 @@
+
+ */
+interface DiscoveryStrategy
+{
+ /**
+ * Find a resource of a specific type.
+ *
+ * @param string $type
+ *
+ * @return array The return value is always an array with zero or more elements. Each
+ * element is an array with two keys ['class' => string, 'condition' => mixed].
+ *
+ * @throws StrategyUnavailableException if we cannot use this strategy
+ */
+ public static function getCandidates($type);
+}
diff --git a/vendor/php-http/discovery/src/Strategy/MockClientStrategy.php b/vendor/php-http/discovery/src/Strategy/MockClientStrategy.php
new file mode 100644
index 000000000..0cee3f7ed
--- /dev/null
+++ b/vendor/php-http/discovery/src/Strategy/MockClientStrategy.php
@@ -0,0 +1,27 @@
+
+ */
+final class MockClientStrategy implements DiscoveryStrategy
+{
+ /**
+ * {@inheritdoc}
+ */
+ public static function getCandidates($type)
+ {
+ if (is_a(HttpClient::class, $type, true) || is_a(HttpAsyncClient::class, $type, true)) {
+ return [['class' => Mock::class, 'condition' => Mock::class]];
+ }
+
+ return [];
+ }
+}
diff --git a/vendor/php-http/discovery/src/Strategy/PuliBetaStrategy.php b/vendor/php-http/discovery/src/Strategy/PuliBetaStrategy.php
new file mode 100644
index 000000000..6b3a862da
--- /dev/null
+++ b/vendor/php-http/discovery/src/Strategy/PuliBetaStrategy.php
@@ -0,0 +1,93 @@
+
+ * @author Márk Sági-Kazár
+ */
+class PuliBetaStrategy implements DiscoveryStrategy
+{
+ /**
+ * @var GeneratedPuliFactory
+ */
+ protected static $puliFactory;
+
+ /**
+ * @var Discovery
+ */
+ protected static $puliDiscovery;
+
+ /**
+ * @return GeneratedPuliFactory
+ *
+ * @throws PuliUnavailableException
+ */
+ private static function getPuliFactory()
+ {
+ if (null === self::$puliFactory) {
+ if (!defined('PULI_FACTORY_CLASS')) {
+ throw new PuliUnavailableException('Puli Factory is not available');
+ }
+
+ $puliFactoryClass = PULI_FACTORY_CLASS;
+
+ if (!ClassDiscovery::safeClassExists($puliFactoryClass)) {
+ throw new PuliUnavailableException('Puli Factory class does not exist');
+ }
+
+ self::$puliFactory = new $puliFactoryClass();
+ }
+
+ return self::$puliFactory;
+ }
+
+ /**
+ * Returns the Puli discovery layer.
+ *
+ * @return Discovery
+ *
+ * @throws PuliUnavailableException
+ */
+ private static function getPuliDiscovery()
+ {
+ if (!isset(self::$puliDiscovery)) {
+ $factory = self::getPuliFactory();
+ $repository = $factory->createRepository();
+
+ self::$puliDiscovery = $factory->createDiscovery($repository);
+ }
+
+ return self::$puliDiscovery;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function getCandidates($type)
+ {
+ $returnData = [];
+ $bindings = self::getPuliDiscovery()->findBindings($type);
+
+ foreach ($bindings as $binding) {
+ $condition = true;
+ if ($binding->hasParameterValue('depends')) {
+ $condition = $binding->getParameterValue('depends');
+ }
+ $returnData[] = ['class' => $binding->getClassName(), 'condition' => $condition];
+ }
+
+ return $returnData;
+ }
+}
diff --git a/vendor/php-http/discovery/src/StreamFactoryDiscovery.php b/vendor/php-http/discovery/src/StreamFactoryDiscovery.php
new file mode 100644
index 000000000..e11c49ae2
--- /dev/null
+++ b/vendor/php-http/discovery/src/StreamFactoryDiscovery.php
@@ -0,0 +1,34 @@
+
+ *
+ * @deprecated This will be removed in 2.0. Consider using Psr17FactoryDiscovery.
+ */
+final class StreamFactoryDiscovery extends ClassDiscovery
+{
+ /**
+ * Finds a Stream Factory.
+ *
+ * @return StreamFactory
+ *
+ * @throws Exception\NotFoundException
+ */
+ public static function find()
+ {
+ try {
+ $streamFactory = static::findOneByType(StreamFactory::class);
+ } catch (DiscoveryFailedException $e) {
+ throw new NotFoundException('No stream factories found. To use Guzzle, Diactoros or Slim Framework factories install php-http/message and the chosen message implementation.', 0, $e);
+ }
+
+ return static::instantiateClass($streamFactory);
+ }
+}
diff --git a/vendor/php-http/discovery/src/UriFactoryDiscovery.php b/vendor/php-http/discovery/src/UriFactoryDiscovery.php
new file mode 100644
index 000000000..db3add206
--- /dev/null
+++ b/vendor/php-http/discovery/src/UriFactoryDiscovery.php
@@ -0,0 +1,34 @@
+
+ *
+ * @deprecated This will be removed in 2.0. Consider using Psr17FactoryDiscovery.
+ */
+final class UriFactoryDiscovery extends ClassDiscovery
+{
+ /**
+ * Finds a URI Factory.
+ *
+ * @return UriFactory
+ *
+ * @throws Exception\NotFoundException
+ */
+ public static function find()
+ {
+ try {
+ $uriFactory = static::findOneByType(UriFactory::class);
+ } catch (DiscoveryFailedException $e) {
+ throw new NotFoundException('No uri factories found. To use Guzzle, Diactoros or Slim Framework factories install php-http/message and the chosen message implementation.', 0, $e);
+ }
+
+ return static::instantiateClass($uriFactory);
+ }
+}
diff --git a/vendor/php-http/guzzle7-adapter/CHANGELOG.md b/vendor/php-http/guzzle7-adapter/CHANGELOG.md
new file mode 100644
index 000000000..9aa94407b
--- /dev/null
+++ b/vendor/php-http/guzzle7-adapter/CHANGELOG.md
@@ -0,0 +1,18 @@
+# Change Log
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
+and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
+
+## [1.0.0] - 2021-03-09
+
+- Stable release - no changes since 0.1.1
+
+## [0.1.1] - 2020-10-21
+
+* Allow installation with PHP 8
+
+## [0.1.0] - 2020-08-16
+
+First release
diff --git a/vendor/php-http/guzzle7-adapter/LICENSE b/vendor/php-http/guzzle7-adapter/LICENSE
new file mode 100644
index 000000000..0d6ce83b8
--- /dev/null
+++ b/vendor/php-http/guzzle7-adapter/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2020 PHP HTTP Team
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/php-http/guzzle7-adapter/README.md b/vendor/php-http/guzzle7-adapter/README.md
new file mode 100644
index 000000000..7e6b5b5dc
--- /dev/null
+++ b/vendor/php-http/guzzle7-adapter/README.md
@@ -0,0 +1,45 @@
+# Guzzle 7 HTTP Adapter
+
+[](https://github.com/php-http/guzzle7-adapter/releases)
+[](LICENSE)
+[](https://packagist.org/packages/php-http/guzzle7-adapter)
+
+**Guzzle 7 HTTP Adapter.**
+
+## Install
+
+Via Composer
+
+``` bash
+$ composer require php-http/guzzle7-adapter
+```
+
+## Documentation
+
+Please see the [official documentation](http://docs.php-http.org/en/latest/clients/guzzle7-adapter.html).
+
+## Testing
+
+First launch the http server:
+
+```bash
+$ ./vendor/bin/http_test_server > /dev/null 2>&1 &
+```
+
+Then the test suite:
+
+``` bash
+$ composer test
+```
+
+## Contributing
+
+Please see our [contributing guide](http://docs.php-http.org/en/latest/development/contributing.html).
+
+## Security
+
+If you discover any security related issues, please contact us at [security@php-http.org](mailto:security@php-http.org).
+
+## License
+
+The MIT License (MIT). Please see [License File](LICENSE) for more information.
diff --git a/vendor/php-http/guzzle7-adapter/composer.json b/vendor/php-http/guzzle7-adapter/composer.json
new file mode 100644
index 000000000..3299d2eb7
--- /dev/null
+++ b/vendor/php-http/guzzle7-adapter/composer.json
@@ -0,0 +1,43 @@
+{
+ "name": "php-http/guzzle7-adapter",
+ "description": "Guzzle 7 HTTP Adapter",
+ "license": "MIT",
+ "keywords": ["guzzle", "http"],
+ "homepage": "http://httplug.io",
+ "authors": [
+ {
+ "name": "Tobias Nyholm",
+ "email": "tobias.nyholm@gmail.com"
+ }
+ ],
+ "require": {
+ "php": "^7.2 | ^8.0",
+ "php-http/httplug": "^2.0",
+ "psr/http-client": "^1.0",
+ "guzzlehttp/guzzle": "^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^8.0|^9.3",
+ "php-http/client-integration-tests": "^3.0"
+ },
+ "provide": {
+ "php-http/client-implementation": "1.0",
+ "php-http/async-client-implementation": "1.0",
+ "psr/http-client-implementation": "1.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "Http\\Adapter\\Guzzle7\\": "src/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Http\\Adapter\\Guzzle7\\Tests\\": "tests/"
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "0.2.x-dev"
+ }
+ }
+}
diff --git a/vendor/php-http/guzzle7-adapter/phpstan.neon.dist b/vendor/php-http/guzzle7-adapter/phpstan.neon.dist
new file mode 100644
index 000000000..d42940e93
--- /dev/null
+++ b/vendor/php-http/guzzle7-adapter/phpstan.neon.dist
@@ -0,0 +1,5 @@
+parameters:
+ level: 5
+ reportUnmatchedIgnoredErrors: false
+ paths:
+ - src
diff --git a/vendor/php-http/guzzle7-adapter/psalm.baseline.xml b/vendor/php-http/guzzle7-adapter/psalm.baseline.xml
new file mode 100644
index 000000000..96ab42cf9
--- /dev/null
+++ b/vendor/php-http/guzzle7-adapter/psalm.baseline.xml
@@ -0,0 +1,8 @@
+
+
+
+
+ $exception->getResponse()
+
+
+
diff --git a/vendor/php-http/guzzle7-adapter/psalm.xml b/vendor/php-http/guzzle7-adapter/psalm.xml
new file mode 100644
index 000000000..d70acfe4f
--- /dev/null
+++ b/vendor/php-http/guzzle7-adapter/psalm.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
diff --git a/vendor/php-http/guzzle7-adapter/src/Client.php b/vendor/php-http/guzzle7-adapter/src/Client.php
new file mode 100644
index 000000000..a92ab06bd
--- /dev/null
+++ b/vendor/php-http/guzzle7-adapter/src/Client.php
@@ -0,0 +1,75 @@
+
+ */
+final class Client implements HttpClient, HttpAsyncClient
+{
+ /**
+ * @var ClientInterface
+ */
+ private $guzzle;
+
+ public function __construct(?ClientInterface $guzzle = null)
+ {
+ if (!$guzzle) {
+ $guzzle = self::buildClient();
+ }
+
+ $this->guzzle = $guzzle;
+ }
+
+ /**
+ * Factory method to create the Guzzle 7 adapter with custom Guzzle configuration.
+ */
+ public static function createWithConfig(array $config): Client
+ {
+ return new self(self::buildClient($config));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sendRequest(RequestInterface $request): ResponseInterface
+ {
+ return $this->sendAsyncRequest($request)->wait();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sendAsyncRequest(RequestInterface $request)
+ {
+ $promise = $this->guzzle->sendAsync($request);
+
+ return new Promise($promise, $request);
+ }
+
+ /**
+ * Build the Guzzle client instance.
+ */
+ private static function buildClient(array $config = []): GuzzleClient
+ {
+ $handlerStack = new HandlerStack(Utils::chooseHandler());
+ $handlerStack->push(Middleware::prepareBody(), 'prepare_body');
+ $config = array_merge(['handler' => $handlerStack], $config);
+
+ return new GuzzleClient($config);
+ }
+}
diff --git a/vendor/php-http/guzzle7-adapter/src/Exception/UnexpectedValueException.php b/vendor/php-http/guzzle7-adapter/src/Exception/UnexpectedValueException.php
new file mode 100644
index 000000000..f4731be07
--- /dev/null
+++ b/vendor/php-http/guzzle7-adapter/src/Exception/UnexpectedValueException.php
@@ -0,0 +1,9 @@
+
+ */
+final class Promise implements HttpPromise
+{
+ /**
+ * @var PromiseInterface
+ */
+ private $promise;
+
+ /**
+ * @var string State of the promise
+ */
+ private $state;
+
+ /**
+ * @var ResponseInterface
+ */
+ private $response;
+
+ /**
+ * @var HttplugException
+ */
+ private $exception;
+
+ /**
+ * @var RequestInterface
+ */
+ private $request;
+
+ public function __construct(PromiseInterface $promise, RequestInterface $request)
+ {
+ $this->request = $request;
+ $this->state = self::PENDING;
+ $this->promise = $promise->then(function ($response) {
+ $this->response = $response;
+ $this->state = self::FULFILLED;
+
+ return $response;
+ }, function ($reason) use ($request) {
+ $this->state = self::REJECTED;
+
+ if ($reason instanceof HttplugException) {
+ $this->exception = $reason;
+ } elseif ($reason instanceof GuzzleExceptions\GuzzleException) {
+ $this->exception = $this->handleException($reason, $request);
+ } elseif ($reason instanceof \Throwable) {
+ $this->exception = new HttplugException\TransferException('Invalid exception returned from Guzzle7', 0, $reason);
+ } else {
+ $this->exception = new UnexpectedValueException('Reason returned from Guzzle7 must be an Exception');
+ }
+
+ throw $this->exception;
+ });
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function then(callable $onFulfilled = null, callable $onRejected = null)
+ {
+ return new static($this->promise->then($onFulfilled, $onRejected), $this->request);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getState()
+ {
+ return $this->state;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function wait($unwrap = true)
+ {
+ $this->promise->wait(false);
+
+ if ($unwrap) {
+ if (self::REJECTED == $this->getState()) {
+ throw $this->exception;
+ }
+
+ return $this->response;
+ }
+ }
+
+ /**
+ * Converts a Guzzle exception into an Httplug exception.
+ *
+ * @return HttplugException
+ */
+ private function handleException(GuzzleExceptions\GuzzleException $exception, RequestInterface $request)
+ {
+ if ($exception instanceof GuzzleExceptions\ConnectException) {
+ return new HttplugException\NetworkException($exception->getMessage(), $exception->getRequest(), $exception);
+ }
+
+ if ($exception instanceof GuzzleExceptions\RequestException) {
+ // Make sure we have a response for the HttpException
+ if ($exception->hasResponse()) {
+ return new HttplugException\HttpException(
+ $exception->getMessage(),
+ $exception->getRequest(),
+ $exception->getResponse(),
+ $exception
+ );
+ }
+
+ return new HttplugException\RequestException($exception->getMessage(), $exception->getRequest(), $exception);
+ }
+
+ return new HttplugException\TransferException($exception->getMessage(), 0, $exception);
+ }
+}
diff --git a/vendor/php-http/httplug/.php-cs-fixer.dist.php b/vendor/php-http/httplug/.php-cs-fixer.dist.php
new file mode 100644
index 000000000..83809c25d
--- /dev/null
+++ b/vendor/php-http/httplug/.php-cs-fixer.dist.php
@@ -0,0 +1,16 @@
+in(__DIR__.'/src')
+ ->name('*.php')
+;
+
+$config = (new PhpCsFixer\Config())
+ ->setRiskyAllowed(true)
+ ->setRules([
+ '@Symfony' => true,
+ ])
+ ->setFinder($finder)
+;
+
+return $config;
diff --git a/vendor/php-http/httplug/CHANGELOG.md b/vendor/php-http/httplug/CHANGELOG.md
new file mode 100644
index 000000000..26483c2c4
--- /dev/null
+++ b/vendor/php-http/httplug/CHANGELOG.md
@@ -0,0 +1,136 @@
+# Change Log
+
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
+and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
+
+
+## [Unreleased]
+
+## [2.3.0] - 2022-02-21
+
+### Changed
+
+- Enabled the `$onRejected` callback of `HttpRejectedPromise` to return a promise for implementing a retry
+ mechanism [#168](https://github.com/php-http/httplug/pull/168)
+
+## [2.2.0] - 2020-07-13
+
+### Changed
+
+- Support PHP 7.1-8.0
+
+## [2.1.0] - 2019-12-27
+
+### Changed
+
+- `Http\Client\Exception\NetworkException` no longer extends `Http\Client\Exception\RequestException`,
+ in accordance with [PSR-18](https://www.php-fig.org/psr/psr-18/)
+
+## [2.0.0] - 2018-10-31
+
+This version is no BC break for consumers using HTTPlug. However, HTTP clients that
+implement HTTPlug need to adjust because we add return type declarations.
+
+### Added
+
+- Support for PSR-18 (HTTP client).
+
+### Changed
+
+- **BC Break:** `HttpClient::sendRequest(RequestInterface $request)` has a return type annotation. The new
+signature is `HttpClient::sendRequest(RequestInterface $request): ResponseInterface`.
+- **BC Break:** `RequestException::getRequest()` has a return type annotation. The new
+signature is `RequestException::getRequest(): RequestInterface`.
+
+### Removed
+
+- PHP 5 support
+
+
+## [1.1.0] - 2016-08-31
+
+### Added
+
+- HttpFulfilledPromise and HttpRejectedPromise which respect the HttpAsyncClient interface
+
+
+## [1.0.0] - 2016-01-26
+
+### Removed
+
+- Stability configuration from composer
+
+
+## [1.0.0-RC1] - 2016-01-12
+
+### Changed
+
+- Updated package files
+- Updated promise dependency to RC1
+
+
+## [1.0.0-beta] - 2015-12-17
+
+### Added
+
+- Puli configuration and binding types
+
+### Changed
+
+- Exception concept
+
+
+## [1.0.0-alpha3] - 2015-12-13
+
+### Changed
+
+- Async client does not throw exceptions
+
+### Removed
+
+- Promise interface moved to its own repository: [php-http/promise](https://github.com/php-http/promise)
+
+
+## [1.0.0-alpha2] - 2015-11-16
+
+### Added
+
+- Async client and Promise interface
+
+
+## [1.0.0-alpha] - 2015-10-26
+
+### Added
+
+- Better domain exceptions.
+
+### Changed
+
+- Purpose of the library: general HTTP CLient abstraction.
+
+### Removed
+
+- Request options: they should be configured at construction time.
+- Multiple request sending: should be done asynchronously using Async Client.
+- `getName` method
+
+
+## 0.1.0 - 2015-06-03
+
+### Added
+
+- Initial release
+
+
+[Unreleased]: https://github.com/php-http/httplug/compare/v2.0.0...HEAD
+[2.0.0]: https://github.com/php-http/httplug/compare/v1.1.0...HEAD
+[1.1.0]: https://github.com/php-http/httplug/compare/v1.0.0...v1.1.0
+[1.0.0]: https://github.com/php-http/httplug/compare/v1.0.0-RC1...v1.0.0
+[1.0.0-RC1]: https://github.com/php-http/httplug/compare/v1.0.0-beta...v1.0.0-RC1
+[1.0.0-beta]: https://github.com/php-http/httplug/compare/v1.0.0-alpha3...v1.0.0-beta
+[1.0.0-alpha3]: https://github.com/php-http/httplug/compare/v1.0.0-alpha2...v1.0.0-alpha3
+[1.0.0-alpha2]: https://github.com/php-http/httplug/compare/v1.0.0-alpha...v1.0.0-alpha2
+[1.0.0-alpha]: https://github.com/php-http/httplug/compare/v0.1.0...v1.0.0-alpha
diff --git a/vendor/php-http/httplug/LICENSE b/vendor/php-http/httplug/LICENSE
new file mode 100644
index 000000000..8cd264c6b
--- /dev/null
+++ b/vendor/php-http/httplug/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2014 Eric GELOEN
+Copyright (c) 2015 PHP HTTP Team
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/php-http/httplug/README.md b/vendor/php-http/httplug/README.md
new file mode 100644
index 000000000..ce60cfaa9
--- /dev/null
+++ b/vendor/php-http/httplug/README.md
@@ -0,0 +1,62 @@
+# HTTPlug
+
+[](https://github.com/php-http/httplug/releases)
+[](LICENSE)
+[](https://github.com/php-http/httplug/actions/workflows/ci.yml)
+[](https://scrutinizer-ci.com/g/php-http/httplug)
+[](https://scrutinizer-ci.com/g/php-http/httplug)
+[](https://packagist.org/packages/php-http/httplug)
+
+[](mailto:team@httplug.io)
+
+**HTTPlug, the HTTP client abstraction for PHP.**
+
+
+## Intro
+
+HTTP client standard built on [PSR-7](http://www.php-fig.org/psr/psr-7/) HTTP
+messages. The HTTPlug client interface is compatible with the official standard
+for the HTTP client interface, [PSR-18](http://www.php-fig.org/psr/psr-18/).
+HTTPlug adds an interface for asynchronous HTTP requests, which PSR-18 does not
+cover.
+
+Since HTTPlug has already been widely adopted and a whole ecosystem has been
+built around it, we will keep maintaining this package for the time being.
+HTTPlug 2.0 and newer extend the PSR-18 interface to allow for a convenient
+migration path.
+
+New client implementations and consumers should use the PSR-18 interfaces
+directly. In the long term, we expect PSR-18 to completely replace the need
+for HTTPlug.
+
+
+## History
+
+HTTPlug is the official successor of the [ivory http adapter](https://github.com/egeloen/ivory-http-adapter).
+HTTPlug is a predecessor of [PSR-18](http://www.php-fig.org/psr/psr-18/)
+
+
+## Install
+
+Via Composer
+
+``` bash
+$ composer require php-http/httplug
+```
+
+
+## Documentation
+
+Please see the [official documentation](http://docs.php-http.org).
+
+
+## Testing
+
+``` bash
+$ composer test
+```
+
+
+## License
+
+The MIT License (MIT). Please see [License File](LICENSE) for more information.
diff --git a/vendor/php-http/httplug/composer.json b/vendor/php-http/httplug/composer.json
new file mode 100644
index 000000000..268b27ec7
--- /dev/null
+++ b/vendor/php-http/httplug/composer.json
@@ -0,0 +1,45 @@
+{
+ "name": "php-http/httplug",
+ "description": "HTTPlug, the HTTP client abstraction for PHP",
+ "keywords": [
+ "http",
+ "client"
+ ],
+ "homepage": "http://httplug.io",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Eric GELOEN",
+ "email": "geloen.eric@gmail.com"
+ },
+ {
+ "name": "Márk Sági-Kazár",
+ "email": "mark.sagikazar@gmail.com",
+ "homepage": "https://sagikazarmark.hu"
+ }
+ ],
+ "require": {
+ "php": "^7.1 || ^8.0",
+ "php-http/promise": "^1.1",
+ "psr/http-client": "^1.0",
+ "psr/http-message": "^1.0"
+ },
+ "require-dev": {
+ "friends-of-phpspec/phpspec-code-coverage": "^4.1",
+ "phpspec/phpspec": "^5.1 || ^6.0"
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Http\\Client\\": "src/"
+ }
+ },
+ "scripts": {
+ "test": "vendor/bin/phpspec run",
+ "test-ci": "vendor/bin/phpspec run -c phpspec.ci.yml"
+ }
+}
diff --git a/vendor/php-http/httplug/puli.json b/vendor/php-http/httplug/puli.json
new file mode 100644
index 000000000..416833152
--- /dev/null
+++ b/vendor/php-http/httplug/puli.json
@@ -0,0 +1,12 @@
+{
+ "version": "1.0",
+ "name": "php-http/httplug",
+ "binding-types": {
+ "Http\\Client\\HttpAsyncClient": {
+ "description": "Async HTTP Client"
+ },
+ "Http\\Client\\HttpClient": {
+ "description": "HTTP Client"
+ }
+ }
+}
diff --git a/vendor/php-http/httplug/src/Exception.php b/vendor/php-http/httplug/src/Exception.php
new file mode 100644
index 000000000..4df164c9a
--- /dev/null
+++ b/vendor/php-http/httplug/src/Exception.php
@@ -0,0 +1,14 @@
+
+ */
+interface Exception extends PsrClientException
+{
+}
diff --git a/vendor/php-http/httplug/src/Exception/HttpException.php b/vendor/php-http/httplug/src/Exception/HttpException.php
new file mode 100644
index 000000000..6c2a007a0
--- /dev/null
+++ b/vendor/php-http/httplug/src/Exception/HttpException.php
@@ -0,0 +1,65 @@
+
+ */
+class HttpException extends RequestException
+{
+ /**
+ * @var ResponseInterface
+ */
+ protected $response;
+
+ /**
+ * @param string $message
+ */
+ public function __construct(
+ $message,
+ RequestInterface $request,
+ ResponseInterface $response,
+ \Exception $previous = null
+ ) {
+ parent::__construct($message, $request, $previous);
+
+ $this->response = $response;
+ $this->code = $response->getStatusCode();
+ }
+
+ /**
+ * Returns the response.
+ *
+ * @return ResponseInterface
+ */
+ public function getResponse()
+ {
+ return $this->response;
+ }
+
+ /**
+ * Factory method to create a new exception with a normalized error message.
+ */
+ public static function create(
+ RequestInterface $request,
+ ResponseInterface $response,
+ \Exception $previous = null
+ ) {
+ $message = sprintf(
+ '[url] %s [http method] %s [status code] %s [reason phrase] %s',
+ $request->getRequestTarget(),
+ $request->getMethod(),
+ $response->getStatusCode(),
+ $response->getReasonPhrase()
+ );
+
+ return new static($message, $request, $response, $previous);
+ }
+}
diff --git a/vendor/php-http/httplug/src/Exception/NetworkException.php b/vendor/php-http/httplug/src/Exception/NetworkException.php
new file mode 100644
index 000000000..9b4f1e8fd
--- /dev/null
+++ b/vendor/php-http/httplug/src/Exception/NetworkException.php
@@ -0,0 +1,28 @@
+
+ */
+class NetworkException extends TransferException implements PsrNetworkException
+{
+ use RequestAwareTrait;
+
+ /**
+ * @param string $message
+ */
+ public function __construct($message, RequestInterface $request, \Exception $previous = null)
+ {
+ $this->setRequest($request);
+
+ parent::__construct($message, 0, $previous);
+ }
+}
diff --git a/vendor/php-http/httplug/src/Exception/RequestAwareTrait.php b/vendor/php-http/httplug/src/Exception/RequestAwareTrait.php
new file mode 100644
index 000000000..71b4bb8c9
--- /dev/null
+++ b/vendor/php-http/httplug/src/Exception/RequestAwareTrait.php
@@ -0,0 +1,26 @@
+request = $request;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getRequest(): RequestInterface
+ {
+ return $this->request;
+ }
+}
diff --git a/vendor/php-http/httplug/src/Exception/RequestException.php b/vendor/php-http/httplug/src/Exception/RequestException.php
new file mode 100644
index 000000000..f6c60ce56
--- /dev/null
+++ b/vendor/php-http/httplug/src/Exception/RequestException.php
@@ -0,0 +1,29 @@
+
+ */
+class RequestException extends TransferException implements PsrRequestException
+{
+ use RequestAwareTrait;
+
+ /**
+ * @param string $message
+ */
+ public function __construct($message, RequestInterface $request, \Exception $previous = null)
+ {
+ $this->setRequest($request);
+
+ parent::__construct($message, 0, $previous);
+ }
+}
diff --git a/vendor/php-http/httplug/src/Exception/TransferException.php b/vendor/php-http/httplug/src/Exception/TransferException.php
new file mode 100644
index 000000000..a858cf5ec
--- /dev/null
+++ b/vendor/php-http/httplug/src/Exception/TransferException.php
@@ -0,0 +1,14 @@
+
+ */
+class TransferException extends \RuntimeException implements Exception
+{
+}
diff --git a/vendor/php-http/httplug/src/HttpAsyncClient.php b/vendor/php-http/httplug/src/HttpAsyncClient.php
new file mode 100644
index 000000000..c3b9d61aa
--- /dev/null
+++ b/vendor/php-http/httplug/src/HttpAsyncClient.php
@@ -0,0 +1,25 @@
+
+ */
+interface HttpAsyncClient
+{
+ /**
+ * Sends a PSR-7 request in an asynchronous way.
+ *
+ * Exceptions related to processing the request are available from the returned Promise.
+ *
+ * @return Promise resolves a PSR-7 Response or fails with an Http\Client\Exception
+ *
+ * @throws \Exception If processing the request is impossible (eg. bad configuration).
+ */
+ public function sendAsyncRequest(RequestInterface $request);
+}
diff --git a/vendor/php-http/httplug/src/HttpClient.php b/vendor/php-http/httplug/src/HttpClient.php
new file mode 100644
index 000000000..4442bd013
--- /dev/null
+++ b/vendor/php-http/httplug/src/HttpClient.php
@@ -0,0 +1,15 @@
+response = $response;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function then(callable $onFulfilled = null, callable $onRejected = null)
+ {
+ if (null === $onFulfilled) {
+ return $this;
+ }
+
+ try {
+ return new self($onFulfilled($this->response));
+ } catch (Exception $e) {
+ return new HttpRejectedPromise($e);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getState()
+ {
+ return Promise::FULFILLED;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function wait($unwrap = true)
+ {
+ if ($unwrap) {
+ return $this->response;
+ }
+ }
+}
diff --git a/vendor/php-http/httplug/src/Promise/HttpRejectedPromise.php b/vendor/php-http/httplug/src/Promise/HttpRejectedPromise.php
new file mode 100644
index 000000000..624cc8a94
--- /dev/null
+++ b/vendor/php-http/httplug/src/Promise/HttpRejectedPromise.php
@@ -0,0 +1,58 @@
+exception = $exception;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function then(callable $onFulfilled = null, callable $onRejected = null)
+ {
+ if (null === $onRejected) {
+ return $this;
+ }
+
+ try {
+ $result = $onRejected($this->exception);
+ if ($result instanceof Promise) {
+ return $result;
+ }
+
+ return new HttpFulfilledPromise($result);
+ } catch (Exception $e) {
+ return new self($e);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getState()
+ {
+ return Promise::REJECTED;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function wait($unwrap = true)
+ {
+ if ($unwrap) {
+ throw $this->exception;
+ }
+ }
+}
diff --git a/vendor/php-http/message-factory/CHANGELOG.md b/vendor/php-http/message-factory/CHANGELOG.md
new file mode 100644
index 000000000..4711924c6
--- /dev/null
+++ b/vendor/php-http/message-factory/CHANGELOG.md
@@ -0,0 +1,65 @@
+# Change Log
+
+
+## 1.0.2 - 2015-12-19
+
+### Added
+
+- Request and Response factory binding types to Puli
+
+
+## 1.0.1 - 2015-12-17
+
+### Added
+
+- Puli configuration and binding types
+
+
+## 1.0.0 - 2015-12-15
+
+### Added
+
+- Response Factory in order to be reused in Message and Server Message factories
+- Request Factory
+
+### Changed
+
+- Message Factory extends Request and Response factories
+
+
+## 1.0.0-RC1 - 2015-12-14
+
+### Added
+
+- CS check
+
+### Changed
+
+- RuntimeException is thrown when the StreamFactory cannot write to the underlying stream
+
+
+## 0.3.0 - 2015-11-16
+
+### Removed
+
+- Client Context Factory
+- Factory Awares and Templates
+
+
+## 0.2.0 - 2015-11-16
+
+### Changed
+
+- Reordered the parameters when creating a message to have the protocol last,
+as its the least likely to need to be changed.
+
+
+## 0.1.0 - 2015-06-01
+
+### Added
+
+- Initial release
+
+### Changed
+
+- Helpers are renamed to templates
diff --git a/vendor/php-http/message-factory/LICENSE b/vendor/php-http/message-factory/LICENSE
new file mode 100644
index 000000000..8e2c4a0b8
--- /dev/null
+++ b/vendor/php-http/message-factory/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2015 PHP HTTP Team
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/php-http/message-factory/README.md b/vendor/php-http/message-factory/README.md
new file mode 100644
index 000000000..4654495a7
--- /dev/null
+++ b/vendor/php-http/message-factory/README.md
@@ -0,0 +1,36 @@
+# PSR-7 Message Factory
+
+[](https://github.com/php-http/message-factory/releases)
+[](LICENSE)
+[](https://packagist.org/packages/php-http/message-factory)
+
+**Factory interfaces for PSR-7 HTTP Message.**
+
+
+## Install
+
+Via Composer
+
+``` bash
+$ composer require php-http/message-factory
+```
+
+
+## Documentation
+
+Please see the [official documentation](http://php-http.readthedocs.org/en/latest/message-factory/).
+
+
+## Contributing
+
+Please see [CONTRIBUTING](CONTRIBUTING.md) and [CONDUCT](CONDUCT.md) for details.
+
+
+## Security
+
+If you discover any security related issues, please contact us at [security@php-http.org](mailto:security@php-http.org).
+
+
+## License
+
+The MIT License (MIT). Please see [License File](LICENSE) for more information.
diff --git a/vendor/php-http/message-factory/composer.json b/vendor/php-http/message-factory/composer.json
new file mode 100644
index 000000000..7c72febe5
--- /dev/null
+++ b/vendor/php-http/message-factory/composer.json
@@ -0,0 +1,27 @@
+{
+ "name": "php-http/message-factory",
+ "description": "Factory interfaces for PSR-7 HTTP Message",
+ "license": "MIT",
+ "keywords": ["http", "factory", "message", "stream", "uri"],
+ "homepage": "http://php-http.org",
+ "authors": [
+ {
+ "name": "Márk Sági-Kazár",
+ "email": "mark.sagikazar@gmail.com"
+ }
+ ],
+ "require": {
+ "php": ">=5.4",
+ "psr/http-message": "^1.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "Http\\Message\\": "src/"
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ }
+}
diff --git a/vendor/php-http/message-factory/puli.json b/vendor/php-http/message-factory/puli.json
new file mode 100644
index 000000000..08d37627d
--- /dev/null
+++ b/vendor/php-http/message-factory/puli.json
@@ -0,0 +1,43 @@
+{
+ "version": "1.0",
+ "binding-types": {
+ "Http\\Message\\MessageFactory": {
+ "description": "PSR-7 Message Factory",
+ "parameters": {
+ "depends": {
+ "description": "Optional class dependency which can be checked by consumers"
+ }
+ }
+ },
+ "Http\\Message\\RequestFactory": {
+ "parameters": {
+ "depends": {
+ "description": "Optional class dependency which can be checked by consumers"
+ }
+ }
+ },
+ "Http\\Message\\ResponseFactory": {
+ "parameters": {
+ "depends": {
+ "description": "Optional class dependency which can be checked by consumers"
+ }
+ }
+ },
+ "Http\\Message\\StreamFactory": {
+ "description": "PSR-7 Stream Factory",
+ "parameters": {
+ "depends": {
+ "description": "Optional class dependency which can be checked by consumers"
+ }
+ }
+ },
+ "Http\\Message\\UriFactory": {
+ "description": "PSR-7 URI Factory",
+ "parameters": {
+ "depends": {
+ "description": "Optional class dependency which can be checked by consumers"
+ }
+ }
+ }
+ }
+}
diff --git a/vendor/php-http/message-factory/src/MessageFactory.php b/vendor/php-http/message-factory/src/MessageFactory.php
new file mode 100644
index 000000000..965aaa804
--- /dev/null
+++ b/vendor/php-http/message-factory/src/MessageFactory.php
@@ -0,0 +1,12 @@
+
+ */
+interface MessageFactory extends RequestFactory, ResponseFactory
+{
+}
diff --git a/vendor/php-http/message-factory/src/RequestFactory.php b/vendor/php-http/message-factory/src/RequestFactory.php
new file mode 100644
index 000000000..624e82f36
--- /dev/null
+++ b/vendor/php-http/message-factory/src/RequestFactory.php
@@ -0,0 +1,34 @@
+
+ */
+interface RequestFactory
+{
+ /**
+ * Creates a new PSR-7 request.
+ *
+ * @param string $method
+ * @param string|UriInterface $uri
+ * @param array $headers
+ * @param resource|string|StreamInterface|null $body
+ * @param string $protocolVersion
+ *
+ * @return RequestInterface
+ */
+ public function createRequest(
+ $method,
+ $uri,
+ array $headers = [],
+ $body = null,
+ $protocolVersion = '1.1'
+ );
+}
diff --git a/vendor/php-http/message-factory/src/ResponseFactory.php b/vendor/php-http/message-factory/src/ResponseFactory.php
new file mode 100644
index 000000000..2411ed3a1
--- /dev/null
+++ b/vendor/php-http/message-factory/src/ResponseFactory.php
@@ -0,0 +1,35 @@
+
+ */
+interface ResponseFactory
+{
+ /**
+ * Creates a new PSR-7 response.
+ *
+ * @param int $statusCode
+ * @param string|null $reasonPhrase
+ * @param array $headers
+ * @param resource|string|StreamInterface|null $body
+ * @param string $protocolVersion
+ *
+ * @return ResponseInterface
+ */
+ public function createResponse(
+ $statusCode = 200,
+ $reasonPhrase = null,
+ array $headers = [],
+ $body = null,
+ $protocolVersion = '1.1'
+ );
+}
diff --git a/vendor/php-http/message-factory/src/StreamFactory.php b/vendor/php-http/message-factory/src/StreamFactory.php
new file mode 100644
index 000000000..327a902f9
--- /dev/null
+++ b/vendor/php-http/message-factory/src/StreamFactory.php
@@ -0,0 +1,25 @@
+
+ */
+interface StreamFactory
+{
+ /**
+ * Creates a new PSR-7 stream.
+ *
+ * @param string|resource|StreamInterface|null $body
+ *
+ * @return StreamInterface
+ *
+ * @throws \InvalidArgumentException If the stream body is invalid.
+ * @throws \RuntimeException If creating the stream from $body fails.
+ */
+ public function createStream($body = null);
+}
diff --git a/vendor/php-http/message-factory/src/UriFactory.php b/vendor/php-http/message-factory/src/UriFactory.php
new file mode 100644
index 000000000..f05e62521
--- /dev/null
+++ b/vendor/php-http/message-factory/src/UriFactory.php
@@ -0,0 +1,24 @@
+
+ */
+interface UriFactory
+{
+ /**
+ * Creates an PSR-7 URI.
+ *
+ * @param string|UriInterface $uri
+ *
+ * @return UriInterface
+ *
+ * @throws \InvalidArgumentException If the $uri argument can not be converted into a valid URI.
+ */
+ public function createUri($uri);
+}
diff --git a/vendor/php-http/message/CHANGELOG.md b/vendor/php-http/message/CHANGELOG.md
new file mode 100644
index 000000000..a185f4612
--- /dev/null
+++ b/vendor/php-http/message/CHANGELOG.md
@@ -0,0 +1,254 @@
+# Change Log
+
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
+and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
+
+## [1.13.0] - 2022-02-11
+
+- Added `Formatter::formatResponseForRequest()` to allow the formatter to get context from the request to decide what of the response to output.
+- Deprecated `Formatter::formatResponse()` in favor of the new `formatResponseForRequest` method.
+
+## [1.12.0] - 2021-08-29
+
+- Added support for adjusting binary detection regex in FullHttpMessageFormatter.
+
+## [1.11.2] - 2021-08-03
+
+- Support GuzzleHttp/Psr7 version 2.0 in the (deprecated) GuzzleStreamFactory.
+
+## [1.11.1] - 2021-05-24
+
+- Support GuzzleHttp/Psr7 version 2.0 in the (deprecated) GuzzleUriFactory.
+
+## [1.11.0] - 2020-02-01
+
+- Migrated from `zendframework/zend-diactoros` to `laminas/laminas-diactoros`.
+ Users are encouraged to update their dependencies by simply replacing the Zend package with the Laminas package.
+ Due to the [laminas-zendframework-brige](https://github.com/laminas/laminas-zendframework-bridge), BC changes
+ are not expected and legacy code does not need to be refactored (though it is
+ [recommended and simple](https://docs.laminas.dev/migration/)).
+- The diactoros factories of `php-http/message` will return objects from the `Laminas\Diactoros\` namespace, if
+ the respective classes are available via autoloading, but continue to return objects from `Zend\Diactoros\`
+ namespace otherwise.
+
+- Allow to specify the hashing algorithm for WSSE authentication.
+
+## [1.10.0] - 2020-11-11
+
+- Added support for PHP 8.0.
+
+## [1.9.1] - 2020-10-13
+
+- Improved detection of binary stream to not consider newlines, carriage return or tabs as binary.
+
+## [1.9.0] - 2020-08-17
+
+- Omitted binary body in FullHttpMessageFormatter and CurlCommandFormatter.
+ `[binary stream omitted]` will be shown instead.
+
+### Added
+
+- New Header authentication method for arbitrary header authentication.
+
+## [1.8.0] - 2019-08-05
+
+### Changed
+
+- Raised minimum PHP version to 7.1
+
+### Fixed
+
+- Fatal error on `CurlCommandFormatter` when body is larger than `escapeshellarg` allowed length.
+- Do not read stream in message formatter if stream is not seekable.
+
+## [1.7.2] - 2018-10-30
+
+### Fixed
+
+- FilteredStream uses `@trigger_error` instead of throwing exceptions to not
+ break careless users. You still need to fix your stream code to respect
+ `isSeekable`. Seeking does not work as expected, and we will add exceptions
+ in version 2.
+
+## [1.7.1] - 2018-10-29
+
+### Fixed
+
+- FilteredStream is not actually seekable
+
+
+## [1.7.0] - 2018-08-15
+
+### Fixed
+
+- Fix CurlCommandFormatter for binary request payloads
+- Fix QueryParam authentication to assemble proper URL regardless of PHP `arg_separator.output` directive
+- Do not pass `null` parameters to `Clue\StreamFilter\fun`
+
+### Changed
+
+- Dropped tests on HHVM
+
+
+## [1.6.0] - 2017-07-05
+
+### Added
+
+- CookieUtil::parseDate to create a date from cookie date string
+
+### Fixed
+
+- Fix curl command of CurlFormatter when there is an user-agent header
+
+
+## [1.5.0] - 2017-02-14
+
+### Added
+
+- Check for empty string in Stream factories
+- Cookie::createWithoutValidation Static constructor to create a cookie. Will not perform any attribute validation during instantiation.
+- Cookie::isValid Method to check if cookie attributes are valid.
+
+### Fixed
+
+- FilteredStream::getSize returns null because the contents size is unknown.
+- Stream factories does not rewinds streams. The previous behavior was not coherent between factories and inputs.
+
+### Deprecated
+
+- FilteredStream::getReadFilter The read filter is internal and should never be used by consuming code.
+- FilteredStream::getWriteFilter We did not implement writing to the streams at all. And if we do, the filter is an internal information and should not be used by consuming code.
+
+
+## [1.4.1] - 2016-12-16
+
+### Fixed
+
+- Cookie::matchPath Cookie with root path (`/`) will not match sub path (e.g. `/cookie`).
+
+
+## [1.4.0] - 2016-10-20
+
+### Added
+
+- Message, stream and URI factories for [Slim Framework](https://github.com/slimphp/Slim)
+- BufferedStream that allow you to decorate a non-seekable stream with a seekable one.
+- cUrlFormatter to be able to redo the request with a cURL command
+
+
+## [1.3.1] - 2016-07-15
+
+### Fixed
+
+- FullHttpMessageFormatter will not read from streams that you cannot rewind (non-seekable)
+- FullHttpMessageFormatter will not read from the stream if $maxBodyLength is zero
+- FullHttpMessageFormatter rewinds streams after they are read
+
+
+## [1.3.0] - 2016-07-14
+
+### Added
+
+- FullHttpMessageFormatter to include headers and body in the formatted message
+
+### Fixed
+
+- #41: Response builder broke header value
+
+
+## [1.2.0] - 2016-03-29
+
+### Added
+
+- The RequestMatcher is built after the Symfony RequestMatcher and separates
+ scheme, host and path expressions and provides an option to filter on the
+ method
+- New RequestConditional authentication method using request matchers
+- Add automatic basic auth info detection based on the URL
+
+### Changed
+
+- Improved ResponseBuilder
+
+### Deprecated
+
+- RegexRequestMatcher, use RequestMatcher instead
+- Matching authenitcation method, use RequestConditional instead
+
+
+## [1.1.0] - 2016-02-25
+
+### Added
+
+ - Add a request matcher interface and regex implementation
+ - Add a callback request matcher implementation
+ - Add a ResponseBuilder, to create PSR7 Response from a string
+
+### Fixed
+
+ - Fix casting string on a FilteredStream not filtering the output
+
+
+## [1.0.0] - 2016-01-27
+
+
+## [0.2.0] - 2015-12-29
+
+### Added
+
+- Autoregistration of stream filters using Composer autoload
+- Cookie
+- [Apigen](http://www.apigen.org/) configuration
+
+
+## [0.1.2] - 2015-12-26
+
+### Added
+
+- Request and response factory bindings
+
+### Fixed
+
+- Chunk filter namespace in Dechunk stream
+
+
+## [0.1.1] - 2015-12-25
+
+### Added
+
+- Formatter
+
+
+## 0.1.0 - 2015-12-24
+
+### Added
+
+- Authentication
+- Encoding
+- Message decorator
+- Message factory (Guzzle, Diactoros)
+
+
+[Unreleased]: https://github.com/php-http/message/compare/1.10.0...HEAD
+[1.10.0]: https://github.com/php-http/message/compare/1.9.1...1.10.0
+[1.9.1]: https://github.com/php-http/message/compare/1.9.0...1.9.1
+[1.9.0]: https://github.com/php-http/message/compare/1.8.0...1.9.0
+[1.8.0]: https://github.com/php-http/message/compare/1.7.2...1.8.0
+[1.7.2]: https://github.com/php-http/message/compare/v1.7.1...1.7.2
+[1.7.1]: https://github.com/php-http/message/compare/1.7.0...v1.7.1
+[1.7.0]: https://github.com/php-http/message/compare/1.6.0...1.7.0
+[1.6.0]: https://github.com/php-http/message/compare/1.5.0...1.6.0
+[1.5.0]: https://github.com/php-http/message/compare/v1.4.1...1.5.0
+[1.4.1]: https://github.com/php-http/message/compare/v1.4.0...v1.4.1
+[1.4.0]: https://github.com/php-http/message/compare/v1.3.1...v1.4.0
+[1.3.1]: https://github.com/php-http/message/compare/v1.3.0...v1.3.1
+[1.3.0]: https://github.com/php-http/message/compare/v1.2.0...v1.3.0
+[1.2.0]: https://github.com/php-http/message/compare/v1.1.0...v1.2.0
+[1.1.0]: https://github.com/php-http/message/compare/v1.0.0...v1.1.0
+[1.0.0]: https://github.com/php-http/message/compare/0.2.0...v1.0.0
+[0.2.0]: https://github.com/php-http/message/compare/v0.1.2...0.2.0
+[0.1.2]: https://github.com/php-http/message/compare/v0.1.1...v0.1.2
+[0.1.1]: https://github.com/php-http/message/compare/v0.1.0...v0.1.1
diff --git a/vendor/php-http/message/LICENSE b/vendor/php-http/message/LICENSE
new file mode 100644
index 000000000..4558d6f06
--- /dev/null
+++ b/vendor/php-http/message/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2015-2016 PHP HTTP Team
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/php-http/message/README.md b/vendor/php-http/message/README.md
new file mode 100644
index 000000000..df1a7d552
--- /dev/null
+++ b/vendor/php-http/message/README.md
@@ -0,0 +1,51 @@
+# HTTP Message
+
+[](https://github.com/php-http/message/releases)
+[](LICENSE)
+[](https://github.com/php-http/message/actions?query=workflow%3ACI+branch%3Amaster)
+[](https://packagist.org/packages/php-http/message)
+
+**HTTP Message related tools.**
+
+
+## Install
+
+Via Composer
+
+``` bash
+$ composer require php-http/message
+```
+
+
+## Intro
+
+This package contains various PSR-7 tools which might be useful in an HTTP workflow:
+
+- Authentication method implementations
+- Various Stream encoding tools
+- Message decorators
+- Message factory implementations for Guzzle PSR-7 and Diactoros
+- Cookie implementation
+- Request matchers
+
+
+## Documentation
+
+Please see the [official documentation](http://docs.php-http.org/en/latest/message.html).
+
+
+## Testing
+
+``` bash
+$ composer test
+```
+
+
+## Credits
+
+Thanks to [Cuzzle](https://github.com/namshi/cuzzle) for inpiration for the `CurlCommandFormatter`.
+
+
+## License
+
+The MIT License (MIT). Please see [License File](LICENSE) for more information.
diff --git a/vendor/php-http/message/apigen.neon b/vendor/php-http/message/apigen.neon
new file mode 100644
index 000000000..0ba1a1850
--- /dev/null
+++ b/vendor/php-http/message/apigen.neon
@@ -0,0 +1,6 @@
+source:
+ - src/
+
+destination: build/api/
+
+templateTheme: bootstrap
diff --git a/vendor/php-http/message/composer.json b/vendor/php-http/message/composer.json
new file mode 100644
index 000000000..1a614df8d
--- /dev/null
+++ b/vendor/php-http/message/composer.json
@@ -0,0 +1,68 @@
+{
+ "name": "php-http/message",
+ "description": "HTTP Message related tools",
+ "keywords": [
+ "message",
+ "http",
+ "psr-7"
+ ],
+ "homepage": "http://php-http.org",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Márk Sági-Kazár",
+ "email": "mark.sagikazar@gmail.com"
+ }
+ ],
+ "require": {
+ "php": "^7.1 || ^8.0",
+ "clue/stream-filter": "^1.5",
+ "php-http/message-factory": "^1.0.2",
+ "psr/http-message": "^1.0"
+ },
+ "provide": {
+ "php-http/message-factory-implementation": "1.0"
+ },
+ "require-dev": {
+ "ext-zlib": "*",
+ "ergebnis/composer-normalize": "^2.6",
+ "guzzlehttp/psr7": "^1.0",
+ "phpspec/phpspec": "^5.1 || ^6.3 || ^7.1",
+ "slim/slim": "^3.0",
+ "laminas/laminas-diactoros": "^2.0"
+ },
+ "suggest": {
+ "ext-zlib": "Used with compressor/decompressor streams",
+ "guzzlehttp/psr7": "Used with Guzzle PSR-7 Factories",
+ "laminas/laminas-diactoros": "Used with Diactoros Factories",
+ "slim/slim": "Used with Slim Framework PSR-7 implementation"
+ },
+ "config": {
+ "sort-packages": true,
+ "allow-plugins": {
+ "ergebnis/composer-normalize": true
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.10-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Http\\Message\\": "src/"
+ },
+ "files": [
+ "src/filters.php"
+ ]
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "spec\\Http\\Message\\": "spec/"
+ }
+ },
+ "scripts": {
+ "test": "vendor/bin/phpspec run",
+ "test-ci": "vendor/bin/phpspec run -c phpspec.ci.yml"
+ }
+}
diff --git a/vendor/php-http/message/puli.json b/vendor/php-http/message/puli.json
new file mode 100644
index 000000000..024a85d9e
--- /dev/null
+++ b/vendor/php-http/message/puli.json
@@ -0,0 +1,111 @@
+{
+ "version": "1.0",
+ "name": "php-http/message",
+ "bindings": {
+ "064d003d-78a1-48c4-8f3b-1f92ff25da69": {
+ "_class": "Puli\\Discovery\\Binding\\ClassBinding",
+ "class": "Http\\Message\\MessageFactory\\DiactorosMessageFactory",
+ "type": "Http\\Message\\MessageFactory",
+ "parameters": {
+ "depends": "Zend\\Diactoros\\Request"
+ }
+ },
+ "0836751e-6558-4d1b-8993-4a52012947c3": {
+ "_class": "Puli\\Discovery\\Binding\\ClassBinding",
+ "class": "Http\\Message\\MessageFactory\\SlimMessageFactory",
+ "type": "Http\\Message\\ResponseFactory"
+ },
+ "1d127622-dc61-4bfa-b9da-d221548d72c3": {
+ "_class": "Puli\\Discovery\\Binding\\ClassBinding",
+ "class": "Http\\Message\\MessageFactory\\SlimMessageFactory",
+ "type": "Http\\Message\\RequestFactory"
+ },
+ "2438c2d0-0658-441f-8855-ddaf0f87d54d": {
+ "_class": "Puli\\Discovery\\Binding\\ClassBinding",
+ "class": "Http\\Message\\MessageFactory\\GuzzleMessageFactory",
+ "type": "Http\\Message\\MessageFactory",
+ "parameters": {
+ "depends": "GuzzleHttp\\Psr7\\Request"
+ }
+ },
+ "253aa08c-d705-46e7-b1d2-e28c97eef792": {
+ "_class": "Puli\\Discovery\\Binding\\ClassBinding",
+ "class": "Http\\Message\\MessageFactory\\GuzzleMessageFactory",
+ "type": "Http\\Message\\RequestFactory",
+ "parameters": {
+ "depends": "GuzzleHttp\\Psr7\\Request"
+ }
+ },
+ "273a34f9-62f4-4ba1-9801-b1284d49ff89": {
+ "_class": "Puli\\Discovery\\Binding\\ClassBinding",
+ "class": "Http\\Message\\StreamFactory\\GuzzleStreamFactory",
+ "type": "Http\\Message\\StreamFactory",
+ "parameters": {
+ "depends": "GuzzleHttp\\Psr7\\Stream"
+ }
+ },
+ "304b83db-b594-4d83-ae75-1f633adf92f7": {
+ "_class": "Puli\\Discovery\\Binding\\ClassBinding",
+ "class": "Http\\Message\\UriFactory\\GuzzleUriFactory",
+ "type": "Http\\Message\\UriFactory",
+ "parameters": {
+ "depends": "GuzzleHttp\\Psr7\\Uri"
+ }
+ },
+ "3f4bc1cd-aa95-4702-9fa7-65408e471691": {
+ "_class": "Puli\\Discovery\\Binding\\ClassBinding",
+ "class": "Http\\Message\\UriFactory\\DiactorosUriFactory",
+ "type": "Http\\Message\\UriFactory",
+ "parameters": {
+ "depends": "Zend\\Diactoros\\Uri"
+ }
+ },
+ "4672a6ee-ad9e-4109-a5d1-b7d46f26c7a1": {
+ "_class": "Puli\\Discovery\\Binding\\ClassBinding",
+ "class": "Http\\Message\\MessageFactory\\SlimMessageFactory",
+ "type": "Http\\Message\\MessageFactory"
+ },
+ "6234e947-d3bd-43eb-97d5-7f9e22e6bb1b": {
+ "_class": "Puli\\Discovery\\Binding\\ClassBinding",
+ "class": "Http\\Message\\MessageFactory\\DiactorosMessageFactory",
+ "type": "Http\\Message\\ResponseFactory",
+ "parameters": {
+ "depends": "Zend\\Diactoros\\Response"
+ }
+ },
+ "6a9ad6ce-d82c-470f-8e30-60f21d9d95bf": {
+ "_class": "Puli\\Discovery\\Binding\\ClassBinding",
+ "class": "Http\\Message\\UriFactory\\SlimUriFactory",
+ "type": "Http\\Message\\UriFactory"
+ },
+ "72c2afa0-ea56-4d03-adb6-a9f241a8a734": {
+ "_class": "Puli\\Discovery\\Binding\\ClassBinding",
+ "class": "Http\\Message\\StreamFactory\\SlimStreamFactory",
+ "type": "Http\\Message\\StreamFactory"
+ },
+ "95c1be8f-39fe-4abd-8351-92cb14379a75": {
+ "_class": "Puli\\Discovery\\Binding\\ClassBinding",
+ "class": "Http\\Message\\StreamFactory\\DiactorosStreamFactory",
+ "type": "Http\\Message\\StreamFactory",
+ "parameters": {
+ "depends": "Zend\\Diactoros\\Stream"
+ }
+ },
+ "a018af27-7590-4dcf-83a1-497f95604cd6": {
+ "_class": "Puli\\Discovery\\Binding\\ClassBinding",
+ "class": "Http\\Message\\MessageFactory\\GuzzleMessageFactory",
+ "type": "Http\\Message\\ResponseFactory",
+ "parameters": {
+ "depends": "GuzzleHttp\\Psr7\\Response"
+ }
+ },
+ "c07955b1-de46-43db-923b-d07fae9382cb": {
+ "_class": "Puli\\Discovery\\Binding\\ClassBinding",
+ "class": "Http\\Message\\MessageFactory\\DiactorosMessageFactory",
+ "type": "Http\\Message\\RequestFactory",
+ "parameters": {
+ "depends": "Zend\\Diactoros\\Request"
+ }
+ }
+ }
+}
diff --git a/vendor/php-http/message/src/Authentication.php b/vendor/php-http/message/src/Authentication.php
new file mode 100644
index 000000000..0fe0cb3ab
--- /dev/null
+++ b/vendor/php-http/message/src/Authentication.php
@@ -0,0 +1,25 @@
+
+ */
+interface Authentication
+{
+ /**
+ * Alter the request to add the authentication credentials.
+ *
+ * To do that, the implementation might use pre-stored credentials or do
+ * separate HTTP requests to obtain a valid token.
+ *
+ * @param RequestInterface $request The request without authentication information
+ *
+ * @return RequestInterface The request with added authentication information
+ */
+ public function authenticate(RequestInterface $request);
+}
diff --git a/vendor/php-http/message/src/Authentication/AutoBasicAuth.php b/vendor/php-http/message/src/Authentication/AutoBasicAuth.php
new file mode 100644
index 000000000..7b6a42948
--- /dev/null
+++ b/vendor/php-http/message/src/Authentication/AutoBasicAuth.php
@@ -0,0 +1,48 @@
+
+ */
+final class AutoBasicAuth implements Authentication
+{
+ /**
+ * Whether user info should be removed from the URI.
+ *
+ * @var bool
+ */
+ private $shouldRemoveUserInfo;
+
+ /**
+ * @param bool|true $shouldRremoveUserInfo
+ */
+ public function __construct($shouldRremoveUserInfo = true)
+ {
+ $this->shouldRemoveUserInfo = (bool) $shouldRremoveUserInfo;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function authenticate(RequestInterface $request)
+ {
+ $uri = $request->getUri();
+ $userInfo = $uri->getUserInfo();
+
+ if (!empty($userInfo)) {
+ if ($this->shouldRemoveUserInfo) {
+ $request = $request->withUri($uri->withUserInfo(''));
+ }
+
+ $request = $request->withHeader('Authorization', sprintf('Basic %s', base64_encode($userInfo)));
+ }
+
+ return $request;
+ }
+}
diff --git a/vendor/php-http/message/src/Authentication/BasicAuth.php b/vendor/php-http/message/src/Authentication/BasicAuth.php
new file mode 100644
index 000000000..23618a53c
--- /dev/null
+++ b/vendor/php-http/message/src/Authentication/BasicAuth.php
@@ -0,0 +1,44 @@
+
+ */
+final class BasicAuth implements Authentication
+{
+ /**
+ * @var string
+ */
+ private $username;
+
+ /**
+ * @var string
+ */
+ private $password;
+
+ /**
+ * @param string $username
+ * @param string $password
+ */
+ public function __construct($username, $password)
+ {
+ $this->username = $username;
+ $this->password = $password;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function authenticate(RequestInterface $request)
+ {
+ $header = sprintf('Basic %s', base64_encode(sprintf('%s:%s', $this->username, $this->password)));
+
+ return $request->withHeader('Authorization', $header);
+ }
+}
diff --git a/vendor/php-http/message/src/Authentication/Bearer.php b/vendor/php-http/message/src/Authentication/Bearer.php
new file mode 100644
index 000000000..a8fb21a14
--- /dev/null
+++ b/vendor/php-http/message/src/Authentication/Bearer.php
@@ -0,0 +1,37 @@
+
+ */
+final class Bearer implements Authentication
+{
+ /**
+ * @var string
+ */
+ private $token;
+
+ /**
+ * @param string $token
+ */
+ public function __construct($token)
+ {
+ $this->token = $token;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function authenticate(RequestInterface $request)
+ {
+ $header = sprintf('Bearer %s', $this->token);
+
+ return $request->withHeader('Authorization', $header);
+ }
+}
diff --git a/vendor/php-http/message/src/Authentication/Chain.php b/vendor/php-http/message/src/Authentication/Chain.php
new file mode 100644
index 000000000..71002bb17
--- /dev/null
+++ b/vendor/php-http/message/src/Authentication/Chain.php
@@ -0,0 +1,47 @@
+
+ */
+final class Chain implements Authentication
+{
+ /**
+ * @var Authentication[]
+ */
+ private $authenticationChain = [];
+
+ /**
+ * @param Authentication[] $authenticationChain
+ */
+ public function __construct(array $authenticationChain = [])
+ {
+ foreach ($authenticationChain as $authentication) {
+ if (!$authentication instanceof Authentication) {
+ throw new \InvalidArgumentException(
+ 'Members of the authentication chain must be of type Http\Message\Authentication'
+ );
+ }
+ }
+
+ $this->authenticationChain = $authenticationChain;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function authenticate(RequestInterface $request)
+ {
+ foreach ($this->authenticationChain as $authentication) {
+ $request = $authentication->authenticate($request);
+ }
+
+ return $request;
+ }
+}
diff --git a/vendor/php-http/message/src/Authentication/Header.php b/vendor/php-http/message/src/Authentication/Header.php
new file mode 100644
index 000000000..77f638275
--- /dev/null
+++ b/vendor/php-http/message/src/Authentication/Header.php
@@ -0,0 +1,36 @@
+name = $name;
+ $this->value = $value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function authenticate(RequestInterface $request)
+ {
+ return $request->withHeader($this->name, $this->value);
+ }
+}
diff --git a/vendor/php-http/message/src/Authentication/Matching.php b/vendor/php-http/message/src/Authentication/Matching.php
new file mode 100644
index 000000000..7a5c247be
--- /dev/null
+++ b/vendor/php-http/message/src/Authentication/Matching.php
@@ -0,0 +1,69 @@
+
+ *
+ * @deprecated since since version 1.2, and will be removed in 2.0. Use {@link RequestConditional} instead.
+ */
+final class Matching implements Authentication
+{
+ /**
+ * @var Authentication
+ */
+ private $authentication;
+
+ /**
+ * @var CallbackRequestMatcher
+ */
+ private $matcher;
+
+ public function __construct(Authentication $authentication, callable $matcher = null)
+ {
+ if (is_null($matcher)) {
+ $matcher = function () {
+ return true;
+ };
+ }
+
+ $this->authentication = $authentication;
+ $this->matcher = new CallbackRequestMatcher($matcher);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function authenticate(RequestInterface $request)
+ {
+ if ($this->matcher->matches($request)) {
+ return $this->authentication->authenticate($request);
+ }
+
+ return $request;
+ }
+
+ /**
+ * Creates a matching authentication for an URL.
+ *
+ * @param string $url
+ *
+ * @return self
+ */
+ public static function createUrlMatcher(Authentication $authentication, $url)
+ {
+ $matcher = function (RequestInterface $request) use ($url) {
+ return preg_match($url, $request->getRequestTarget());
+ };
+
+ return new static($authentication, $matcher);
+ }
+}
diff --git a/vendor/php-http/message/src/Authentication/QueryParam.php b/vendor/php-http/message/src/Authentication/QueryParam.php
new file mode 100644
index 000000000..243efef3f
--- /dev/null
+++ b/vendor/php-http/message/src/Authentication/QueryParam.php
@@ -0,0 +1,47 @@
+
+ */
+final class QueryParam implements Authentication
+{
+ /**
+ * @var array
+ */
+ private $params = [];
+
+ public function __construct(array $params)
+ {
+ $this->params = $params;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function authenticate(RequestInterface $request)
+ {
+ $uri = $request->getUri();
+ $query = $uri->getQuery();
+ $params = [];
+
+ parse_str($query, $params);
+
+ $params = array_merge($params, $this->params);
+
+ $query = http_build_query($params, '', '&');
+
+ $uri = $uri->withQuery($query);
+
+ return $request->withUri($uri);
+ }
+}
diff --git a/vendor/php-http/message/src/Authentication/RequestConditional.php b/vendor/php-http/message/src/Authentication/RequestConditional.php
new file mode 100644
index 000000000..01062cf69
--- /dev/null
+++ b/vendor/php-http/message/src/Authentication/RequestConditional.php
@@ -0,0 +1,43 @@
+
+ */
+final class RequestConditional implements Authentication
+{
+ /**
+ * @var RequestMatcher
+ */
+ private $requestMatcher;
+
+ /**
+ * @var Authentication
+ */
+ private $authentication;
+
+ public function __construct(RequestMatcher $requestMatcher, Authentication $authentication)
+ {
+ $this->requestMatcher = $requestMatcher;
+ $this->authentication = $authentication;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function authenticate(RequestInterface $request)
+ {
+ if ($this->requestMatcher->matches($request)) {
+ return $this->authentication->authenticate($request);
+ }
+
+ return $request;
+ }
+}
diff --git a/vendor/php-http/message/src/Authentication/Wsse.php b/vendor/php-http/message/src/Authentication/Wsse.php
new file mode 100644
index 000000000..f343633de
--- /dev/null
+++ b/vendor/php-http/message/src/Authentication/Wsse.php
@@ -0,0 +1,68 @@
+
+ */
+final class Wsse implements Authentication
+{
+ /**
+ * @var string
+ */
+ private $username;
+
+ /**
+ * @var string
+ */
+ private $password;
+
+ /**
+ * @var string
+ */
+ private $hashAlgorithm;
+
+ /**
+ * @param string $username
+ * @param string $password
+ * @param string $hashAlgorithm To use a better hashing algorithm than the weak sha1, pass the algorithm to use, e.g. "sha512"
+ */
+ public function __construct($username, $password, $hashAlgorithm = 'sha1')
+ {
+ $this->username = $username;
+ $this->password = $password;
+ if (false === in_array($hashAlgorithm, hash_algos())) {
+ throw new InvalidArgumentException(sprintf('Unaccepted hashing algorithm: %s', $hashAlgorithm));
+ }
+ $this->hashAlgorithm = $hashAlgorithm;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function authenticate(RequestInterface $request)
+ {
+ $nonce = substr(md5(uniqid(uniqid().'_', true)), 0, 16);
+ $created = date('c');
+ $digest = base64_encode(hash($this->hashAlgorithm, base64_decode($nonce).$created.$this->password, true));
+
+ $wsse = sprintf(
+ 'UsernameToken Username="%s", PasswordDigest="%s", Nonce="%s", Created="%s"',
+ $this->username,
+ $digest,
+ $nonce,
+ $created
+ );
+
+ return $request
+ ->withHeader('Authorization', 'WSSE profile="UsernameToken"')
+ ->withHeader('X-WSSE', $wsse)
+ ;
+ }
+}
diff --git a/vendor/php-http/message/src/Builder/ResponseBuilder.php b/vendor/php-http/message/src/Builder/ResponseBuilder.php
new file mode 100644
index 000000000..4c3ecfc4f
--- /dev/null
+++ b/vendor/php-http/message/src/Builder/ResponseBuilder.php
@@ -0,0 +1,146 @@
+response = $response;
+ }
+
+ /**
+ * Return response.
+ *
+ * @return ResponseInterface
+ */
+ public function getResponse()
+ {
+ return $this->response;
+ }
+
+ /**
+ * Add headers represented by an array of header lines.
+ *
+ * @param string[] $headers response headers as array of header lines
+ *
+ * @return $this
+ *
+ * @throws \UnexpectedValueException for invalid header values
+ * @throws \InvalidArgumentException for invalid status code arguments
+ */
+ public function setHeadersFromArray(array $headers)
+ {
+ $status = array_shift($headers);
+ $this->setStatus($status);
+
+ foreach ($headers as $headerLine) {
+ $headerLine = trim($headerLine);
+ if ('' === $headerLine) {
+ continue;
+ }
+
+ $this->addHeader($headerLine);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Add headers represented by a single string.
+ *
+ * @param string $headers response headers as single string
+ *
+ * @return $this
+ *
+ * @throws \InvalidArgumentException if $headers is not a string on object with __toString()
+ * @throws \UnexpectedValueException for invalid header values
+ */
+ public function setHeadersFromString($headers)
+ {
+ if (!(is_string($headers)
+ || (is_object($headers) && method_exists($headers, '__toString')))
+ ) {
+ throw new \InvalidArgumentException(
+ sprintf(
+ '%s expects parameter 1 to be a string, %s given',
+ __METHOD__,
+ is_object($headers) ? get_class($headers) : gettype($headers)
+ )
+ );
+ }
+
+ $this->setHeadersFromArray(explode("\r\n", $headers));
+
+ return $this;
+ }
+
+ /**
+ * Set response status from a status string.
+ *
+ * @param string $statusLine response status as a string
+ *
+ * @return $this
+ *
+ * @throws \InvalidArgumentException for invalid status line
+ */
+ public function setStatus($statusLine)
+ {
+ $parts = explode(' ', $statusLine, 3);
+ if (count($parts) < 2 || 0 !== strpos(strtolower($parts[0]), 'http/')) {
+ throw new \InvalidArgumentException(
+ sprintf('"%s" is not a valid HTTP status line', $statusLine)
+ );
+ }
+
+ $reasonPhrase = count($parts) > 2 ? $parts[2] : '';
+ $this->response = $this->response
+ ->withStatus((int) $parts[1], $reasonPhrase)
+ ->withProtocolVersion(substr($parts[0], 5));
+
+ return $this;
+ }
+
+ /**
+ * Add header represented by a string.
+ *
+ * @param string $headerLine response header as a string
+ *
+ * @return $this
+ *
+ * @throws \InvalidArgumentException for invalid header names or values
+ */
+ public function addHeader($headerLine)
+ {
+ $parts = explode(':', $headerLine, 2);
+ if (2 !== count($parts)) {
+ throw new \InvalidArgumentException(
+ sprintf('"%s" is not a valid HTTP header line', $headerLine)
+ );
+ }
+ $name = trim($parts[0]);
+ $value = trim($parts[1]);
+ if ($this->response->hasHeader($name)) {
+ $this->response = $this->response->withAddedHeader($name, $value);
+ } else {
+ $this->response = $this->response->withHeader($name, $value);
+ }
+
+ return $this;
+ }
+}
diff --git a/vendor/php-http/message/src/Cookie.php b/vendor/php-http/message/src/Cookie.php
new file mode 100644
index 000000000..0cc2d43c4
--- /dev/null
+++ b/vendor/php-http/message/src/Cookie.php
@@ -0,0 +1,524 @@
+
+ *
+ * @see http://tools.ietf.org/search/rfc6265
+ */
+final class Cookie
+{
+ /**
+ * @var string
+ */
+ private $name;
+
+ /**
+ * @var string|null
+ */
+ private $value;
+
+ /**
+ * @var int|null
+ */
+ private $maxAge;
+
+ /**
+ * @var string|null
+ */
+ private $domain;
+
+ /**
+ * @var string
+ */
+ private $path;
+
+ /**
+ * @var bool
+ */
+ private $secure;
+
+ /**
+ * @var bool
+ */
+ private $httpOnly;
+
+ /**
+ * Expires attribute is HTTP 1.0 only and should be avoided.
+ *
+ * @var \DateTime|null
+ */
+ private $expires;
+
+ /**
+ * @param string $name
+ * @param string|null $value
+ * @param int|null $maxAge
+ * @param string|null $domain
+ * @param string|null $path
+ * @param bool $secure
+ * @param bool $httpOnly
+ * @param \DateTime|null $expires Expires attribute is HTTP 1.0 only and should be avoided.
+ *
+ * @throws \InvalidArgumentException if name, value or max age is not valid
+ */
+ public function __construct(
+ $name,
+ $value = null,
+ $maxAge = null,
+ $domain = null,
+ $path = null,
+ $secure = false,
+ $httpOnly = false,
+ \DateTime $expires = null
+ ) {
+ $this->validateName($name);
+ $this->validateValue($value);
+ $this->validateMaxAge($maxAge);
+
+ $this->name = $name;
+ $this->value = $value;
+ $this->maxAge = $maxAge;
+ $this->expires = $expires;
+ $this->domain = $this->normalizeDomain($domain);
+ $this->path = $this->normalizePath($path);
+ $this->secure = (bool) $secure;
+ $this->httpOnly = (bool) $httpOnly;
+ }
+
+ /**
+ * Creates a new cookie without any attribute validation.
+ *
+ * @param string $name
+ * @param string|null $value
+ * @param int $maxAge
+ * @param string|null $domain
+ * @param string|null $path
+ * @param bool $secure
+ * @param bool $httpOnly
+ * @param \DateTime|null $expires Expires attribute is HTTP 1.0 only and should be avoided.
+ */
+ public static function createWithoutValidation(
+ $name,
+ $value = null,
+ $maxAge = null,
+ $domain = null,
+ $path = null,
+ $secure = false,
+ $httpOnly = false,
+ \DateTime $expires = null
+ ) {
+ $cookie = new self('name', null, null, $domain, $path, $secure, $httpOnly, $expires);
+ $cookie->name = $name;
+ $cookie->value = $value;
+ $cookie->maxAge = $maxAge;
+
+ return $cookie;
+ }
+
+ /**
+ * Returns the name.
+ *
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Returns the value.
+ *
+ * @return string|null
+ */
+ public function getValue()
+ {
+ return $this->value;
+ }
+
+ /**
+ * Checks if there is a value.
+ *
+ * @return bool
+ */
+ public function hasValue()
+ {
+ return isset($this->value);
+ }
+
+ /**
+ * Sets the value.
+ *
+ * @param string|null $value
+ *
+ * @return Cookie
+ */
+ public function withValue($value)
+ {
+ $this->validateValue($value);
+
+ $new = clone $this;
+ $new->value = $value;
+
+ return $new;
+ }
+
+ /**
+ * Returns the max age.
+ *
+ * @return int|null
+ */
+ public function getMaxAge()
+ {
+ return $this->maxAge;
+ }
+
+ /**
+ * Checks if there is a max age.
+ *
+ * @return bool
+ */
+ public function hasMaxAge()
+ {
+ return isset($this->maxAge);
+ }
+
+ /**
+ * Sets the max age.
+ *
+ * @param int|null $maxAge
+ *
+ * @return Cookie
+ */
+ public function withMaxAge($maxAge)
+ {
+ $this->validateMaxAge($maxAge);
+
+ $new = clone $this;
+ $new->maxAge = $maxAge;
+
+ return $new;
+ }
+
+ /**
+ * Returns the expiration time.
+ *
+ * @return \DateTime|null
+ */
+ public function getExpires()
+ {
+ return $this->expires;
+ }
+
+ /**
+ * Checks if there is an expiration time.
+ *
+ * @return bool
+ */
+ public function hasExpires()
+ {
+ return isset($this->expires);
+ }
+
+ /**
+ * Sets the expires.
+ *
+ * @return Cookie
+ */
+ public function withExpires(\DateTime $expires = null)
+ {
+ $new = clone $this;
+ $new->expires = $expires;
+
+ return $new;
+ }
+
+ /**
+ * Checks if the cookie is expired.
+ *
+ * @return bool
+ */
+ public function isExpired()
+ {
+ return isset($this->expires) and $this->expires < new \DateTime();
+ }
+
+ /**
+ * Returns the domain.
+ *
+ * @return string|null
+ */
+ public function getDomain()
+ {
+ return $this->domain;
+ }
+
+ /**
+ * Checks if there is a domain.
+ *
+ * @return bool
+ */
+ public function hasDomain()
+ {
+ return isset($this->domain);
+ }
+
+ /**
+ * Sets the domain.
+ *
+ * @param string|null $domain
+ *
+ * @return Cookie
+ */
+ public function withDomain($domain)
+ {
+ $new = clone $this;
+ $new->domain = $this->normalizeDomain($domain);
+
+ return $new;
+ }
+
+ /**
+ * Checks whether this cookie is meant for this domain.
+ *
+ * @see http://tools.ietf.org/html/rfc6265#section-5.1.3
+ *
+ * @param string $domain
+ *
+ * @return bool
+ */
+ public function matchDomain($domain)
+ {
+ // Domain is not set or exact match
+ if (!$this->hasDomain() || 0 === strcasecmp($domain, $this->domain)) {
+ return true;
+ }
+
+ // Domain is not an IP address
+ if (filter_var($domain, FILTER_VALIDATE_IP)) {
+ return false;
+ }
+
+ return (bool) preg_match(sprintf('/\b%s$/i', preg_quote($this->domain)), $domain);
+ }
+
+ /**
+ * Returns the path.
+ *
+ * @return string
+ */
+ public function getPath()
+ {
+ return $this->path;
+ }
+
+ /**
+ * Sets the path.
+ *
+ * @param string|null $path
+ *
+ * @return Cookie
+ */
+ public function withPath($path)
+ {
+ $new = clone $this;
+ $new->path = $this->normalizePath($path);
+
+ return $new;
+ }
+
+ /**
+ * Checks whether this cookie is meant for this path.
+ *
+ * @see http://tools.ietf.org/html/rfc6265#section-5.1.4
+ *
+ * @param string $path
+ *
+ * @return bool
+ */
+ public function matchPath($path)
+ {
+ return $this->path === $path || (0 === strpos($path, rtrim($this->path, '/').'/'));
+ }
+
+ /**
+ * Checks whether this cookie may only be sent over HTTPS.
+ *
+ * @return bool
+ */
+ public function isSecure()
+ {
+ return $this->secure;
+ }
+
+ /**
+ * Sets whether this cookie should only be sent over HTTPS.
+ *
+ * @param bool $secure
+ *
+ * @return Cookie
+ */
+ public function withSecure($secure)
+ {
+ $new = clone $this;
+ $new->secure = (bool) $secure;
+
+ return $new;
+ }
+
+ /**
+ * Check whether this cookie may not be accessed through Javascript.
+ *
+ * @return bool
+ */
+ public function isHttpOnly()
+ {
+ return $this->httpOnly;
+ }
+
+ /**
+ * Sets whether this cookie may not be accessed through Javascript.
+ *
+ * @param bool $httpOnly
+ *
+ * @return Cookie
+ */
+ public function withHttpOnly($httpOnly)
+ {
+ $new = clone $this;
+ $new->httpOnly = (bool) $httpOnly;
+
+ return $new;
+ }
+
+ /**
+ * Checks if this cookie represents the same cookie as $cookie.
+ *
+ * This does not compare the values, only name, domain and path.
+ *
+ * @param Cookie $cookie
+ *
+ * @return bool
+ */
+ public function match(self $cookie)
+ {
+ return $this->name === $cookie->name && $this->domain === $cookie->domain and $this->path === $cookie->path;
+ }
+
+ /**
+ * Validates cookie attributes.
+ *
+ * @return bool
+ */
+ public function isValid()
+ {
+ try {
+ $this->validateName($this->name);
+ $this->validateValue($this->value);
+ $this->validateMaxAge($this->maxAge);
+ } catch (\InvalidArgumentException $e) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Validates the name attribute.
+ *
+ * @see http://tools.ietf.org/search/rfc2616#section-2.2
+ *
+ * @param string $name
+ *
+ * @throws \InvalidArgumentException if the name is empty or contains invalid characters
+ */
+ private function validateName($name)
+ {
+ if (strlen($name) < 1) {
+ throw new \InvalidArgumentException('The name cannot be empty');
+ }
+
+ // Name attribute is a token as per spec in RFC 2616
+ if (preg_match('/[\x00-\x20\x22\x28-\x29\x2C\x2F\x3A-\x40\x5B-\x5D\x7B\x7D\x7F]/', $name)) {
+ throw new \InvalidArgumentException(sprintf('The cookie name "%s" contains invalid characters.', $name));
+ }
+ }
+
+ /**
+ * Validates a value.
+ *
+ * @see http://tools.ietf.org/html/rfc6265#section-4.1.1
+ *
+ * @param string|null $value
+ *
+ * @throws \InvalidArgumentException if the value contains invalid characters
+ */
+ private function validateValue($value)
+ {
+ if (isset($value)) {
+ if (preg_match('/[^\x21\x23-\x2B\x2D-\x3A\x3C-\x5B\x5D-\x7E]/', $value)) {
+ throw new \InvalidArgumentException(sprintf('The cookie value "%s" contains invalid characters.', $value));
+ }
+ }
+ }
+
+ /**
+ * Validates a Max-Age attribute.
+ *
+ * @param int|null $maxAge
+ *
+ * @throws \InvalidArgumentException if the Max-Age is not an empty or integer value
+ */
+ private function validateMaxAge($maxAge)
+ {
+ if (isset($maxAge)) {
+ if (!is_int($maxAge)) {
+ throw new \InvalidArgumentException('Max-Age must be integer');
+ }
+ }
+ }
+
+ /**
+ * Remove the leading '.' and lowercase the domain as per spec in RFC 6265.
+ *
+ * @see http://tools.ietf.org/html/rfc6265#section-4.1.2.3
+ * @see http://tools.ietf.org/html/rfc6265#section-5.1.3
+ * @see http://tools.ietf.org/html/rfc6265#section-5.2.3
+ *
+ * @param string|null $domain
+ *
+ * @return string
+ */
+ private function normalizeDomain($domain)
+ {
+ if (isset($domain)) {
+ $domain = ltrim(strtolower($domain), '.');
+ }
+
+ return $domain;
+ }
+
+ /**
+ * Processes path as per spec in RFC 6265.
+ *
+ * @see http://tools.ietf.org/html/rfc6265#section-5.1.4
+ * @see http://tools.ietf.org/html/rfc6265#section-5.2.4
+ *
+ * @param string|null $path
+ *
+ * @return string
+ */
+ private function normalizePath($path)
+ {
+ $path = rtrim($path, '/');
+
+ if (empty($path) or '/' !== substr($path, 0, 1)) {
+ $path = '/';
+ }
+
+ return $path;
+ }
+}
diff --git a/vendor/php-http/message/src/CookieJar.php b/vendor/php-http/message/src/CookieJar.php
new file mode 100644
index 000000000..914ad9797
--- /dev/null
+++ b/vendor/php-http/message/src/CookieJar.php
@@ -0,0 +1,212 @@
+
+ */
+final class CookieJar implements \Countable, \IteratorAggregate
+{
+ /**
+ * @var \SplObjectStorage
+ */
+ private $cookies;
+
+ public function __construct()
+ {
+ $this->cookies = new \SplObjectStorage();
+ }
+
+ /**
+ * Checks if there is a cookie.
+ *
+ * @return bool
+ */
+ public function hasCookie(Cookie $cookie)
+ {
+ return $this->cookies->contains($cookie);
+ }
+
+ /**
+ * Adds a cookie.
+ */
+ public function addCookie(Cookie $cookie)
+ {
+ if (!$this->hasCookie($cookie)) {
+ $cookies = $this->getMatchingCookies($cookie);
+
+ foreach ($cookies as $matchingCookie) {
+ if ($cookie->getValue() !== $matchingCookie->getValue() || $cookie->getMaxAge() > $matchingCookie->getMaxAge()) {
+ $this->removeCookie($matchingCookie);
+
+ continue;
+ }
+ }
+
+ if ($cookie->hasValue()) {
+ $this->cookies->attach($cookie);
+ }
+ }
+ }
+
+ /**
+ * Removes a cookie.
+ */
+ public function removeCookie(Cookie $cookie)
+ {
+ $this->cookies->detach($cookie);
+ }
+
+ /**
+ * Returns the cookies.
+ *
+ * @return Cookie[]
+ */
+ public function getCookies()
+ {
+ $match = function ($matchCookie) {
+ return true;
+ };
+
+ return $this->findMatchingCookies($match);
+ }
+
+ /**
+ * Returns all matching cookies.
+ *
+ * @return Cookie[]
+ */
+ public function getMatchingCookies(Cookie $cookie)
+ {
+ $match = function ($matchCookie) use ($cookie) {
+ return $matchCookie->match($cookie);
+ };
+
+ return $this->findMatchingCookies($match);
+ }
+
+ /**
+ * Finds matching cookies based on a callable.
+ *
+ * @return Cookie[]
+ */
+ private function findMatchingCookies(callable $match)
+ {
+ $cookies = [];
+
+ foreach ($this->cookies as $cookie) {
+ if ($match($cookie)) {
+ $cookies[] = $cookie;
+ }
+ }
+
+ return $cookies;
+ }
+
+ /**
+ * Checks if there are cookies.
+ *
+ * @return bool
+ */
+ public function hasCookies()
+ {
+ return $this->cookies->count() > 0;
+ }
+
+ /**
+ * Sets the cookies and removes any previous one.
+ *
+ * @param Cookie[] $cookies
+ */
+ public function setCookies(array $cookies)
+ {
+ $this->clear();
+ $this->addCookies($cookies);
+ }
+
+ /**
+ * Adds some cookies.
+ *
+ * @param Cookie[] $cookies
+ */
+ public function addCookies(array $cookies)
+ {
+ foreach ($cookies as $cookie) {
+ $this->addCookie($cookie);
+ }
+ }
+
+ /**
+ * Removes some cookies.
+ *
+ * @param Cookie[] $cookies
+ */
+ public function removeCookies(array $cookies)
+ {
+ foreach ($cookies as $cookie) {
+ $this->removeCookie($cookie);
+ }
+ }
+
+ /**
+ * Removes cookies which match the given parameters.
+ *
+ * Null means that parameter should not be matched
+ *
+ * @param string|null $name
+ * @param string|null $domain
+ * @param string|null $path
+ */
+ public function removeMatchingCookies($name = null, $domain = null, $path = null)
+ {
+ $match = function ($cookie) use ($name, $domain, $path) {
+ $match = true;
+
+ if (isset($name)) {
+ $match = $match && ($cookie->getName() === $name);
+ }
+
+ if (isset($domain)) {
+ $match = $match && $cookie->matchDomain($domain);
+ }
+
+ if (isset($path)) {
+ $match = $match && $cookie->matchPath($path);
+ }
+
+ return $match;
+ };
+
+ $cookies = $this->findMatchingCookies($match);
+
+ $this->removeCookies($cookies);
+ }
+
+ /**
+ * Removes all cookies.
+ */
+ public function clear()
+ {
+ $this->cookies = new \SplObjectStorage();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ #[\ReturnTypeWillChange]
+ public function count()
+ {
+ return $this->cookies->count();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ #[\ReturnTypeWillChange]
+ public function getIterator()
+ {
+ return clone $this->cookies;
+ }
+}
diff --git a/vendor/php-http/message/src/CookieUtil.php b/vendor/php-http/message/src/CookieUtil.php
new file mode 100644
index 000000000..44c53145e
--- /dev/null
+++ b/vendor/php-http/message/src/CookieUtil.php
@@ -0,0 +1,53 @@
+
+ */
+trait MessageDecorator
+{
+ /**
+ * @var MessageInterface
+ */
+ private $message;
+
+ /**
+ * Returns the decorated message.
+ *
+ * Since the underlying Message is immutable as well
+ * exposing it is not an issue, because it's state cannot be altered
+ *
+ * @return MessageInterface
+ */
+ public function getMessage()
+ {
+ return $this->message;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getProtocolVersion()
+ {
+ return $this->message->getProtocolVersion();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function withProtocolVersion($version)
+ {
+ $new = clone $this;
+ $new->message = $this->message->withProtocolVersion($version);
+
+ return $new;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getHeaders()
+ {
+ return $this->message->getHeaders();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasHeader($header)
+ {
+ return $this->message->hasHeader($header);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getHeader($header)
+ {
+ return $this->message->getHeader($header);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getHeaderLine($header)
+ {
+ return $this->message->getHeaderLine($header);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function withHeader($header, $value)
+ {
+ $new = clone $this;
+ $new->message = $this->message->withHeader($header, $value);
+
+ return $new;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function withAddedHeader($header, $value)
+ {
+ $new = clone $this;
+ $new->message = $this->message->withAddedHeader($header, $value);
+
+ return $new;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function withoutHeader($header)
+ {
+ $new = clone $this;
+ $new->message = $this->message->withoutHeader($header);
+
+ return $new;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getBody()
+ {
+ return $this->message->getBody();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function withBody(StreamInterface $body)
+ {
+ $new = clone $this;
+ $new->message = $this->message->withBody($body);
+
+ return $new;
+ }
+}
diff --git a/vendor/php-http/message/src/Decorator/RequestDecorator.php b/vendor/php-http/message/src/Decorator/RequestDecorator.php
new file mode 100644
index 000000000..bd254a8fc
--- /dev/null
+++ b/vendor/php-http/message/src/Decorator/RequestDecorator.php
@@ -0,0 +1,86 @@
+
+ */
+trait RequestDecorator
+{
+ use MessageDecorator {
+ getMessage as getRequest;
+ }
+
+ /**
+ * Exchanges the underlying request with another.
+ *
+ * @return self
+ */
+ public function withRequest(RequestInterface $request)
+ {
+ $new = clone $this;
+ $new->message = $request;
+
+ return $new;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getRequestTarget()
+ {
+ return $this->message->getRequestTarget();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function withRequestTarget($requestTarget)
+ {
+ $new = clone $this;
+ $new->message = $this->message->withRequestTarget($requestTarget);
+
+ return $new;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMethod()
+ {
+ return $this->message->getMethod();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function withMethod($method)
+ {
+ $new = clone $this;
+ $new->message = $this->message->withMethod($method);
+
+ return $new;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getUri()
+ {
+ return $this->message->getUri();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function withUri(UriInterface $uri, $preserveHost = false)
+ {
+ $new = clone $this;
+ $new->message = $this->message->withUri($uri, $preserveHost);
+
+ return $new;
+ }
+}
diff --git a/vendor/php-http/message/src/Decorator/ResponseDecorator.php b/vendor/php-http/message/src/Decorator/ResponseDecorator.php
new file mode 100644
index 000000000..20319ed31
--- /dev/null
+++ b/vendor/php-http/message/src/Decorator/ResponseDecorator.php
@@ -0,0 +1,55 @@
+
+ */
+trait ResponseDecorator
+{
+ use MessageDecorator {
+ getMessage as getResponse;
+ }
+
+ /**
+ * Exchanges the underlying response with another.
+ *
+ * @return self
+ */
+ public function withResponse(ResponseInterface $response)
+ {
+ $new = clone $this;
+ $new->message = $response;
+
+ return $new;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getStatusCode()
+ {
+ return $this->message->getStatusCode();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function withStatus($code, $reasonPhrase = '')
+ {
+ $new = clone $this;
+ $new->message = $this->message->withStatus($code, $reasonPhrase);
+
+ return $new;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getReasonPhrase()
+ {
+ return $this->message->getReasonPhrase();
+ }
+}
diff --git a/vendor/php-http/message/src/Decorator/StreamDecorator.php b/vendor/php-http/message/src/Decorator/StreamDecorator.php
new file mode 100644
index 000000000..f405c7afe
--- /dev/null
+++ b/vendor/php-http/message/src/Decorator/StreamDecorator.php
@@ -0,0 +1,138 @@
+
+ */
+trait StreamDecorator
+{
+ /**
+ * @var StreamInterface
+ */
+ protected $stream;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function __toString()
+ {
+ return $this->stream->__toString();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function close()
+ {
+ $this->stream->close();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function detach()
+ {
+ return $this->stream->detach();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getSize()
+ {
+ return $this->stream->getSize();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function tell()
+ {
+ return $this->stream->tell();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function eof()
+ {
+ return $this->stream->eof();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isSeekable()
+ {
+ return $this->stream->isSeekable();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function seek($offset, $whence = SEEK_SET)
+ {
+ $this->stream->seek($offset, $whence);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function rewind()
+ {
+ $this->stream->rewind();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isWritable()
+ {
+ return $this->stream->isWritable();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function write($string)
+ {
+ return $this->stream->write($string);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isReadable()
+ {
+ return $this->stream->isReadable();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function read($length)
+ {
+ return $this->stream->read($length);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getContents()
+ {
+ return $this->stream->getContents();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMetadata($key = null)
+ {
+ return $this->stream->getMetadata($key);
+ }
+}
diff --git a/vendor/php-http/message/src/Encoding/ChunkStream.php b/vendor/php-http/message/src/Encoding/ChunkStream.php
new file mode 100644
index 000000000..74c2fbd09
--- /dev/null
+++ b/vendor/php-http/message/src/Encoding/ChunkStream.php
@@ -0,0 +1,39 @@
+
+ */
+class ChunkStream extends FilteredStream
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function readFilter()
+ {
+ return 'chunk';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function writeFilter()
+ {
+ return 'dechunk';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function fill()
+ {
+ parent::fill();
+
+ if ($this->stream->eof()) {
+ $this->buffer .= "0\r\n\r\n";
+ }
+ }
+}
diff --git a/vendor/php-http/message/src/Encoding/CompressStream.php b/vendor/php-http/message/src/Encoding/CompressStream.php
new file mode 100644
index 000000000..bdb740a91
--- /dev/null
+++ b/vendor/php-http/message/src/Encoding/CompressStream.php
@@ -0,0 +1,45 @@
+
+ */
+class CompressStream extends FilteredStream
+{
+ /**
+ * @param int $level
+ */
+ public function __construct(StreamInterface $stream, $level = -1)
+ {
+ if (!extension_loaded('zlib')) {
+ throw new \RuntimeException('The zlib extension must be enabled to use this stream');
+ }
+
+ parent::__construct($stream, ['window' => 15, 'level' => $level]);
+
+ // @deprecated will be removed in 2.0
+ $this->writeFilterCallback = Filter\fun($this->writeFilter(), ['window' => 15]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function readFilter()
+ {
+ return 'zlib.deflate';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function writeFilter()
+ {
+ return 'zlib.inflate';
+ }
+}
diff --git a/vendor/php-http/message/src/Encoding/DechunkStream.php b/vendor/php-http/message/src/Encoding/DechunkStream.php
new file mode 100644
index 000000000..4cade835c
--- /dev/null
+++ b/vendor/php-http/message/src/Encoding/DechunkStream.php
@@ -0,0 +1,29 @@
+
+ */
+class DechunkStream extends FilteredStream
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function readFilter()
+ {
+ return 'dechunk';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function writeFilter()
+ {
+ return 'chunk';
+ }
+}
diff --git a/vendor/php-http/message/src/Encoding/DecompressStream.php b/vendor/php-http/message/src/Encoding/DecompressStream.php
new file mode 100644
index 000000000..ab3a34543
--- /dev/null
+++ b/vendor/php-http/message/src/Encoding/DecompressStream.php
@@ -0,0 +1,45 @@
+
+ */
+class DecompressStream extends FilteredStream
+{
+ /**
+ * @param int $level
+ */
+ public function __construct(StreamInterface $stream, $level = -1)
+ {
+ if (!extension_loaded('zlib')) {
+ throw new \RuntimeException('The zlib extension must be enabled to use this stream');
+ }
+
+ parent::__construct($stream, ['window' => 15]);
+
+ // @deprecated will be removed in 2.0
+ $this->writeFilterCallback = Filter\fun($this->writeFilter(), ['window' => 15, 'level' => $level]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function readFilter()
+ {
+ return 'zlib.inflate';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function writeFilter()
+ {
+ return 'zlib.deflate';
+ }
+}
diff --git a/vendor/php-http/message/src/Encoding/DeflateStream.php b/vendor/php-http/message/src/Encoding/DeflateStream.php
new file mode 100644
index 000000000..2ab3e0038
--- /dev/null
+++ b/vendor/php-http/message/src/Encoding/DeflateStream.php
@@ -0,0 +1,41 @@
+
+ */
+class DeflateStream extends FilteredStream
+{
+ /**
+ * @param int $level
+ */
+ public function __construct(StreamInterface $stream, $level = -1)
+ {
+ parent::__construct($stream, ['window' => -15, 'level' => $level]);
+
+ // @deprecated will be removed in 2.0
+ $this->writeFilterCallback = Filter\fun($this->writeFilter(), ['window' => -15]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function readFilter()
+ {
+ return 'zlib.deflate';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function writeFilter()
+ {
+ return 'zlib.inflate';
+ }
+}
diff --git a/vendor/php-http/message/src/Encoding/Filter/Chunk.php b/vendor/php-http/message/src/Encoding/Filter/Chunk.php
new file mode 100644
index 000000000..538e27007
--- /dev/null
+++ b/vendor/php-http/message/src/Encoding/Filter/Chunk.php
@@ -0,0 +1,31 @@
+
+ */
+class Chunk extends \php_user_filter
+{
+ /**
+ * {@inheritdoc}
+ */
+ #[\ReturnTypeWillChange]
+ public function filter($in, $out, &$consumed, $closing)
+ {
+ while ($bucket = stream_bucket_make_writeable($in)) {
+ $lenbucket = stream_bucket_new($this->stream, dechex($bucket->datalen)."\r\n");
+ stream_bucket_append($out, $lenbucket);
+
+ $consumed += $bucket->datalen;
+ stream_bucket_append($out, $bucket);
+
+ $lenbucket = stream_bucket_new($this->stream, "\r\n");
+ stream_bucket_append($out, $lenbucket);
+ }
+
+ return PSFS_PASS_ON;
+ }
+}
diff --git a/vendor/php-http/message/src/Encoding/FilteredStream.php b/vendor/php-http/message/src/Encoding/FilteredStream.php
new file mode 100644
index 000000000..a937c82f6
--- /dev/null
+++ b/vendor/php-http/message/src/Encoding/FilteredStream.php
@@ -0,0 +1,234 @@
+
+ */
+abstract class FilteredStream implements StreamInterface
+{
+ use StreamDecorator {
+ rewind as private doRewind;
+ seek as private doSeek;
+ }
+ const BUFFER_SIZE = 8192;
+
+ /**
+ * @var callable
+ */
+ protected $readFilterCallback;
+
+ /**
+ * @var resource
+ *
+ * @deprecated since version 1.5, will be removed in 2.0
+ */
+ protected $readFilter;
+
+ /**
+ * @var callable
+ *
+ * @deprecated since version 1.5, will be removed in 2.0
+ */
+ protected $writeFilterCallback;
+
+ /**
+ * @var resource
+ *
+ * @deprecated since version 1.5, will be removed in 2.0
+ */
+ protected $writeFilter;
+
+ /**
+ * Internal buffer.
+ *
+ * @var string
+ */
+ protected $buffer = '';
+
+ /**
+ * @param mixed|null $readFilterOptions
+ * @param mixed|null $writeFilterOptions deprecated since 1.5, will be removed in 2.0
+ */
+ public function __construct(StreamInterface $stream, $readFilterOptions = null, $writeFilterOptions = null)
+ {
+ if (null !== $readFilterOptions) {
+ $this->readFilterCallback = Filter\fun($this->readFilter(), $readFilterOptions);
+ } else {
+ $this->readFilterCallback = Filter\fun($this->readFilter());
+ }
+
+ if (null !== $writeFilterOptions) {
+ $this->writeFilterCallback = Filter\fun($this->writeFilter(), $writeFilterOptions);
+
+ @trigger_error('The $writeFilterOptions argument is deprecated since version 1.5 and will be removed in 2.0.', E_USER_DEPRECATED);
+ } else {
+ $this->writeFilterCallback = Filter\fun($this->writeFilter());
+ }
+
+ $this->stream = $stream;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function read($length)
+ {
+ if (strlen($this->buffer) >= $length) {
+ $read = substr($this->buffer, 0, $length);
+ $this->buffer = substr($this->buffer, $length);
+
+ return $read;
+ }
+
+ if ($this->stream->eof()) {
+ $buffer = $this->buffer;
+ $this->buffer = '';
+
+ return $buffer;
+ }
+
+ $read = $this->buffer;
+ $this->buffer = '';
+ $this->fill();
+
+ return $read.$this->read($length - strlen($read));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function eof()
+ {
+ return $this->stream->eof() && '' === $this->buffer;
+ }
+
+ /**
+ * Buffer is filled by reading underlying stream.
+ *
+ * Callback is reading once more even if the stream is ended.
+ * This allow to get last data in the PHP buffer otherwise this
+ * bug is present : https://bugs.php.net/bug.php?id=48725
+ */
+ protected function fill()
+ {
+ $readFilterCallback = $this->readFilterCallback;
+ $this->buffer .= $readFilterCallback($this->stream->read(self::BUFFER_SIZE));
+
+ if ($this->stream->eof()) {
+ $this->buffer .= $readFilterCallback();
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getContents()
+ {
+ $buffer = '';
+
+ while (!$this->eof()) {
+ $buf = $this->read(self::BUFFER_SIZE);
+ // Using a loose equality here to match on '' and false.
+ if (null == $buf) {
+ break;
+ }
+
+ $buffer .= $buf;
+ }
+
+ return $buffer;
+ }
+
+ /**
+ * Always returns null because we can't tell the size of a stream when we filter.
+ */
+ public function getSize()
+ {
+ return null;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function __toString()
+ {
+ return $this->getContents();
+ }
+
+ /**
+ * Filtered streams are not seekable.
+ *
+ * We would need to buffer and process everything to allow seeking.
+ */
+ public function isSeekable()
+ {
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function rewind()
+ {
+ @trigger_error('Filtered streams are not seekable. This method will start raising an exception in the next major version', E_USER_DEPRECATED);
+ $this->doRewind();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function seek($offset, $whence = SEEK_SET)
+ {
+ @trigger_error('Filtered streams are not seekable. This method will start raising an exception in the next major version', E_USER_DEPRECATED);
+ $this->doSeek($offset, $whence);
+ }
+
+ /**
+ * Returns the read filter name.
+ *
+ * @return string
+ *
+ * @deprecated since version 1.5, will be removed in 2.0
+ */
+ public function getReadFilter()
+ {
+ @trigger_error('The '.__CLASS__.'::'.__METHOD__.' method is deprecated since version 1.5 and will be removed in 2.0.', E_USER_DEPRECATED);
+
+ return $this->readFilter();
+ }
+
+ /**
+ * Returns the write filter name.
+ *
+ * @return string
+ */
+ abstract protected function readFilter();
+
+ /**
+ * Returns the write filter name.
+ *
+ * @return string
+ *
+ * @deprecated since version 1.5, will be removed in 2.0
+ */
+ public function getWriteFilter()
+ {
+ @trigger_error('The '.__CLASS__.'::'.__METHOD__.' method is deprecated since version 1.5 and will be removed in 2.0.', E_USER_DEPRECATED);
+
+ return $this->writeFilter();
+ }
+
+ /**
+ * Returns the write filter name.
+ *
+ * @return string
+ */
+ abstract protected function writeFilter();
+}
diff --git a/vendor/php-http/message/src/Encoding/GzipDecodeStream.php b/vendor/php-http/message/src/Encoding/GzipDecodeStream.php
new file mode 100644
index 000000000..92b5dad57
--- /dev/null
+++ b/vendor/php-http/message/src/Encoding/GzipDecodeStream.php
@@ -0,0 +1,45 @@
+
+ */
+class GzipDecodeStream extends FilteredStream
+{
+ /**
+ * @param int $level
+ */
+ public function __construct(StreamInterface $stream, $level = -1)
+ {
+ if (!extension_loaded('zlib')) {
+ throw new \RuntimeException('The zlib extension must be enabled to use this stream');
+ }
+
+ parent::__construct($stream, ['window' => 31]);
+
+ // @deprecated will be removed in 2.0
+ $this->writeFilterCallback = Filter\fun($this->writeFilter(), ['window' => 31, 'level' => $level]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function readFilter()
+ {
+ return 'zlib.inflate';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function writeFilter()
+ {
+ return 'zlib.deflate';
+ }
+}
diff --git a/vendor/php-http/message/src/Encoding/GzipEncodeStream.php b/vendor/php-http/message/src/Encoding/GzipEncodeStream.php
new file mode 100644
index 000000000..13f097a87
--- /dev/null
+++ b/vendor/php-http/message/src/Encoding/GzipEncodeStream.php
@@ -0,0 +1,45 @@
+
+ */
+class GzipEncodeStream extends FilteredStream
+{
+ /**
+ * @param int $level
+ */
+ public function __construct(StreamInterface $stream, $level = -1)
+ {
+ if (!extension_loaded('zlib')) {
+ throw new \RuntimeException('The zlib extension must be enabled to use this stream');
+ }
+
+ parent::__construct($stream, ['window' => 31, 'level' => $level]);
+
+ // @deprecated will be removed in 2.0
+ $this->writeFilterCallback = Filter\fun($this->writeFilter(), ['window' => 31]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function readFilter()
+ {
+ return 'zlib.deflate';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function writeFilter()
+ {
+ return 'zlib.inflate';
+ }
+}
diff --git a/vendor/php-http/message/src/Encoding/InflateStream.php b/vendor/php-http/message/src/Encoding/InflateStream.php
new file mode 100644
index 000000000..06c518750
--- /dev/null
+++ b/vendor/php-http/message/src/Encoding/InflateStream.php
@@ -0,0 +1,45 @@
+
+ */
+class InflateStream extends FilteredStream
+{
+ /**
+ * @param int $level
+ */
+ public function __construct(StreamInterface $stream, $level = -1)
+ {
+ if (!extension_loaded('zlib')) {
+ throw new \RuntimeException('The zlib extension must be enabled to use this stream');
+ }
+
+ parent::__construct($stream, ['window' => -15]);
+
+ // @deprecated will be removed in 2.0
+ $this->writeFilterCallback = Filter\fun($this->writeFilter(), ['window' => -15, 'level' => $level]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function readFilter()
+ {
+ return 'zlib.inflate';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function writeFilter()
+ {
+ return 'zlib.deflate';
+ }
+}
diff --git a/vendor/php-http/message/src/Exception.php b/vendor/php-http/message/src/Exception.php
new file mode 100644
index 000000000..80d4cd9de
--- /dev/null
+++ b/vendor/php-http/message/src/Exception.php
@@ -0,0 +1,10 @@
+
+ *
+ * The formatResponseForRequest method will be added to this interface in the next major version, replacing the formatRequest method.
+ * Meanwhile, callers SHOULD check the formatter for the existence of formatResponseForRequest and call that if available.
+ *
+ * @method string formatResponseForRequest(ResponseInterface $response, RequestInterface $request) Formats a response in context of its request.
+ */
+interface Formatter
+{
+ /**
+ * Formats a request.
+ *
+ * @return string
+ */
+ public function formatRequest(RequestInterface $request);
+
+ /**
+ * @deprecated since 1.13, use formatResponseForRequest() instead
+ *
+ * Formats a response.
+ *
+ * @return string
+ */
+ public function formatResponse(ResponseInterface $response);
+}
diff --git a/vendor/php-http/message/src/Formatter/CurlCommandFormatter.php b/vendor/php-http/message/src/Formatter/CurlCommandFormatter.php
new file mode 100644
index 000000000..80d2971cb
--- /dev/null
+++ b/vendor/php-http/message/src/Formatter/CurlCommandFormatter.php
@@ -0,0 +1,103 @@
+
+ */
+class CurlCommandFormatter implements Formatter
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function formatRequest(RequestInterface $request)
+ {
+ $command = sprintf('curl %s', escapeshellarg((string) $request->getUri()->withFragment('')));
+ if ('1.0' === $request->getProtocolVersion()) {
+ $command .= ' --http1.0';
+ } elseif ('2.0' === $request->getProtocolVersion()) {
+ $command .= ' --http2';
+ }
+
+ $method = strtoupper($request->getMethod());
+ if ('HEAD' === $method) {
+ $command .= ' --head';
+ } elseif ('GET' !== $method) {
+ $command .= ' --request '.$method;
+ }
+
+ $command .= $this->getHeadersAsCommandOptions($request);
+
+ $body = $request->getBody();
+ if ($body->getSize() > 0) {
+ // escapeshellarg argument max length on Windows, but longer body in curl command would be impractical anyways
+ if ($body->getSize() > 8192) {
+ $data = '[too long stream omitted]';
+ } elseif ($body->isSeekable()) {
+ $data = $body->__toString();
+ $body->rewind();
+ // all non-printable ASCII characters and except for \t, \r, \n
+ if (preg_match('/([\x00-\x09\x0C\x0E-\x1F\x7F])/', $data)) {
+ $data = '[binary stream omitted]';
+ }
+ } else {
+ $data = '[non-seekable stream omitted]';
+ }
+ $escapedData = @escapeshellarg($data);
+ if (empty($escapedData)) {
+ $escapedData = 'We couldn\'t not escape the data properly';
+ }
+
+ $command .= sprintf(' --data %s', $escapedData);
+ }
+
+ return $command;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function formatResponse(ResponseInterface $response)
+ {
+ return '';
+ }
+
+ /**
+ * Formats a response in context of its request.
+ *
+ * @return string
+ */
+ public function formatResponseForRequest(ResponseInterface $response, RequestInterface $request)
+ {
+ return $this->formatResponse($response);
+ }
+
+ /**
+ * @return string
+ */
+ private function getHeadersAsCommandOptions(RequestInterface $request)
+ {
+ $command = '';
+ foreach ($request->getHeaders() as $name => $values) {
+ if ('host' === strtolower($name) && $values[0] === $request->getUri()->getHost()) {
+ continue;
+ }
+
+ if ('user-agent' === strtolower($name)) {
+ $command .= sprintf(' -A %s', escapeshellarg($values[0]));
+
+ continue;
+ }
+
+ $command .= sprintf(' -H %s', escapeshellarg($name.': '.$request->getHeaderLine($name)));
+ }
+
+ return $command;
+ }
+}
diff --git a/vendor/php-http/message/src/Formatter/FullHttpMessageFormatter.php b/vendor/php-http/message/src/Formatter/FullHttpMessageFormatter.php
new file mode 100644
index 000000000..8b9b1264e
--- /dev/null
+++ b/vendor/php-http/message/src/Formatter/FullHttpMessageFormatter.php
@@ -0,0 +1,116 @@
+
+ */
+class FullHttpMessageFormatter implements Formatter
+{
+ /**
+ * The maximum length of the body.
+ *
+ * @var int|null
+ */
+ private $maxBodyLength;
+
+ /**
+ * @var string
+ */
+ private $binaryDetectionRegex;
+
+ /**
+ * @param int|null $maxBodyLength
+ * @param string $binaryDetectionRegex By default, this is all non-printable ASCII characters and except for \t, \r, \n
+ */
+ public function __construct($maxBodyLength = 1000, string $binaryDetectionRegex = '/([\x00-\x09\x0C\x0E-\x1F\x7F])/')
+ {
+ $this->maxBodyLength = $maxBodyLength;
+ $this->binaryDetectionRegex = $binaryDetectionRegex;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function formatRequest(RequestInterface $request)
+ {
+ $message = sprintf(
+ "%s %s HTTP/%s\n",
+ $request->getMethod(),
+ $request->getRequestTarget(),
+ $request->getProtocolVersion()
+ );
+
+ foreach ($request->getHeaders() as $name => $values) {
+ $message .= $name.': '.implode(', ', $values)."\n";
+ }
+
+ return $this->addBody($request, $message);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function formatResponse(ResponseInterface $response)
+ {
+ $message = sprintf(
+ "HTTP/%s %s %s\n",
+ $response->getProtocolVersion(),
+ $response->getStatusCode(),
+ $response->getReasonPhrase()
+ );
+
+ foreach ($response->getHeaders() as $name => $values) {
+ $message .= $name.': '.implode(', ', $values)."\n";
+ }
+
+ return $this->addBody($response, $message);
+ }
+
+ /**
+ * Formats a response in context of its request.
+ *
+ * @return string
+ */
+ public function formatResponseForRequest(ResponseInterface $response, RequestInterface $request)
+ {
+ return $this->formatResponse($response);
+ }
+
+ /**
+ * Add the message body if the stream is seekable.
+ *
+ * @param string $message
+ *
+ * @return string
+ */
+ private function addBody(MessageInterface $request, $message)
+ {
+ $message .= "\n";
+ $stream = $request->getBody();
+ if (!$stream->isSeekable() || 0 === $this->maxBodyLength) {
+ // Do not read the stream
+ return $message;
+ }
+
+ $data = $stream->__toString();
+ $stream->rewind();
+
+ if (preg_match($this->binaryDetectionRegex, $data)) {
+ return $message.'[binary stream omitted]';
+ }
+
+ if (null === $this->maxBodyLength) {
+ return $message.$data;
+ }
+
+ return $message.mb_substr($data, 0, $this->maxBodyLength);
+ }
+}
diff --git a/vendor/php-http/message/src/Formatter/SimpleFormatter.php b/vendor/php-http/message/src/Formatter/SimpleFormatter.php
new file mode 100644
index 000000000..ee99ae3f3
--- /dev/null
+++ b/vendor/php-http/message/src/Formatter/SimpleFormatter.php
@@ -0,0 +1,52 @@
+
+ * @author Márk Sági-Kazár
+ */
+class SimpleFormatter implements Formatter
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function formatRequest(RequestInterface $request)
+ {
+ return sprintf(
+ '%s %s %s',
+ $request->getMethod(),
+ $request->getUri()->__toString(),
+ $request->getProtocolVersion()
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function formatResponse(ResponseInterface $response)
+ {
+ return sprintf(
+ '%s %s %s',
+ $response->getStatusCode(),
+ $response->getReasonPhrase(),
+ $response->getProtocolVersion()
+ );
+ }
+
+ /**
+ * Formats a response in context of its request.
+ *
+ * @return string
+ */
+ public function formatResponseForRequest(ResponseInterface $response, RequestInterface $request)
+ {
+ return $this->formatResponse($response);
+ }
+}
diff --git a/vendor/php-http/message/src/MessageFactory/DiactorosMessageFactory.php b/vendor/php-http/message/src/MessageFactory/DiactorosMessageFactory.php
new file mode 100644
index 000000000..6d54d3510
--- /dev/null
+++ b/vendor/php-http/message/src/MessageFactory/DiactorosMessageFactory.php
@@ -0,0 +1,82 @@
+
+ *
+ * @deprecated This will be removed in php-http/message2.0. Consider using the official Diactoros PSR-17 factory
+ */
+final class DiactorosMessageFactory implements MessageFactory
+{
+ /**
+ * @var DiactorosStreamFactory
+ */
+ private $streamFactory;
+
+ public function __construct()
+ {
+ $this->streamFactory = new DiactorosStreamFactory();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function createRequest(
+ $method,
+ $uri,
+ array $headers = [],
+ $body = null,
+ $protocolVersion = '1.1'
+ ) {
+ if (class_exists(LaminasRequest::class)) {
+ return (new LaminasRequest(
+ $uri,
+ $method,
+ $this->streamFactory->createStream($body),
+ $headers
+ ))->withProtocolVersion($protocolVersion);
+ }
+
+ return (new ZendRequest(
+ $uri,
+ $method,
+ $this->streamFactory->createStream($body),
+ $headers
+ ))->withProtocolVersion($protocolVersion);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function createResponse(
+ $statusCode = 200,
+ $reasonPhrase = null,
+ array $headers = [],
+ $body = null,
+ $protocolVersion = '1.1'
+ ) {
+ if (class_exists(LaminasResponse::class)) {
+ return (new LaminasResponse(
+ $this->streamFactory->createStream($body),
+ $statusCode,
+ $headers
+ ))->withProtocolVersion($protocolVersion);
+ }
+
+ return (new ZendResponse(
+ $this->streamFactory->createStream($body),
+ $statusCode,
+ $headers
+ ))->withProtocolVersion($protocolVersion);
+ }
+}
diff --git a/vendor/php-http/message/src/MessageFactory/GuzzleMessageFactory.php b/vendor/php-http/message/src/MessageFactory/GuzzleMessageFactory.php
new file mode 100644
index 000000000..02989d9f6
--- /dev/null
+++ b/vendor/php-http/message/src/MessageFactory/GuzzleMessageFactory.php
@@ -0,0 +1,55 @@
+
+ *
+ * @deprecated This will be removed in php-http/message2.0. Consider using the official Guzzle PSR-17 factory
+ */
+final class GuzzleMessageFactory implements MessageFactory
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function createRequest(
+ $method,
+ $uri,
+ array $headers = [],
+ $body = null,
+ $protocolVersion = '1.1'
+ ) {
+ return new Request(
+ $method,
+ $uri,
+ $headers,
+ $body,
+ $protocolVersion
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function createResponse(
+ $statusCode = 200,
+ $reasonPhrase = null,
+ array $headers = [],
+ $body = null,
+ $protocolVersion = '1.1'
+ ) {
+ return new Response(
+ $statusCode,
+ $headers,
+ $body,
+ $protocolVersion,
+ $reasonPhrase
+ );
+ }
+}
diff --git a/vendor/php-http/message/src/MessageFactory/SlimMessageFactory.php b/vendor/php-http/message/src/MessageFactory/SlimMessageFactory.php
new file mode 100644
index 000000000..bee93228b
--- /dev/null
+++ b/vendor/php-http/message/src/MessageFactory/SlimMessageFactory.php
@@ -0,0 +1,74 @@
+
+ *
+ * @deprecated This will be removed in php-http/message2.0. Consider using the official Slim PSR-17 factory
+ */
+final class SlimMessageFactory implements MessageFactory
+{
+ /**
+ * @var SlimStreamFactory
+ */
+ private $streamFactory;
+
+ /**
+ * @var SlimUriFactory
+ */
+ private $uriFactory;
+
+ public function __construct()
+ {
+ $this->streamFactory = new SlimStreamFactory();
+ $this->uriFactory = new SlimUriFactory();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function createRequest(
+ $method,
+ $uri,
+ array $headers = [],
+ $body = null,
+ $protocolVersion = '1.1'
+ ) {
+ return (new Request(
+ $method,
+ $this->uriFactory->createUri($uri),
+ new Headers($headers),
+ [],
+ [],
+ $this->streamFactory->createStream($body),
+ []
+ ))->withProtocolVersion($protocolVersion);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function createResponse(
+ $statusCode = 200,
+ $reasonPhrase = null,
+ array $headers = [],
+ $body = null,
+ $protocolVersion = '1.1'
+ ) {
+ return (new Response(
+ $statusCode,
+ new Headers($headers),
+ $this->streamFactory->createStream($body)
+ ))->withProtocolVersion($protocolVersion);
+ }
+}
diff --git a/vendor/php-http/message/src/RequestMatcher.php b/vendor/php-http/message/src/RequestMatcher.php
new file mode 100644
index 000000000..94fe53240
--- /dev/null
+++ b/vendor/php-http/message/src/RequestMatcher.php
@@ -0,0 +1,26 @@
+
+ */
+interface RequestMatcher
+{
+ /**
+ * Decides whether the rule(s) implemented by the strategy matches the supplied request.
+ *
+ * @param RequestInterface $request The PSR7 request to check for a match
+ *
+ * @return bool true if the request matches, false otherwise
+ */
+ public function matches(RequestInterface $request);
+}
diff --git a/vendor/php-http/message/src/RequestMatcher/CallbackRequestMatcher.php b/vendor/php-http/message/src/RequestMatcher/CallbackRequestMatcher.php
new file mode 100644
index 000000000..1197dd959
--- /dev/null
+++ b/vendor/php-http/message/src/RequestMatcher/CallbackRequestMatcher.php
@@ -0,0 +1,32 @@
+
+ */
+final class CallbackRequestMatcher implements RequestMatcher
+{
+ /**
+ * @var callable
+ */
+ private $callback;
+
+ public function __construct(callable $callback)
+ {
+ $this->callback = $callback;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function matches(RequestInterface $request)
+ {
+ return (bool) call_user_func($this->callback, $request);
+ }
+}
diff --git a/vendor/php-http/message/src/RequestMatcher/RegexRequestMatcher.php b/vendor/php-http/message/src/RequestMatcher/RegexRequestMatcher.php
new file mode 100644
index 000000000..91f3729e6
--- /dev/null
+++ b/vendor/php-http/message/src/RequestMatcher/RegexRequestMatcher.php
@@ -0,0 +1,41 @@
+
+ *
+ * @deprecated since version 1.2 and will be removed in 2.0. Use {@link RequestMatcher} instead.
+ */
+final class RegexRequestMatcher implements RequestMatcher
+{
+ /**
+ * Matching regex.
+ *
+ * @var string
+ */
+ private $regex;
+
+ /**
+ * @param string $regex
+ */
+ public function __construct($regex)
+ {
+ $this->regex = $regex;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function matches(RequestInterface $request)
+ {
+ return (bool) preg_match($this->regex, (string) $request->getUri());
+ }
+}
diff --git a/vendor/php-http/message/src/RequestMatcher/RequestMatcher.php b/vendor/php-http/message/src/RequestMatcher/RequestMatcher.php
new file mode 100644
index 000000000..e2aa02123
--- /dev/null
+++ b/vendor/php-http/message/src/RequestMatcher/RequestMatcher.php
@@ -0,0 +1,78 @@
+
+ * @author Joel Wurtz
+ */
+final class RequestMatcher implements RequestMatcherInterface
+{
+ /**
+ * @var string
+ */
+ private $path;
+
+ /**
+ * @var string
+ */
+ private $host;
+
+ /**
+ * @var array
+ */
+ private $methods = [];
+
+ /**
+ * @var string[]
+ */
+ private $schemes = [];
+
+ /**
+ * The regular expressions used for path or host must be specified without delimiter.
+ * You do not need to escape the forward slash / to match it.
+ *
+ * @param string|null $path Regular expression for the path
+ * @param string|null $host Regular expression for the hostname
+ * @param string|string[]|null $methods Method or list of methods to match
+ * @param string|string[]|null $schemes Scheme or list of schemes to match (e.g. http or https)
+ */
+ public function __construct($path = null, $host = null, $methods = [], $schemes = [])
+ {
+ $this->path = $path;
+ $this->host = $host;
+ $this->methods = array_map('strtoupper', (array) $methods);
+ $this->schemes = array_map('strtolower', (array) $schemes);
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function matches(RequestInterface $request)
+ {
+ if ($this->schemes && !in_array($request->getUri()->getScheme(), $this->schemes)) {
+ return false;
+ }
+
+ if ($this->methods && !in_array($request->getMethod(), $this->methods)) {
+ return false;
+ }
+
+ if (null !== $this->path && !preg_match('{'.$this->path.'}', rawurldecode($request->getUri()->getPath()))) {
+ return false;
+ }
+
+ if (null !== $this->host && !preg_match('{'.$this->host.'}i', $request->getUri()->getHost())) {
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/vendor/php-http/message/src/Stream/BufferedStream.php b/vendor/php-http/message/src/Stream/BufferedStream.php
new file mode 100644
index 000000000..3d38731d6
--- /dev/null
+++ b/vendor/php-http/message/src/Stream/BufferedStream.php
@@ -0,0 +1,273 @@
+stream = $stream;
+ $this->size = $stream->getSize();
+
+ if ($useFileBuffer) {
+ $this->resource = fopen('php://temp/maxmemory:'.$memoryBuffer, 'rw+');
+ } else {
+ $this->resource = fopen('php://memory', 'rw+');
+ }
+
+ if (false === $this->resource) {
+ throw new \RuntimeException('Cannot create a resource over temp or memory implementation');
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function __toString()
+ {
+ try {
+ $this->rewind();
+
+ return $this->getContents();
+ } catch (\Throwable $throwable) {
+ return '';
+ } catch (\Exception $exception) { // Layer to be BC with PHP 5, remove this when we only support PHP 7+
+ return '';
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function close()
+ {
+ if (null === $this->resource) {
+ throw new \RuntimeException('Cannot close on a detached stream');
+ }
+
+ $this->stream->close();
+ fclose($this->resource);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function detach()
+ {
+ if (null === $this->resource) {
+ return;
+ }
+
+ // Force reading the remaining data of the stream
+ $this->getContents();
+
+ $resource = $this->resource;
+ $this->stream->close();
+ $this->stream = null;
+ $this->resource = null;
+
+ return $resource;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getSize()
+ {
+ if (null === $this->resource) {
+ return;
+ }
+
+ if (null === $this->size && $this->stream->eof()) {
+ return $this->written;
+ }
+
+ return $this->size;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function tell()
+ {
+ if (null === $this->resource) {
+ throw new \RuntimeException('Cannot tell on a detached stream');
+ }
+
+ return ftell($this->resource);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function eof()
+ {
+ if (null === $this->resource) {
+ throw new \RuntimeException('Cannot call eof on a detached stream');
+ }
+
+ // We are at the end only when both our resource and underlying stream are at eof
+ return $this->stream->eof() && (ftell($this->resource) === $this->written);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isSeekable()
+ {
+ return null !== $this->resource;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function seek($offset, $whence = SEEK_SET)
+ {
+ if (null === $this->resource) {
+ throw new \RuntimeException('Cannot seek on a detached stream');
+ }
+
+ fseek($this->resource, $offset, $whence);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function rewind()
+ {
+ if (null === $this->resource) {
+ throw new \RuntimeException('Cannot rewind on a detached stream');
+ }
+
+ rewind($this->resource);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isWritable()
+ {
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function write($string)
+ {
+ throw new \RuntimeException('Cannot write on this stream');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isReadable()
+ {
+ return null !== $this->resource;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function read($length)
+ {
+ if (null === $this->resource) {
+ throw new \RuntimeException('Cannot read on a detached stream');
+ }
+ if ($length < 0) {
+ throw new \InvalidArgumentException('Can not read a negative amount of bytes');
+ }
+
+ $read = '';
+
+ // First read from the resource
+ if (ftell($this->resource) !== $this->written) {
+ $read = fread($this->resource, $length);
+ }
+
+ $bytesRead = strlen($read);
+
+ if ($bytesRead < $length) {
+ $streamRead = $this->stream->read($length - $bytesRead);
+
+ // Write on the underlying stream what we read
+ $this->written += fwrite($this->resource, $streamRead);
+ $read .= $streamRead;
+ }
+
+ return $read;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getContents()
+ {
+ if (null === $this->resource) {
+ throw new \RuntimeException('Cannot read on a detached stream');
+ }
+
+ $read = '';
+
+ while (!$this->eof()) {
+ $read .= $this->read(8192);
+ }
+
+ return $read;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMetadata($key = null)
+ {
+ if (null === $this->resource) {
+ if (null === $key) {
+ return [];
+ }
+
+ return;
+ }
+
+ $metadata = stream_get_meta_data($this->resource);
+
+ if (null === $key) {
+ return $metadata;
+ }
+
+ if (!array_key_exists($key, $metadata)) {
+ return;
+ }
+
+ return $metadata[$key];
+ }
+}
diff --git a/vendor/php-http/message/src/StreamFactory/DiactorosStreamFactory.php b/vendor/php-http/message/src/StreamFactory/DiactorosStreamFactory.php
new file mode 100644
index 000000000..8ae2b288e
--- /dev/null
+++ b/vendor/php-http/message/src/StreamFactory/DiactorosStreamFactory.php
@@ -0,0 +1,48 @@
+
+ *
+ * @deprecated This will be removed in php-http/message2.0. Consider using the official Diactoros PSR-17 factory
+ */
+final class DiactorosStreamFactory implements StreamFactory
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function createStream($body = null)
+ {
+ if ($body instanceof StreamInterface) {
+ return $body;
+ }
+
+ if (is_resource($body)) {
+ if (class_exists(LaminasStream::class)) {
+ return new LaminasStream($body);
+ }
+
+ return new ZendStream($body);
+ }
+
+ if (class_exists(LaminasStream::class)) {
+ $stream = new LaminasStream('php://memory', 'rw');
+ } else {
+ $stream = new ZendStream('php://memory', 'rw');
+ }
+
+ if (null !== $body && '' !== $body) {
+ $stream->write((string) $body);
+ }
+
+ return $stream;
+ }
+}
diff --git a/vendor/php-http/message/src/StreamFactory/GuzzleStreamFactory.php b/vendor/php-http/message/src/StreamFactory/GuzzleStreamFactory.php
new file mode 100644
index 000000000..14d83e943
--- /dev/null
+++ b/vendor/php-http/message/src/StreamFactory/GuzzleStreamFactory.php
@@ -0,0 +1,28 @@
+
+ *
+ * @deprecated This will be removed in php-http/message2.0. Consider using the official Guzzle PSR-17 factory
+ */
+final class GuzzleStreamFactory implements StreamFactory
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function createStream($body = null)
+ {
+ if (class_exists(Utils::class)) {
+ return Utils::streamFor($body);
+ }
+
+ return \GuzzleHttp\Psr7\stream_for($body);
+ }
+}
diff --git a/vendor/php-http/message/src/StreamFactory/SlimStreamFactory.php b/vendor/php-http/message/src/StreamFactory/SlimStreamFactory.php
new file mode 100644
index 000000000..9274aaee8
--- /dev/null
+++ b/vendor/php-http/message/src/StreamFactory/SlimStreamFactory.php
@@ -0,0 +1,39 @@
+
+ *
+ * @deprecated This will be removed in php-http/message2.0. Consider using the official Slim PSR-17 factory
+ */
+final class SlimStreamFactory implements StreamFactory
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function createStream($body = null)
+ {
+ if ($body instanceof StreamInterface) {
+ return $body;
+ }
+
+ if (is_resource($body)) {
+ return new Stream($body);
+ }
+
+ $resource = fopen('php://memory', 'r+');
+ $stream = new Stream($resource);
+ if (null !== $body && '' !== $body) {
+ $stream->write((string) $body);
+ }
+
+ return $stream;
+ }
+}
diff --git a/vendor/php-http/message/src/UriFactory/DiactorosUriFactory.php b/vendor/php-http/message/src/UriFactory/DiactorosUriFactory.php
new file mode 100644
index 000000000..be883defa
--- /dev/null
+++ b/vendor/php-http/message/src/UriFactory/DiactorosUriFactory.php
@@ -0,0 +1,36 @@
+
+ *
+ * @deprecated This will be removed in php-http/message2.0. Consider using the official Diactoros PSR-17 factory
+ */
+final class DiactorosUriFactory implements UriFactory
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function createUri($uri)
+ {
+ if ($uri instanceof UriInterface) {
+ return $uri;
+ } elseif (is_string($uri)) {
+ if (class_exists(LaminasUri::class)) {
+ return new LaminasUri($uri);
+ }
+
+ return new ZendUri($uri);
+ }
+
+ throw new \InvalidArgumentException('URI must be a string or UriInterface');
+ }
+}
diff --git a/vendor/php-http/message/src/UriFactory/GuzzleUriFactory.php b/vendor/php-http/message/src/UriFactory/GuzzleUriFactory.php
new file mode 100644
index 000000000..e09ac61e9
--- /dev/null
+++ b/vendor/php-http/message/src/UriFactory/GuzzleUriFactory.php
@@ -0,0 +1,29 @@
+
+ *
+ * @deprecated This will be removed in php-http/message2.0. Consider using the official Guzzle PSR-17 factory
+ */
+final class GuzzleUriFactory implements UriFactory
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function createUri($uri)
+ {
+ if (class_exists(Utils::class)) {
+ return Utils::uriFor($uri);
+ }
+
+ return uri_for($uri);
+ }
+}
diff --git a/vendor/php-http/message/src/UriFactory/SlimUriFactory.php b/vendor/php-http/message/src/UriFactory/SlimUriFactory.php
new file mode 100644
index 000000000..e5bef0367
--- /dev/null
+++ b/vendor/php-http/message/src/UriFactory/SlimUriFactory.php
@@ -0,0 +1,33 @@
+
+ *
+ * @deprecated This will be removed in php-http/message2.0. Consider using the official Slim PSR-17 factory
+ */
+final class SlimUriFactory implements UriFactory
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function createUri($uri)
+ {
+ if ($uri instanceof UriInterface) {
+ return $uri;
+ }
+
+ if (is_string($uri)) {
+ return Uri::createFromString($uri);
+ }
+
+ throw new \InvalidArgumentException('URI must be a string or UriInterface');
+ }
+}
diff --git a/vendor/php-http/message/src/filters.php b/vendor/php-http/message/src/filters.php
new file mode 100644
index 000000000..15ed73de7
--- /dev/null
+++ b/vendor/php-http/message/src/filters.php
@@ -0,0 +1,6 @@
+
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/php-http/promise/README.md b/vendor/php-http/promise/README.md
new file mode 100644
index 000000000..ee95e0933
--- /dev/null
+++ b/vendor/php-http/promise/README.md
@@ -0,0 +1,48 @@
+# Promise
+
+[](https://github.com/php-http/promise/releases)
+[](LICENSE)
+[](https://travis-ci.org/php-http/promise)
+[](https://scrutinizer-ci.com/g/php-http/promise)
+[](https://scrutinizer-ci.com/g/php-http/promise)
+[](https://packagist.org/packages/php-http/promise)
+
+**Promise used for asynchronous HTTP requests.**
+
+**Note:** This will eventually be removed/deprecated and replaced with the upcoming Promise PSR.
+
+
+## Install
+
+Via Composer
+
+``` bash
+$ composer require php-http/promise
+```
+
+
+## Documentation
+
+Please see the [official documentation](http://docs.php-http.org/en/latest/components/promise.html).
+
+
+## Testing
+
+``` bash
+$ composer test
+```
+
+
+## Contributing
+
+Please see our [contributing guide](http://docs.php-http.org/en/latest/development/contributing.html).
+
+
+## Security
+
+If you discover any security related issues, please contact us at [security@php-http.org](mailto:security@php-http.org).
+
+
+## License
+
+The MIT License (MIT). Please see [License File](LICENSE) for more information.
diff --git a/vendor/php-http/promise/composer.json b/vendor/php-http/promise/composer.json
new file mode 100644
index 000000000..812167bc8
--- /dev/null
+++ b/vendor/php-http/promise/composer.json
@@ -0,0 +1,38 @@
+{
+ "name": "php-http/promise",
+ "description": "Promise used for asynchronous HTTP requests",
+ "license": "MIT",
+ "keywords": ["promise"],
+ "homepage": "http://httplug.io",
+ "authors": [
+ {
+ "name": "Joel Wurtz",
+ "email": "joel.wurtz@gmail.com"
+ },
+ {
+ "name": "Márk Sági-Kazár",
+ "email": "mark.sagikazar@gmail.com"
+ }
+ ],
+ "require": {
+ "php" : "^7.1 || ^8.0"
+ },
+ "require-dev": {
+ "friends-of-phpspec/phpspec-code-coverage" : "^4.3.2",
+ "phpspec/phpspec": "^5.1.2 || ^6.2"
+ },
+ "autoload": {
+ "psr-4": {
+ "Http\\Promise\\": "src/"
+ }
+ },
+ "scripts": {
+ "test": "vendor/bin/phpspec run",
+ "test-ci": "vendor/bin/phpspec run -c phpspec.yml.ci"
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1-dev"
+ }
+ }
+}
diff --git a/vendor/php-http/promise/src/FulfilledPromise.php b/vendor/php-http/promise/src/FulfilledPromise.php
new file mode 100644
index 000000000..f60f686a2
--- /dev/null
+++ b/vendor/php-http/promise/src/FulfilledPromise.php
@@ -0,0 +1,58 @@
+
+ */
+final class FulfilledPromise implements Promise
+{
+ /**
+ * @var mixed
+ */
+ private $result;
+
+ /**
+ * @param $result
+ */
+ public function __construct($result)
+ {
+ $this->result = $result;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function then(callable $onFulfilled = null, callable $onRejected = null)
+ {
+ if (null === $onFulfilled) {
+ return $this;
+ }
+
+ try {
+ return new self($onFulfilled($this->result));
+ } catch (\Exception $e) {
+ return new RejectedPromise($e);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getState()
+ {
+ return Promise::FULFILLED;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function wait($unwrap = true)
+ {
+ if ($unwrap) {
+ return $this->result;
+ }
+ }
+}
diff --git a/vendor/php-http/promise/src/Promise.php b/vendor/php-http/promise/src/Promise.php
new file mode 100644
index 000000000..3258ed0d3
--- /dev/null
+++ b/vendor/php-http/promise/src/Promise.php
@@ -0,0 +1,69 @@
+
+ * @author Márk Sági-Kazár
+ */
+interface Promise
+{
+ /**
+ * Promise has not been fulfilled or rejected.
+ */
+ const PENDING = 'pending';
+
+ /**
+ * Promise has been fulfilled.
+ */
+ const FULFILLED = 'fulfilled';
+
+ /**
+ * Promise has been rejected.
+ */
+ const REJECTED = 'rejected';
+
+ /**
+ * Adds behavior for when the promise is resolved or rejected (response will be available, or error happens).
+ *
+ * If you do not care about one of the cases, you can set the corresponding callable to null
+ * The callback will be called when the value arrived and never more than once.
+ *
+ * @param callable|null $onFulfilled called when a response will be available
+ * @param callable|null $onRejected called when an exception occurs
+ *
+ * @return Promise a new resolved promise with value of the executed callback (onFulfilled / onRejected)
+ */
+ public function then(callable $onFulfilled = null, callable $onRejected = null);
+
+ /**
+ * Returns the state of the promise, one of PENDING, FULFILLED or REJECTED.
+ *
+ * @return string
+ */
+ public function getState();
+
+ /**
+ * Wait for the promise to be fulfilled or rejected.
+ *
+ * When this method returns, the request has been resolved and if callables have been
+ * specified, the appropriate one has terminated.
+ *
+ * When $unwrap is true (the default), the response is returned, or the exception thrown
+ * on failure. Otherwise, nothing is returned or thrown.
+ *
+ * @param bool $unwrap Whether to return resolved value / throw reason or not
+ *
+ * @return mixed Resolved value, null if $unwrap is set to false
+ *
+ * @throws \Exception the rejection reason if $unwrap is set to true and the request failed
+ */
+ public function wait($unwrap = true);
+}
diff --git a/vendor/php-http/promise/src/RejectedPromise.php b/vendor/php-http/promise/src/RejectedPromise.php
new file mode 100644
index 000000000..e396a40f7
--- /dev/null
+++ b/vendor/php-http/promise/src/RejectedPromise.php
@@ -0,0 +1,58 @@
+
+ */
+final class RejectedPromise implements Promise
+{
+ /**
+ * @var \Exception
+ */
+ private $exception;
+
+ /**
+ * @param \Exception $exception
+ */
+ public function __construct(\Exception $exception)
+ {
+ $this->exception = $exception;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function then(callable $onFulfilled = null, callable $onRejected = null)
+ {
+ if (null === $onRejected) {
+ return $this;
+ }
+
+ try {
+ return new FulfilledPromise($onRejected($this->exception));
+ } catch (\Exception $e) {
+ return new self($e);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getState()
+ {
+ return Promise::REJECTED;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function wait($unwrap = true)
+ {
+ if ($unwrap) {
+ throw $this->exception;
+ }
+ }
+}
diff --git a/vendor/phpoption/phpoption/Makefile b/vendor/phpoption/phpoption/Makefile
deleted file mode 100644
index 84d715d98..000000000
--- a/vendor/phpoption/phpoption/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-install:
- @docker run -it -w /data -v ${PWD}:/data:delegated -v ~/.composer:/root/.composer:delegated --entrypoint composer --rm registry.gitlab.com/grahamcampbell/php:7.4-base update
- @docker run -it -w /data -v ${PWD}:/data:delegated -v ~/.composer:/root/.composer:delegated --entrypoint composer --rm registry.gitlab.com/grahamcampbell/php:7.4-base bin all update
-
-phpunit:
- @rm -f bootstrap/cache/*.php && docker run -it -w /data -v ${PWD}:/data:delegated --entrypoint vendor/bin/phpunit --rm registry.gitlab.com/grahamcampbell/php:7.4-cli
-
-phpstan-analyze-src:
- @docker run -it -w /data -v ${PWD}:/data:delegated --entrypoint vendor/bin/phpstan --rm registry.gitlab.com/grahamcampbell/php:7.4-cli analyze src -c phpstan.src.neon.dist
-
-phpstan-analyze-tests:
- @docker run -it -w /data -v ${PWD}:/data:delegated --entrypoint vendor/bin/phpstan --rm registry.gitlab.com/grahamcampbell/php:7.4-cli analyze tests -c phpstan.tests.neon.dist
-
-phpstan-baseline:
- @docker run -it -w /data -v ${PWD}:/data:delegated --entrypoint vendor/bin/phpstan --rm registry.gitlab.com/grahamcampbell/php:7.4-cli analyze src -c phpstan.src.neon.dist --generate-baseline
-
-psalm-analyze:
- @docker run -it -w /data -v ${PWD}:/data:delegated --entrypoint vendor/bin/psalm.phar --rm registry.gitlab.com/grahamcampbell/php:7.4-cli
-
-psalm-show-info:
- @docker run -it -w /data -v ${PWD}:/data:delegated --entrypoint vendor/bin/psalm .phar--rm registry.gitlab.com/grahamcampbell/php:7.4-cli --show-info=true
-
-test: phpunit phpstan-analyze-src phpstan-analyze-tests psalm-analyze
-
-clean:
- @rm -rf .phpunit.result.cache composer.lock vendor vendor-bin/*/composer.lock vendor-bin/*/vendor
diff --git a/vendor/phpoption/phpoption/composer.json b/vendor/phpoption/phpoption/composer.json
index 3cff6ef82..0106c9771 100644
--- a/vendor/phpoption/phpoption/composer.json
+++ b/vendor/phpoption/phpoption/composer.json
@@ -16,11 +16,11 @@
}
],
"require": {
- "php": "^7.0 || ^8.0"
+ "php": "^7.2.5 || ^8.0"
},
"require-dev": {
- "bamarni/composer-bin-plugin": "^1.4.1",
- "phpunit/phpunit": "^6.5.14 || ^7.5.20 || ^8.5.19 || ^9.5.8"
+ "bamarni/composer-bin-plugin": "^1.8",
+ "phpunit/phpunit": "^8.5.28 || ^9.5.21"
},
"autoload": {
"psr-4": {
@@ -33,11 +33,18 @@
}
},
"config": {
+ "allow-plugins": {
+ "bamarni/composer-bin-plugin": true
+ },
"preferred-install": "dist"
},
"extra": {
+ "bamarni-bin": {
+ "bin-links": true,
+ "forward-command": true
+ },
"branch-alias": {
- "dev-master": "1.8-dev"
+ "dev-master": "1.9-dev"
}
},
"minimum-stability": "dev",
diff --git a/vendor/phpunit/php-token-stream/.gitattributes b/vendor/phpunit/php-token-stream/.gitattributes
index 461090b7e..a88b8c68e 100644
--- a/vendor/phpunit/php-token-stream/.gitattributes
+++ b/vendor/phpunit/php-token-stream/.gitattributes
@@ -1 +1,12 @@
+/.github export-ignore
+/.phive export-ignore
+/.php_cs.dist export-ignore
+/.psalm export-ignore
+/bin export-ignore
+/build.xml export-ignore
+/phpunit.xml export-ignore
+/tests export-ignore
+/tools export-ignore
+/tools/* binary
+
*.php diff=php
diff --git a/vendor/phpunit/php-token-stream/.github/FUNDING.yml b/vendor/phpunit/php-token-stream/.github/FUNDING.yml
deleted file mode 100644
index b19ea81a0..000000000
--- a/vendor/phpunit/php-token-stream/.github/FUNDING.yml
+++ /dev/null
@@ -1 +0,0 @@
-patreon: s_bergmann
diff --git a/vendor/phpunit/php-token-stream/.gitignore b/vendor/phpunit/php-token-stream/.gitignore
index 77aae3df6..93a0be47b 100644
--- a/vendor/phpunit/php-token-stream/.gitignore
+++ b/vendor/phpunit/php-token-stream/.gitignore
@@ -1,3 +1,7 @@
/.idea
+/.php_cs
+/.php_cs.cache
+/.phpunit.result.cache
+/.psalm/cache
/composer.lock
/vendor
diff --git a/vendor/phpunit/php-token-stream/.travis.yml b/vendor/phpunit/php-token-stream/.travis.yml
deleted file mode 100644
index 4e8056d8e..000000000
--- a/vendor/phpunit/php-token-stream/.travis.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-language: php
-
-php:
- - 7.1
- - 7.2
- - 7.3
- - 7.4snapshot
-
-sudo: false
-
-before_install:
- - composer self-update
- - composer clear-cache
-
-install:
- - travis_retry composer update --no-interaction --no-ansi --no-progress --no-suggest
-
-script:
- - ./vendor/bin/phpunit --coverage-clover=coverage.xml
-
-after_success:
- - bash <(curl -s https://codecov.io/bash)
-
-notifications:
- email: false
-
diff --git a/vendor/phpunit/php-token-stream/ChangeLog.md b/vendor/phpunit/php-token-stream/ChangeLog.md
index bf59ea4df..4a93f524b 100644
--- a/vendor/phpunit/php-token-stream/ChangeLog.md
+++ b/vendor/phpunit/php-token-stream/ChangeLog.md
@@ -2,23 +2,41 @@
All notable changes to `sebastianbergmann/php-token-stream` are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
-## [3.1.3] - 2021-07-26
+## [4.0.4] - 2020-08-04
-### Changed
+### Added
-* The declarations of methods in `PHP_Token_Stream` that implement the `ArrayAccess`, `Countable`, and `SeekableIterator` interfaces are now compatible with PHP 8.1
+* Support for `NAME_FULLY_QUALIFIED`, `NAME_QUALIFIED`, and `NAME_RELATIVE` tokens
-## [3.1.2] - 2020-11-30
+## [4.0.3] - 2020-06-27
-### Changed
+### Added
-* Changed PHP version constraint in `composer.json` from `^7.1` to `>=7.1` to allow installation of this version of this library on PHP 8. However, this version of this library does not work on PHP 8. PHPUnit 8.5, which uses this version of this library (through phpunit/php-code-coverage), does not call into this library and instead shows a message that code coverage functionality is not available for PHPUnit 8.5 on PHP 8.
+* This component is now supported on PHP 8
+
+## [4.0.2] - 2020-06-16
+
+### Fixed
+
+* Fixed backward compatibility breaks introduced in version 4.0.1
+
+## [4.0.1] - 2020-05-06
+
+### Fixed
+
+* [#93](https://github.com/sebastianbergmann/php-token-stream/issues/93): Class with method that uses anonymous class is not processed correctly
+
+## [4.0.0] - 2020-02-07
+
+### Removed
+
+* This component is no longer supported PHP 7.1 and PHP 7.2
## [3.1.1] - 2019-09-17
### Fixed
-* Fixed [#84](https://github.com/sebastianbergmann/php-token-stream/issues/84): Methods named `class` are not handled correctly
+* [#84](https://github.com/sebastianbergmann/php-token-stream/issues/84): Methods named `class` are not handled correctly
## [3.1.0] - 2019-07-25
@@ -30,37 +48,40 @@ All notable changes to `sebastianbergmann/php-token-stream` are documented in th
### Changed
-* Implemented [#82](https://github.com/sebastianbergmann/php-token-stream/issues/82): Make sure this component works when its classes are prefixed using php-scoper
+* [#82](https://github.com/sebastianbergmann/php-token-stream/issues/82): Make sure this component works when its classes are prefixed using php-scoper
## [3.0.1] - 2018-10-30
### Fixed
-* Fixed [#78](https://github.com/sebastianbergmann/php-token-stream/pull/78): `getEndTokenId()` does not handle string-dollar (`"${var}"`) interpolation
+* [#78](https://github.com/sebastianbergmann/php-token-stream/pull/78): `getEndTokenId()` does not handle string-dollar (`"${var}"`) interpolation
## [3.0.0] - 2018-02-01
### Removed
-* Implemented [#71](https://github.com/sebastianbergmann/php-token-stream/issues/71): Remove code specific to Hack language constructs
-* Implemented [#72](https://github.com/sebastianbergmann/php-token-stream/issues/72): Drop support for PHP 7.0
+* [#71](https://github.com/sebastianbergmann/php-token-stream/issues/71): Remove code specific to Hack language constructs
+* [#72](https://github.com/sebastianbergmann/php-token-stream/issues/72): Drop support for PHP 7.0
## [2.0.2] - 2017-11-27
### Fixed
-* Fixed [#69](https://github.com/sebastianbergmann/php-token-stream/issues/69): `PHP_Token_USE_FUNCTION` does not serialize correctly
+* [#69](https://github.com/sebastianbergmann/php-token-stream/issues/69): `PHP_Token_USE_FUNCTION` does not serialize correctly
## [2.0.1] - 2017-08-20
### Fixed
-* Fixed [#68](https://github.com/sebastianbergmann/php-token-stream/issues/68): Method with name `empty` wrongly recognized as anonymous function
+* [#68](https://github.com/sebastianbergmann/php-token-stream/issues/68): Method with name `empty` wrongly recognized as anonymous function
## [2.0.0] - 2017-08-03
-[3.1.3]: https://github.com/sebastianbergmann/php-token-stream/compare/3.1.2...3.1.3
-[3.1.2]: https://github.com/sebastianbergmann/php-token-stream/compare/3.1.1...3.1.2
+[4.0.4]: https://github.com/sebastianbergmann/php-token-stream/compare/4.0.3...4.0.4
+[4.0.3]: https://github.com/sebastianbergmann/php-token-stream/compare/4.0.2...4.0.3
+[4.0.2]: https://github.com/sebastianbergmann/php-token-stream/compare/4.0.1...4.0.2
+[4.0.1]: https://github.com/sebastianbergmann/php-token-stream/compare/4.0.0...4.0.1
+[4.0.0]: https://github.com/sebastianbergmann/php-token-stream/compare/3.1.1...4.0.0
[3.1.1]: https://github.com/sebastianbergmann/php-token-stream/compare/3.1.0...3.1.1
[3.1.0]: https://github.com/sebastianbergmann/php-token-stream/compare/3.0.2...3.1.0
[3.0.2]: https://github.com/sebastianbergmann/php-token-stream/compare/3.0.1...3.0.2
diff --git a/vendor/phpunit/php-token-stream/LICENSE b/vendor/phpunit/php-token-stream/LICENSE
index 2cad5be40..a6d0c8c4f 100644
--- a/vendor/phpunit/php-token-stream/LICENSE
+++ b/vendor/phpunit/php-token-stream/LICENSE
@@ -1,6 +1,6 @@
php-token-stream
-Copyright (c) 2009-2019, Sebastian Bergmann .
+Copyright (c) 2009-2020, Sebastian Bergmann .
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/vendor/phpunit/php-token-stream/README.md b/vendor/phpunit/php-token-stream/README.md
index 149b7e2df..162de8d19 100644
--- a/vendor/phpunit/php-token-stream/README.md
+++ b/vendor/phpunit/php-token-stream/README.md
@@ -1,14 +1,18 @@
-[](https://travis-ci.org/sebastianbergmann/php-token-stream)
+# phpunit/php-token-stream
-# php-token-stream
+[](https://github.com/sebastianbergmann/php-token-stream/actions)
+[](https://shepherd.dev/github/sebastianbergmann/php-token-stream)
## Installation
You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
- composer require phpunit/php-token-stream
+```
+composer require phpunit/php-token-stream
+```
If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:
- composer require --dev phpunit/php-token-stream
-
+```
+composer require --dev phpunit/php-token-stream
+```
diff --git a/vendor/phpunit/php-token-stream/build.xml b/vendor/phpunit/php-token-stream/build.xml
deleted file mode 100644
index 0da8056e5..000000000
--- a/vendor/phpunit/php-token-stream/build.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/vendor/phpunit/php-token-stream/composer.json b/vendor/phpunit/php-token-stream/composer.json
index afaabacd9..e0d0b4de7 100644
--- a/vendor/phpunit/php-token-stream/composer.json
+++ b/vendor/phpunit/php-token-stream/composer.json
@@ -16,13 +16,16 @@
},
"prefer-stable": true,
"require": {
- "php": ">=7.1",
+ "php": "^7.3 || ^8.0",
"ext-tokenizer": "*"
},
"require-dev": {
- "phpunit/phpunit": "^7.0"
+ "phpunit/phpunit": "^9.0"
},
"config": {
+ "platform": {
+ "php": "7.3.0"
+ },
"optimize-autoloader": true,
"sort-packages": true
},
@@ -33,7 +36,7 @@
},
"extra": {
"branch-alias": {
- "dev-master": "3.1-dev"
+ "dev-master": "4.0-dev"
}
}
}
diff --git a/vendor/phpunit/php-token-stream/phpunit.xml b/vendor/phpunit/php-token-stream/phpunit.xml
deleted file mode 100644
index 8f159fbd1..000000000
--- a/vendor/phpunit/php-token-stream/phpunit.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
- tests
-
-
-
-
-
- src
-
-
-
diff --git a/vendor/phpunit/php-token-stream/src/Abstract.php b/vendor/phpunit/php-token-stream/src/Abstract.php
new file mode 100644
index 000000000..7bbb555d3
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Abstract.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_ABSTRACT extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Ampersand.php b/vendor/phpunit/php-token-stream/src/Ampersand.php
new file mode 100644
index 000000000..3996f3446
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Ampersand.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_AMPERSAND extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/AndEqual.php b/vendor/phpunit/php-token-stream/src/AndEqual.php
new file mode 100644
index 000000000..9984442a6
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/AndEqual.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_AND_EQUAL extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Array.php b/vendor/phpunit/php-token-stream/src/Array.php
new file mode 100644
index 000000000..72041e944
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Array.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_ARRAY extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/ArrayCast.php b/vendor/phpunit/php-token-stream/src/ArrayCast.php
new file mode 100644
index 000000000..9d113db52
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/ArrayCast.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_ARRAY_CAST extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/As.php b/vendor/phpunit/php-token-stream/src/As.php
new file mode 100644
index 000000000..286578e46
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/As.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_AS extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/At.php b/vendor/phpunit/php-token-stream/src/At.php
new file mode 100644
index 000000000..d8d246857
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/At.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_AT extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Backtick.php b/vendor/phpunit/php-token-stream/src/Backtick.php
new file mode 100644
index 000000000..3d8b55b7f
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Backtick.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_BACKTICK extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/BadCharacter.php b/vendor/phpunit/php-token-stream/src/BadCharacter.php
new file mode 100644
index 000000000..dfc7a40ff
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/BadCharacter.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_BAD_CHARACTER extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/BoolCast.php b/vendor/phpunit/php-token-stream/src/BoolCast.php
new file mode 100644
index 000000000..201cfeab6
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/BoolCast.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_BOOL_CAST extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/BooleanAnd.php b/vendor/phpunit/php-token-stream/src/BooleanAnd.php
new file mode 100644
index 000000000..03f983311
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/BooleanAnd.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_BOOLEAN_AND extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/BooleanOr.php b/vendor/phpunit/php-token-stream/src/BooleanOr.php
new file mode 100644
index 000000000..0f339245b
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/BooleanOr.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_BOOLEAN_OR extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php b/vendor/phpunit/php-token-stream/src/CachingFactory.php
similarity index 80%
rename from vendor/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php
rename to vendor/phpunit/php-token-stream/src/CachingFactory.php
index 9d693938a..c557a84f3 100644
--- a/vendor/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php
+++ b/vendor/phpunit/php-token-stream/src/CachingFactory.php
@@ -1,16 +1,12 @@
-
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
-
-/**
- * A caching factory for token stream objects.
- */
class PHP_Token_Stream_CachingFactory
{
/**
@@ -35,9 +31,9 @@ class PHP_Token_Stream_CachingFactory
/**
* @param string $filename
*/
- public static function clear($filename = null)
+ public static function clear($filename = null)/*: void*/
{
- if (is_string($filename)) {
+ if (\is_string($filename)) {
unset(self::$cache[$filename]);
} else {
self::$cache = [];
diff --git a/vendor/phpunit/php-token-stream/src/Callable.php b/vendor/phpunit/php-token-stream/src/Callable.php
new file mode 100644
index 000000000..4f5751259
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Callable.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_CALLABLE extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Caret.php b/vendor/phpunit/php-token-stream/src/Caret.php
new file mode 100644
index 000000000..af453d897
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Caret.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_CARET extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Case.php b/vendor/phpunit/php-token-stream/src/Case.php
new file mode 100644
index 000000000..ab9b906db
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Case.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_CASE extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Catch.php b/vendor/phpunit/php-token-stream/src/Catch.php
new file mode 100644
index 000000000..8c244acae
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Catch.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_CATCH extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Character.php b/vendor/phpunit/php-token-stream/src/Character.php
new file mode 100644
index 000000000..eea0db099
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Character.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_CHARACTER extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Class.php b/vendor/phpunit/php-token-stream/src/Class.php
new file mode 100644
index 000000000..09167f21c
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Class.php
@@ -0,0 +1,62 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_CLASS extends PHP_Token_INTERFACE
+{
+ /**
+ * @var bool
+ */
+ private $anonymous = false;
+
+ /**
+ * @var string
+ */
+ private $name;
+
+ /**
+ * @return string
+ */
+ public function getName()
+ {
+ if ($this->name !== null) {
+ return $this->name;
+ }
+
+ $next = $this->tokenStream[$this->id + 1];
+
+ if ($next instanceof PHP_Token_WHITESPACE) {
+ $next = $this->tokenStream[$this->id + 2];
+ }
+
+ if ($next instanceof PHP_Token_STRING) {
+ $this->name =(string) $next;
+
+ return $this->name;
+ }
+
+ if ($next instanceof PHP_Token_OPEN_CURLY ||
+ $next instanceof PHP_Token_EXTENDS ||
+ $next instanceof PHP_Token_IMPLEMENTS) {
+ $this->name = \sprintf(
+ 'AnonymousClass:%s#%s',
+ $this->getLine(),
+ $this->getId()
+ );
+
+ $this->anonymous = true;
+
+ return $this->name;
+ }
+ }
+
+ public function isAnonymous()
+ {
+ return $this->anonymous;
+ }
+}
diff --git a/vendor/phpunit/php-token-stream/src/ClassC.php b/vendor/phpunit/php-token-stream/src/ClassC.php
new file mode 100644
index 000000000..2350c99bd
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/ClassC.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_CLASS_C extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/ClassNameConstant.php b/vendor/phpunit/php-token-stream/src/ClassNameConstant.php
new file mode 100644
index 000000000..1b557e3c7
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/ClassNameConstant.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_CLASS_NAME_CONSTANT extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Clone.php b/vendor/phpunit/php-token-stream/src/Clone.php
new file mode 100644
index 000000000..24e661047
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Clone.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_CLONE extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/CloseBracket.php b/vendor/phpunit/php-token-stream/src/CloseBracket.php
new file mode 100644
index 000000000..b86b74575
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/CloseBracket.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_CLOSE_BRACKET extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/CloseCurly.php b/vendor/phpunit/php-token-stream/src/CloseCurly.php
new file mode 100644
index 000000000..aa86cdc4d
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/CloseCurly.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_CLOSE_CURLY extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/CloseSquare.php b/vendor/phpunit/php-token-stream/src/CloseSquare.php
new file mode 100644
index 000000000..fc819d015
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/CloseSquare.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_CLOSE_SQUARE extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/CloseTag.php b/vendor/phpunit/php-token-stream/src/CloseTag.php
new file mode 100644
index 000000000..419510cf8
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/CloseTag.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_CLOSE_TAG extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Coalesce.php b/vendor/phpunit/php-token-stream/src/Coalesce.php
new file mode 100644
index 000000000..55b2beb4a
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Coalesce.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_COALESCE extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/CoalesceEqual.php b/vendor/phpunit/php-token-stream/src/CoalesceEqual.php
new file mode 100644
index 000000000..b60096181
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/CoalesceEqual.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_COALESCE_EQUAL extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Colon.php b/vendor/phpunit/php-token-stream/src/Colon.php
new file mode 100644
index 000000000..66dd84089
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Colon.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_COLON extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Comma.php b/vendor/phpunit/php-token-stream/src/Comma.php
new file mode 100644
index 000000000..b57ba370c
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Comma.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_COMMA extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Comment.php b/vendor/phpunit/php-token-stream/src/Comment.php
new file mode 100644
index 000000000..c50c80b80
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Comment.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_COMMENT extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/ConcatEqual.php b/vendor/phpunit/php-token-stream/src/ConcatEqual.php
new file mode 100644
index 000000000..f57c748f3
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/ConcatEqual.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_CONCAT_EQUAL extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Const.php b/vendor/phpunit/php-token-stream/src/Const.php
new file mode 100644
index 000000000..a5376422c
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Const.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_CONST extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/ConstantEncapsedString.php b/vendor/phpunit/php-token-stream/src/ConstantEncapsedString.php
new file mode 100644
index 000000000..2a030cd3c
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/ConstantEncapsedString.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_CONSTANT_ENCAPSED_STRING extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Continue.php b/vendor/phpunit/php-token-stream/src/Continue.php
new file mode 100644
index 000000000..a21c8ba10
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Continue.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_CONTINUE extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/CurlyOpen.php b/vendor/phpunit/php-token-stream/src/CurlyOpen.php
new file mode 100644
index 000000000..7c3e9bcea
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/CurlyOpen.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_CURLY_OPEN extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/DNumber.php b/vendor/phpunit/php-token-stream/src/DNumber.php
new file mode 100644
index 000000000..bf5751f32
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/DNumber.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_DNUMBER extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Dec.php b/vendor/phpunit/php-token-stream/src/Dec.php
new file mode 100644
index 000000000..6f06341c4
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Dec.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_DEC extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Declare.php b/vendor/phpunit/php-token-stream/src/Declare.php
new file mode 100644
index 000000000..60dab6f88
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Declare.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_DECLARE extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Default.php b/vendor/phpunit/php-token-stream/src/Default.php
new file mode 100644
index 000000000..81f3bfd02
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Default.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_DEFAULT extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Dir.php b/vendor/phpunit/php-token-stream/src/Dir.php
new file mode 100644
index 000000000..add4bf84d
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Dir.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_DIR extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Div.php b/vendor/phpunit/php-token-stream/src/Div.php
new file mode 100644
index 000000000..87e11d786
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Div.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_DIV extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/DivEqual.php b/vendor/phpunit/php-token-stream/src/DivEqual.php
new file mode 100644
index 000000000..cb558a89d
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/DivEqual.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_DIV_EQUAL extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Do.php b/vendor/phpunit/php-token-stream/src/Do.php
new file mode 100644
index 000000000..32ceff1c9
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Do.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_DO extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/DocComment.php b/vendor/phpunit/php-token-stream/src/DocComment.php
new file mode 100644
index 000000000..2ca6f2216
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/DocComment.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_DOC_COMMENT extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Dollar.php b/vendor/phpunit/php-token-stream/src/Dollar.php
new file mode 100644
index 000000000..a2a8d5955
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Dollar.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_DOLLAR extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/DollarOpenCurlyBraces.php b/vendor/phpunit/php-token-stream/src/DollarOpenCurlyBraces.php
new file mode 100644
index 000000000..030bcb29b
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/DollarOpenCurlyBraces.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_DOLLAR_OPEN_CURLY_BRACES extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Dot.php b/vendor/phpunit/php-token-stream/src/Dot.php
new file mode 100644
index 000000000..b50a49eed
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Dot.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_DOT extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/DoubleArrow.php b/vendor/phpunit/php-token-stream/src/DoubleArrow.php
new file mode 100644
index 000000000..bc2c6d06a
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/DoubleArrow.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_DOUBLE_ARROW extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/DoubleCast.php b/vendor/phpunit/php-token-stream/src/DoubleCast.php
new file mode 100644
index 000000000..eb72f3642
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/DoubleCast.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_DOUBLE_CAST extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/DoubleColon.php b/vendor/phpunit/php-token-stream/src/DoubleColon.php
new file mode 100644
index 000000000..46ff6e7f2
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/DoubleColon.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_DOUBLE_COLON extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/DoubleQuotes.php b/vendor/phpunit/php-token-stream/src/DoubleQuotes.php
new file mode 100644
index 000000000..10779806e
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/DoubleQuotes.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_DOUBLE_QUOTES extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Echo.php b/vendor/phpunit/php-token-stream/src/Echo.php
new file mode 100644
index 000000000..bfee30cff
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Echo.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_ECHO extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Ellipsis.php b/vendor/phpunit/php-token-stream/src/Ellipsis.php
new file mode 100644
index 000000000..d932cedb6
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Ellipsis.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_ELLIPSIS extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Else.php b/vendor/phpunit/php-token-stream/src/Else.php
new file mode 100644
index 000000000..a3266f863
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Else.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_ELSE extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Elseif.php b/vendor/phpunit/php-token-stream/src/Elseif.php
new file mode 100644
index 000000000..76a7d4e7c
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Elseif.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_ELSEIF extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Empty.php b/vendor/phpunit/php-token-stream/src/Empty.php
new file mode 100644
index 000000000..15f662cdb
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Empty.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_EMPTY extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/EncapsedAndWhitespace.php b/vendor/phpunit/php-token-stream/src/EncapsedAndWhitespace.php
new file mode 100644
index 000000000..5224806db
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/EncapsedAndWhitespace.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_ENCAPSED_AND_WHITESPACE extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/EndHeredoc.php b/vendor/phpunit/php-token-stream/src/EndHeredoc.php
new file mode 100644
index 000000000..e95930cf4
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/EndHeredoc.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_END_HEREDOC extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Enddeclare.php b/vendor/phpunit/php-token-stream/src/Enddeclare.php
new file mode 100644
index 000000000..dd96d7f16
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Enddeclare.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_ENDDECLARE extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Endfor.php b/vendor/phpunit/php-token-stream/src/Endfor.php
new file mode 100644
index 000000000..a5382a273
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Endfor.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_ENDFOR extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Endforeach.php b/vendor/phpunit/php-token-stream/src/Endforeach.php
new file mode 100644
index 000000000..d2ab78a52
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Endforeach.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_ENDFOREACH extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Endif.php b/vendor/phpunit/php-token-stream/src/Endif.php
new file mode 100644
index 000000000..910eeea5c
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Endif.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_ENDIF extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Endswitch.php b/vendor/phpunit/php-token-stream/src/Endswitch.php
new file mode 100644
index 000000000..0fc81462d
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Endswitch.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_ENDSWITCH extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Endwhile.php b/vendor/phpunit/php-token-stream/src/Endwhile.php
new file mode 100644
index 000000000..9a289f110
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Endwhile.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_ENDWHILE extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Equal.php b/vendor/phpunit/php-token-stream/src/Equal.php
new file mode 100644
index 000000000..c8ecb0b70
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Equal.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_EQUAL extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Eval.php b/vendor/phpunit/php-token-stream/src/Eval.php
new file mode 100644
index 000000000..fb82bfd7b
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Eval.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_EVAL extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/ExclamationMark.php b/vendor/phpunit/php-token-stream/src/ExclamationMark.php
new file mode 100644
index 000000000..009ea238e
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/ExclamationMark.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_EXCLAMATION_MARK extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Exit.php b/vendor/phpunit/php-token-stream/src/Exit.php
new file mode 100644
index 000000000..9475887c6
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Exit.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_EXIT extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Extends.php b/vendor/phpunit/php-token-stream/src/Extends.php
new file mode 100644
index 000000000..bf5116060
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Extends.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_EXTENDS extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/File.php b/vendor/phpunit/php-token-stream/src/File.php
new file mode 100644
index 000000000..a89449c3b
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/File.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_FILE extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Final.php b/vendor/phpunit/php-token-stream/src/Final.php
new file mode 100644
index 000000000..f1355d239
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Final.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_FINAL extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Finally.php b/vendor/phpunit/php-token-stream/src/Finally.php
new file mode 100644
index 000000000..8d31fc326
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Finally.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_FINALLY extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Fn.php b/vendor/phpunit/php-token-stream/src/Fn.php
new file mode 100644
index 000000000..8c1ceecb1
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Fn.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_FN extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/For.php b/vendor/phpunit/php-token-stream/src/For.php
new file mode 100644
index 000000000..5b7bcbf8f
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/For.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_FOR extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Foreach.php b/vendor/phpunit/php-token-stream/src/Foreach.php
new file mode 100644
index 000000000..76906b0d1
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Foreach.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_FOREACH extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/FuncC.php b/vendor/phpunit/php-token-stream/src/FuncC.php
new file mode 100644
index 000000000..853446f12
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/FuncC.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_FUNC_C extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Function.php b/vendor/phpunit/php-token-stream/src/Function.php
new file mode 100644
index 000000000..8cc9eb1ad
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Function.php
@@ -0,0 +1,196 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_FUNCTION extends PHP_TokenWithScopeAndVisibility
+{
+ /**
+ * @var array
+ */
+ protected $arguments;
+
+ /**
+ * @var int
+ */
+ protected $ccn;
+
+ /**
+ * @var string
+ */
+ protected $name;
+
+ /**
+ * @var string
+ */
+ protected $signature;
+
+ /**
+ * @var bool
+ */
+ private $anonymous = false;
+
+ /**
+ * @return array
+ */
+ public function getArguments()
+ {
+ if ($this->arguments !== null) {
+ return $this->arguments;
+ }
+
+ $this->arguments = [];
+ $tokens = $this->tokenStream->tokens();
+ $typeDeclaration = null;
+
+ // Search for first token inside brackets
+ $i = $this->id + 2;
+
+ while (!$tokens[$i - 1] instanceof PHP_Token_OPEN_BRACKET) {
+ $i++;
+ }
+
+ while (!$tokens[$i] instanceof PHP_Token_CLOSE_BRACKET) {
+ if ($tokens[$i] instanceof PHP_Token_STRING) {
+ $typeDeclaration = (string) $tokens[$i];
+ } elseif ($tokens[$i] instanceof PHP_Token_VARIABLE) {
+ $this->arguments[(string) $tokens[$i]] = $typeDeclaration;
+ $typeDeclaration = null;
+ }
+
+ $i++;
+ }
+
+ return $this->arguments;
+ }
+
+ /**
+ * @return string
+ */
+ public function getName()
+ {
+ if ($this->name !== null) {
+ return $this->name;
+ }
+
+ $tokens = $this->tokenStream->tokens();
+
+ $i = $this->id + 1;
+
+ if ($tokens[$i] instanceof PHP_Token_WHITESPACE) {
+ $i++;
+ }
+
+ if ($tokens[$i] instanceof PHP_Token_AMPERSAND) {
+ $i++;
+ }
+
+ if ($tokens[$i + 1] instanceof PHP_Token_OPEN_BRACKET) {
+ $this->name = (string) $tokens[$i];
+ } elseif ($tokens[$i + 1] instanceof PHP_Token_WHITESPACE && $tokens[$i + 2] instanceof PHP_Token_OPEN_BRACKET) {
+ $this->name = (string) $tokens[$i];
+ } else {
+ $this->anonymous = true;
+
+ $this->name = \sprintf(
+ 'anonymousFunction:%s#%s',
+ $this->getLine(),
+ $this->getId()
+ );
+ }
+
+ if (!$this->isAnonymous()) {
+ for ($i = $this->id; $i; --$i) {
+ if ($tokens[$i] instanceof PHP_Token_NAMESPACE) {
+ $this->name = $tokens[$i]->getName() . '\\' . $this->name;
+
+ break;
+ }
+
+ if ($tokens[$i] instanceof PHP_Token_INTERFACE) {
+ break;
+ }
+ }
+ }
+
+ return $this->name;
+ }
+
+ /**
+ * @return int
+ */
+ public function getCCN()
+ {
+ if ($this->ccn !== null) {
+ return $this->ccn;
+ }
+
+ $this->ccn = 1;
+ $end = $this->getEndTokenId();
+ $tokens = $this->tokenStream->tokens();
+
+ for ($i = $this->id; $i <= $end; $i++) {
+ switch (\get_class($tokens[$i])) {
+ case PHP_Token_IF::class:
+ case PHP_Token_ELSEIF::class:
+ case PHP_Token_FOR::class:
+ case PHP_Token_FOREACH::class:
+ case PHP_Token_WHILE::class:
+ case PHP_Token_CASE::class:
+ case PHP_Token_CATCH::class:
+ case PHP_Token_BOOLEAN_AND::class:
+ case PHP_Token_LOGICAL_AND::class:
+ case PHP_Token_BOOLEAN_OR::class:
+ case PHP_Token_LOGICAL_OR::class:
+ case PHP_Token_QUESTION_MARK::class:
+ $this->ccn++;
+
+ break;
+ }
+ }
+
+ return $this->ccn;
+ }
+
+ /**
+ * @return string
+ */
+ public function getSignature()
+ {
+ if ($this->signature !== null) {
+ return $this->signature;
+ }
+
+ if ($this->isAnonymous()) {
+ $this->signature = 'anonymousFunction';
+ $i = $this->id + 1;
+ } else {
+ $this->signature = '';
+ $i = $this->id + 2;
+ }
+
+ $tokens = $this->tokenStream->tokens();
+
+ while (isset($tokens[$i]) &&
+ !$tokens[$i] instanceof PHP_Token_OPEN_CURLY &&
+ !$tokens[$i] instanceof PHP_Token_SEMICOLON) {
+ $this->signature .= $tokens[$i++];
+ }
+
+ $this->signature = \trim($this->signature);
+
+ return $this->signature;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isAnonymous()
+ {
+ return $this->anonymous;
+ }
+}
diff --git a/vendor/phpunit/php-token-stream/src/Global.php b/vendor/phpunit/php-token-stream/src/Global.php
new file mode 100644
index 000000000..15d34c0f9
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Global.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_GLOBAL extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Goto.php b/vendor/phpunit/php-token-stream/src/Goto.php
new file mode 100644
index 000000000..68cbce0db
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Goto.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_GOTO extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Gt.php b/vendor/phpunit/php-token-stream/src/Gt.php
new file mode 100644
index 000000000..1df2bc974
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Gt.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_GT extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/HaltCompiler.php b/vendor/phpunit/php-token-stream/src/HaltCompiler.php
new file mode 100644
index 000000000..1976e9b7d
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/HaltCompiler.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_HALT_COMPILER extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/If.php b/vendor/phpunit/php-token-stream/src/If.php
new file mode 100644
index 000000000..2f888f1ce
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/If.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_IF extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Implements.php b/vendor/phpunit/php-token-stream/src/Implements.php
new file mode 100644
index 000000000..bfb035bcc
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Implements.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_IMPLEMENTS extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Inc.php b/vendor/phpunit/php-token-stream/src/Inc.php
new file mode 100644
index 000000000..ca19c33ab
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Inc.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_INC extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Include.php b/vendor/phpunit/php-token-stream/src/Include.php
new file mode 100644
index 000000000..cffb378e7
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Include.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_INCLUDE extends PHP_Token_Includes
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/IncludeOnce.php b/vendor/phpunit/php-token-stream/src/IncludeOnce.php
new file mode 100644
index 000000000..da28d6178
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/IncludeOnce.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_INCLUDE_ONCE extends PHP_Token_Includes
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Includes.php b/vendor/phpunit/php-token-stream/src/Includes.php
new file mode 100644
index 000000000..285dfbf65
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Includes.php
@@ -0,0 +1,57 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+abstract class PHP_Token_Includes extends PHP_Token
+{
+ /**
+ * @var string
+ */
+ protected $name;
+
+ /**
+ * @var string
+ */
+ protected $type;
+
+ /**
+ * @return string
+ */
+ public function getName()
+ {
+ if ($this->name === null) {
+ $this->process();
+ }
+
+ return $this->name;
+ }
+
+ /**
+ * @return string
+ */
+ public function getType()
+ {
+ if ($this->type === null) {
+ $this->process();
+ }
+
+ return $this->type;
+ }
+
+ private function process(): void
+ {
+ $tokens = $this->tokenStream->tokens();
+
+ if ($tokens[$this->id + 2] instanceof PHP_Token_CONSTANT_ENCAPSED_STRING) {
+ $this->name = \trim((string) $tokens[$this->id + 2], "'\"");
+ $this->type = \strtolower(
+ \str_replace('PHP_Token_', '', PHP_Token_Util::getClass($tokens[$this->id]))
+ );
+ }
+ }
+}
diff --git a/vendor/phpunit/php-token-stream/src/InlineHtml.php b/vendor/phpunit/php-token-stream/src/InlineHtml.php
new file mode 100644
index 000000000..a4fc15e05
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/InlineHtml.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_INLINE_HTML extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Instanceof.php b/vendor/phpunit/php-token-stream/src/Instanceof.php
new file mode 100644
index 000000000..c41dd0e60
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Instanceof.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_INSTANCEOF extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Insteadof.php b/vendor/phpunit/php-token-stream/src/Insteadof.php
new file mode 100644
index 000000000..d8c0bc470
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Insteadof.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_INSTEADOF extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/IntCast.php b/vendor/phpunit/php-token-stream/src/IntCast.php
new file mode 100644
index 000000000..2b256017c
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/IntCast.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_INT_CAST extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Interface.php b/vendor/phpunit/php-token-stream/src/Interface.php
new file mode 100644
index 000000000..d2732f561
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Interface.php
@@ -0,0 +1,166 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_INTERFACE extends PHP_TokenWithScopeAndVisibility
+{
+ /**
+ * @var array
+ */
+ protected $interfaces;
+
+ /**
+ * @return string
+ */
+ public function getName()
+ {
+ return (string) $this->tokenStream[$this->id + 2];
+ }
+
+ /**
+ * @return bool
+ */
+ public function hasParent()
+ {
+ return $this->tokenStream[$this->id + 4] instanceof PHP_Token_EXTENDS;
+ }
+
+ /**
+ * @return array
+ */
+ public function getPackage()
+ {
+ $result = [
+ 'namespace' => '',
+ 'fullPackage' => '',
+ 'category' => '',
+ 'package' => '',
+ 'subpackage' => '',
+ ];
+
+ $docComment = $this->getDocblock();
+ $className = $this->getName();
+
+ for ($i = $this->id; $i; --$i) {
+ if ($this->tokenStream[$i] instanceof PHP_Token_NAMESPACE) {
+ $result['namespace'] = $this->tokenStream[$i]->getName();
+
+ break;
+ }
+ }
+
+ if ($docComment === null) {
+ return $result;
+ }
+
+ if (\preg_match('/@category[\s]+([\.\w]+)/', $docComment, $matches)) {
+ $result['category'] = $matches[1];
+ }
+
+ if (\preg_match('/@package[\s]+([\.\w]+)/', $docComment, $matches)) {
+ $result['package'] = $matches[1];
+ $result['fullPackage'] = $matches[1];
+ }
+
+ if (\preg_match('/@subpackage[\s]+([\.\w]+)/', $docComment, $matches)) {
+ $result['subpackage'] = $matches[1];
+ $result['fullPackage'] .= '.' . $matches[1];
+ }
+
+ if (empty($result['fullPackage'])) {
+ $result['fullPackage'] = $this->arrayToName(
+ \explode('_', \str_replace('\\', '_', $className)),
+ '.'
+ );
+ }
+
+ return $result;
+ }
+
+ /**
+ * @return bool|string
+ */
+ public function getParent()
+ {
+ if (!$this->hasParent()) {
+ return false;
+ }
+
+ $i = $this->id + 6;
+ $tokens = $this->tokenStream->tokens();
+ $className = (string) $tokens[$i];
+
+ while (isset($tokens[$i + 1]) &&
+ !$tokens[$i + 1] instanceof PHP_Token_WHITESPACE) {
+ $className .= (string) $tokens[++$i];
+ }
+
+ return $className;
+ }
+
+ /**
+ * @return bool
+ */
+ public function hasInterfaces()
+ {
+ return (isset($this->tokenStream[$this->id + 4]) &&
+ $this->tokenStream[$this->id + 4] instanceof PHP_Token_IMPLEMENTS) ||
+ (isset($this->tokenStream[$this->id + 8]) &&
+ $this->tokenStream[$this->id + 8] instanceof PHP_Token_IMPLEMENTS);
+ }
+
+ /**
+ * @return array|bool
+ */
+ public function getInterfaces()
+ {
+ if ($this->interfaces !== null) {
+ return $this->interfaces;
+ }
+
+ if (!$this->hasInterfaces()) {
+ return $this->interfaces = false;
+ }
+
+ if ($this->tokenStream[$this->id + 4] instanceof PHP_Token_IMPLEMENTS) {
+ $i = $this->id + 3;
+ } else {
+ $i = $this->id + 7;
+ }
+
+ $tokens = $this->tokenStream->tokens();
+
+ while (!$tokens[$i + 1] instanceof PHP_Token_OPEN_CURLY) {
+ $i++;
+
+ if ($tokens[$i] instanceof PHP_Token_STRING) {
+ $this->interfaces[] = (string) $tokens[$i];
+ }
+ }
+
+ return $this->interfaces;
+ }
+
+ /**
+ * @param string $join
+ *
+ * @return string
+ */
+ protected function arrayToName(array $parts, $join = '\\')
+ {
+ $result = '';
+
+ if (\count($parts) > 1) {
+ \array_pop($parts);
+
+ $result = \implode($join, $parts);
+ }
+
+ return $result;
+ }
+}
diff --git a/vendor/phpunit/php-token-stream/src/IsEqual.php b/vendor/phpunit/php-token-stream/src/IsEqual.php
new file mode 100644
index 000000000..70f00af5d
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/IsEqual.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_IS_EQUAL extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/IsGreaterOrEqual.php b/vendor/phpunit/php-token-stream/src/IsGreaterOrEqual.php
new file mode 100644
index 000000000..0227baf46
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/IsGreaterOrEqual.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_IS_GREATER_OR_EQUAL extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/IsIdentical.php b/vendor/phpunit/php-token-stream/src/IsIdentical.php
new file mode 100644
index 000000000..28388df5b
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/IsIdentical.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_IS_IDENTICAL extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/IsNotEqual.php b/vendor/phpunit/php-token-stream/src/IsNotEqual.php
new file mode 100644
index 000000000..f70f2290e
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/IsNotEqual.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_IS_NOT_EQUAL extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/IsNotIdentical.php b/vendor/phpunit/php-token-stream/src/IsNotIdentical.php
new file mode 100644
index 000000000..9fe3a71a2
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/IsNotIdentical.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_IS_NOT_IDENTICAL extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/IsSmallerOrEqual.php b/vendor/phpunit/php-token-stream/src/IsSmallerOrEqual.php
new file mode 100644
index 000000000..7ac0c2fa2
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/IsSmallerOrEqual.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_IS_SMALLER_OR_EQUAL extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Isset.php b/vendor/phpunit/php-token-stream/src/Isset.php
new file mode 100644
index 000000000..47941d643
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Isset.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_ISSET extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Line.php b/vendor/phpunit/php-token-stream/src/Line.php
new file mode 100644
index 000000000..ffed4dbcc
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Line.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_LINE extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/List.php b/vendor/phpunit/php-token-stream/src/List.php
new file mode 100644
index 000000000..9410fc5a7
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/List.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_LIST extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Lnumber.php b/vendor/phpunit/php-token-stream/src/Lnumber.php
new file mode 100644
index 000000000..e996bd0f8
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Lnumber.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_LNUMBER extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/LogicalAnd.php b/vendor/phpunit/php-token-stream/src/LogicalAnd.php
new file mode 100644
index 000000000..72beb476c
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/LogicalAnd.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_LOGICAL_AND extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/LogicalOr.php b/vendor/phpunit/php-token-stream/src/LogicalOr.php
new file mode 100644
index 000000000..ec8be7030
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/LogicalOr.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_LOGICAL_OR extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/LogicalXor.php b/vendor/phpunit/php-token-stream/src/LogicalXor.php
new file mode 100644
index 000000000..e1e223b99
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/LogicalXor.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_LOGICAL_XOR extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Lt.php b/vendor/phpunit/php-token-stream/src/Lt.php
new file mode 100644
index 000000000..288a41330
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Lt.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_LT extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/MethodC.php b/vendor/phpunit/php-token-stream/src/MethodC.php
new file mode 100644
index 000000000..1bebf001a
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/MethodC.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_METHOD_C extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Minus.php b/vendor/phpunit/php-token-stream/src/Minus.php
new file mode 100644
index 000000000..6ca52f523
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Minus.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_MINUS extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/MinusEqual.php b/vendor/phpunit/php-token-stream/src/MinusEqual.php
new file mode 100644
index 000000000..1bfb24c5e
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/MinusEqual.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_MINUS_EQUAL extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/ModEqual.php b/vendor/phpunit/php-token-stream/src/ModEqual.php
new file mode 100644
index 000000000..28aab5863
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/ModEqual.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_MOD_EQUAL extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/MulEqual.php b/vendor/phpunit/php-token-stream/src/MulEqual.php
new file mode 100644
index 000000000..16a0d242e
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/MulEqual.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_MUL_EQUAL extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Mult.php b/vendor/phpunit/php-token-stream/src/Mult.php
new file mode 100644
index 000000000..bd6daed76
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Mult.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_MULT extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/NameFullyQualified.php b/vendor/phpunit/php-token-stream/src/NameFullyQualified.php
new file mode 100644
index 000000000..744118abc
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/NameFullyQualified.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_NAME_FULLY_QUALIFIED extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/NameQualified.php b/vendor/phpunit/php-token-stream/src/NameQualified.php
new file mode 100644
index 000000000..a893144c0
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/NameQualified.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_NAME_QUALIFIED extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/NameRelative.php b/vendor/phpunit/php-token-stream/src/NameRelative.php
new file mode 100644
index 000000000..0b358cc64
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/NameRelative.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_NAME_RELATIVE extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Namespace.php b/vendor/phpunit/php-token-stream/src/Namespace.php
new file mode 100644
index 000000000..634d8ad76
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Namespace.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_NAMESPACE extends PHP_TokenWithScope
+{
+ /**
+ * @return string
+ */
+ public function getName()
+ {
+ $tokens = $this->tokenStream->tokens();
+ $namespace = (string) $tokens[$this->id + 2];
+
+ for ($i = $this->id + 3;; $i += 2) {
+ if (isset($tokens[$i]) &&
+ $tokens[$i] instanceof PHP_Token_NS_SEPARATOR) {
+ $namespace .= '\\' . $tokens[$i + 1];
+ } else {
+ break;
+ }
+ }
+
+ return $namespace;
+ }
+}
diff --git a/vendor/phpunit/php-token-stream/src/New.php b/vendor/phpunit/php-token-stream/src/New.php
new file mode 100644
index 000000000..bd67af28b
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/New.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_NEW extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/NsC.php b/vendor/phpunit/php-token-stream/src/NsC.php
new file mode 100644
index 000000000..2778ea4cd
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/NsC.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_NS_C extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/NsSeparator.php b/vendor/phpunit/php-token-stream/src/NsSeparator.php
new file mode 100644
index 000000000..950291ed9
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/NsSeparator.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_NS_SEPARATOR extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/NumString.php b/vendor/phpunit/php-token-stream/src/NumString.php
new file mode 100644
index 000000000..a073e3d06
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/NumString.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_NUM_STRING extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/ObjectCast.php b/vendor/phpunit/php-token-stream/src/ObjectCast.php
new file mode 100644
index 000000000..c0ec7d5b7
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/ObjectCast.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_OBJECT_CAST extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/ObjectOperator.php b/vendor/phpunit/php-token-stream/src/ObjectOperator.php
new file mode 100644
index 000000000..a4ca75b81
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/ObjectOperator.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_OBJECT_OPERATOR extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/OpenBracket.php b/vendor/phpunit/php-token-stream/src/OpenBracket.php
new file mode 100644
index 000000000..2cb93ed20
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/OpenBracket.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_OPEN_BRACKET extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/OpenCurly.php b/vendor/phpunit/php-token-stream/src/OpenCurly.php
new file mode 100644
index 000000000..59c118d1b
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/OpenCurly.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_OPEN_CURLY extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/OpenSquare.php b/vendor/phpunit/php-token-stream/src/OpenSquare.php
new file mode 100644
index 000000000..04cfefab0
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/OpenSquare.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_OPEN_SQUARE extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/OpenTag.php b/vendor/phpunit/php-token-stream/src/OpenTag.php
new file mode 100644
index 000000000..d3e00239e
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/OpenTag.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_OPEN_TAG extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/OpenTagWithEcho.php b/vendor/phpunit/php-token-stream/src/OpenTagWithEcho.php
new file mode 100644
index 000000000..ec981a2a3
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/OpenTagWithEcho.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_OPEN_TAG_WITH_ECHO extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/OrEqual.php b/vendor/phpunit/php-token-stream/src/OrEqual.php
new file mode 100644
index 000000000..8e7005df2
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/OrEqual.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_OR_EQUAL extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/PaamayimNekudotayim.php b/vendor/phpunit/php-token-stream/src/PaamayimNekudotayim.php
new file mode 100644
index 000000000..3185555d9
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/PaamayimNekudotayim.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_PAAMAYIM_NEKUDOTAYIM extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Percent.php b/vendor/phpunit/php-token-stream/src/Percent.php
new file mode 100644
index 000000000..a2baab533
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Percent.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_PERCENT extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Pipe.php b/vendor/phpunit/php-token-stream/src/Pipe.php
new file mode 100644
index 000000000..4e9438fd9
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Pipe.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_PIPE extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Plus.php b/vendor/phpunit/php-token-stream/src/Plus.php
new file mode 100644
index 000000000..5a4ae324c
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Plus.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_PLUS extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/PlusEqual.php b/vendor/phpunit/php-token-stream/src/PlusEqual.php
new file mode 100644
index 000000000..23825f377
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/PlusEqual.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_PLUS_EQUAL extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Pow.php b/vendor/phpunit/php-token-stream/src/Pow.php
new file mode 100644
index 000000000..84276d73d
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Pow.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_POW extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/PowEqual.php b/vendor/phpunit/php-token-stream/src/PowEqual.php
new file mode 100644
index 000000000..5e5288db7
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/PowEqual.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_POW_EQUAL extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Print.php b/vendor/phpunit/php-token-stream/src/Print.php
new file mode 100644
index 000000000..72ef8e6ab
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Print.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_PRINT extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Private.php b/vendor/phpunit/php-token-stream/src/Private.php
new file mode 100644
index 000000000..0eb36d522
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Private.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_PRIVATE extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Protected.php b/vendor/phpunit/php-token-stream/src/Protected.php
new file mode 100644
index 000000000..9c9cc33ba
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Protected.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_PROTECTED extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Public.php b/vendor/phpunit/php-token-stream/src/Public.php
new file mode 100644
index 000000000..b37d4a94d
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Public.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_PUBLIC extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/QuestionMark.php b/vendor/phpunit/php-token-stream/src/QuestionMark.php
new file mode 100644
index 000000000..4202d5921
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/QuestionMark.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_QUESTION_MARK extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Require.php b/vendor/phpunit/php-token-stream/src/Require.php
new file mode 100644
index 000000000..e18c03fcc
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Require.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_REQUIRE extends PHP_Token_Includes
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/RequireOnce.php b/vendor/phpunit/php-token-stream/src/RequireOnce.php
new file mode 100644
index 000000000..15628a3a8
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/RequireOnce.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_REQUIRE_ONCE extends PHP_Token_Includes
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Return.php b/vendor/phpunit/php-token-stream/src/Return.php
new file mode 100644
index 000000000..acdbc23b1
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Return.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_RETURN extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Semicolon.php b/vendor/phpunit/php-token-stream/src/Semicolon.php
new file mode 100644
index 000000000..47bfa5e16
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Semicolon.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_SEMICOLON extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Sl.php b/vendor/phpunit/php-token-stream/src/Sl.php
new file mode 100644
index 000000000..cda5ecc11
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Sl.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_SL extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/SlEqual.php b/vendor/phpunit/php-token-stream/src/SlEqual.php
new file mode 100644
index 000000000..3d8a17e5a
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/SlEqual.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_SL_EQUAL extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Spaceship.php b/vendor/phpunit/php-token-stream/src/Spaceship.php
new file mode 100644
index 000000000..639a2e30a
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Spaceship.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_SPACESHIP extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Sr.php b/vendor/phpunit/php-token-stream/src/Sr.php
new file mode 100644
index 000000000..749bf0da5
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Sr.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_SR extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/SrEqual.php b/vendor/phpunit/php-token-stream/src/SrEqual.php
new file mode 100644
index 000000000..674039fbd
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/SrEqual.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_SR_EQUAL extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/StartHeredoc.php b/vendor/phpunit/php-token-stream/src/StartHeredoc.php
new file mode 100644
index 000000000..867a35760
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/StartHeredoc.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_START_HEREDOC extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Static.php b/vendor/phpunit/php-token-stream/src/Static.php
new file mode 100644
index 000000000..53307ce29
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Static.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_STATIC extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Token/Stream.php b/vendor/phpunit/php-token-stream/src/Stream.php
similarity index 54%
rename from vendor/phpunit/php-token-stream/src/Token/Stream.php
rename to vendor/phpunit/php-token-stream/src/Stream.php
index c2817b169..bcdb48a73 100644
--- a/vendor/phpunit/php-token-stream/src/Token/Stream.php
+++ b/vendor/phpunit/php-token-stream/src/Stream.php
@@ -1,50 +1,46 @@
-
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
-
-/**
- * A stream of PHP tokens.
- */
class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator
{
/**
- * @var array
+ * @var array>
*/
protected static $customTokens = [
- '(' => 'PHP_Token_OPEN_BRACKET',
- ')' => 'PHP_Token_CLOSE_BRACKET',
- '[' => 'PHP_Token_OPEN_SQUARE',
- ']' => 'PHP_Token_CLOSE_SQUARE',
- '{' => 'PHP_Token_OPEN_CURLY',
- '}' => 'PHP_Token_CLOSE_CURLY',
- ';' => 'PHP_Token_SEMICOLON',
- '.' => 'PHP_Token_DOT',
- ',' => 'PHP_Token_COMMA',
- '=' => 'PHP_Token_EQUAL',
- '<' => 'PHP_Token_LT',
- '>' => 'PHP_Token_GT',
- '+' => 'PHP_Token_PLUS',
- '-' => 'PHP_Token_MINUS',
- '*' => 'PHP_Token_MULT',
- '/' => 'PHP_Token_DIV',
- '?' => 'PHP_Token_QUESTION_MARK',
- '!' => 'PHP_Token_EXCLAMATION_MARK',
- ':' => 'PHP_Token_COLON',
- '"' => 'PHP_Token_DOUBLE_QUOTES',
- '@' => 'PHP_Token_AT',
- '&' => 'PHP_Token_AMPERSAND',
- '%' => 'PHP_Token_PERCENT',
- '|' => 'PHP_Token_PIPE',
- '$' => 'PHP_Token_DOLLAR',
- '^' => 'PHP_Token_CARET',
- '~' => 'PHP_Token_TILDE',
- '`' => 'PHP_Token_BACKTICK'
+ '(' => PHP_Token_OPEN_BRACKET::class,
+ ')' => PHP_Token_CLOSE_BRACKET::class,
+ '[' => PHP_Token_OPEN_SQUARE::class,
+ ']' => PHP_Token_CLOSE_SQUARE::class,
+ '{' => PHP_Token_OPEN_CURLY::class,
+ '}' => PHP_Token_CLOSE_CURLY::class,
+ ';' => PHP_Token_SEMICOLON::class,
+ '.' => PHP_Token_DOT::class,
+ ',' => PHP_Token_COMMA::class,
+ '=' => PHP_Token_EQUAL::class,
+ '<' => PHP_Token_LT::class,
+ '>' => PHP_Token_GT::class,
+ '+' => PHP_Token_PLUS::class,
+ '-' => PHP_Token_MINUS::class,
+ '*' => PHP_Token_MULT::class,
+ '/' => PHP_Token_DIV::class,
+ '?' => PHP_Token_QUESTION_MARK::class,
+ '!' => PHP_Token_EXCLAMATION_MARK::class,
+ ':' => PHP_Token_COLON::class,
+ '"' => PHP_Token_DOUBLE_QUOTES::class,
+ '@' => PHP_Token_AT::class,
+ '&' => PHP_Token_AMPERSAND::class,
+ '%' => PHP_Token_PERCENT::class,
+ '|' => PHP_Token_PIPE::class,
+ '$' => PHP_Token_DOLLAR::class,
+ '^' => PHP_Token_CARET::class,
+ '~' => PHP_Token_TILDE::class,
+ '`' => PHP_Token_BACKTICK::class,
];
/**
@@ -57,6 +53,11 @@ class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator
*/
protected $tokens = [];
+ /**
+ * @var array
+ */
+ protected $tokensByLine = [];
+
/**
* @var int
*/
@@ -104,9 +105,9 @@ class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator
*/
public function __construct($sourceCode)
{
- if (is_file($sourceCode)) {
+ if (\is_file($sourceCode)) {
$this->filename = $sourceCode;
- $sourceCode = file_get_contents($sourceCode);
+ $sourceCode = \file_get_contents($sourceCode);
}
$this->scan($sourceCode);
@@ -117,7 +118,8 @@ class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator
*/
public function __destruct()
{
- $this->tokens = [];
+ $this->tokens = [];
+ $this->tokensByLine = [];
}
/**
@@ -143,70 +145,11 @@ class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator
}
/**
- * Scans the source for sequences of characters and converts them into a
- * stream of tokens.
- *
- * @param string $sourceCode
+ * @return int
*/
- protected function scan($sourceCode)
+ public function count()
{
- $id = 0;
- $line = 1;
- $tokens = token_get_all($sourceCode);
- $numTokens = count($tokens);
-
- $lastNonWhitespaceTokenWasDoubleColon = false;
-
- for ($i = 0; $i < $numTokens; ++$i) {
- $token = $tokens[$i];
- $skip = 0;
-
- if (is_array($token)) {
- $name = substr(token_name($token[0]), 2);
- $text = $token[1];
-
- if ($lastNonWhitespaceTokenWasDoubleColon && $name == 'CLASS') {
- $name = 'CLASS_NAME_CONSTANT';
- } elseif ($name == 'USE' && isset($tokens[$i + 2][0]) && $tokens[$i + 2][0] == T_FUNCTION) {
- $name = 'USE_FUNCTION';
- $text .= $tokens[$i + 1][1] . $tokens[$i + 2][1];
- $skip = 2;
- }
-
- $tokenClass = 'PHP_Token_' . $name;
- } else {
- $text = $token;
- $tokenClass = self::$customTokens[$token];
- }
-
- $this->tokens[] = new $tokenClass($text, $line, $this, $id++);
- $lines = substr_count($text, "\n");
- $line += $lines;
-
- if ($tokenClass == 'PHP_Token_HALT_COMPILER') {
- break;
- } elseif ($tokenClass == 'PHP_Token_COMMENT' ||
- $tokenClass == 'PHP_Token_DOC_COMMENT') {
- $this->linesOfCode['cloc'] += $lines + 1;
- }
-
- if ($name == 'DOUBLE_COLON') {
- $lastNonWhitespaceTokenWasDoubleColon = true;
- } elseif ($name != 'WHITESPACE') {
- $lastNonWhitespaceTokenWasDoubleColon = false;
- }
-
- $i += $skip;
- }
-
- $this->linesOfCode['loc'] = substr_count($sourceCode, "\n");
- $this->linesOfCode['ncloc'] = $this->linesOfCode['loc'] -
- $this->linesOfCode['cloc'];
- }
-
- public function count(): int
- {
- return count($this->tokens);
+ return \count($this->tokens);
}
/**
@@ -285,7 +228,7 @@ class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator
*
* @param bool $categorize OPTIONAL
* @param string $category OPTIONAL Either 'require_once', 'require',
- * 'include_once', 'include'.
+ * 'include_once', 'include'
*
* @return array
*/
@@ -293,19 +236,20 @@ class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator
{
if ($this->includes === null) {
$this->includes = [
- 'require_once' => [],
- 'require' => [],
- 'include_once' => [],
- 'include' => []
+ 'require_once' => [],
+ 'require' => [],
+ 'include_once' => [],
+ 'include' => [],
];
foreach ($this->tokens as $token) {
- switch (PHP_Token_Util::getClass($token)) {
- case 'PHP_Token_REQUIRE_ONCE':
- case 'PHP_Token_REQUIRE':
- case 'PHP_Token_INCLUDE_ONCE':
- case 'PHP_Token_INCLUDE':
+ switch (\get_class($token)) {
+ case PHP_Token_REQUIRE_ONCE::class:
+ case PHP_Token_REQUIRE::class:
+ case PHP_Token_INCLUDE_ONCE::class:
+ case PHP_Token_INCLUDE::class:
$this->includes[$token->getType()][] = $token->getName();
+
break;
}
}
@@ -314,7 +258,7 @@ class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator
if (isset($this->includes[$category])) {
$includes = $this->includes[$category];
} elseif ($categorize === false) {
- $includes = array_merge(
+ $includes = \array_merge(
$this->includes['require_once'],
$this->includes['require'],
$this->includes['include_once'],
@@ -341,131 +285,6 @@ class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator
}
}
- protected function parse()
- {
- $this->interfaces = [];
- $this->classes = [];
- $this->traits = [];
- $this->functions = [];
- $class = [];
- $classEndLine = [];
- $trait = false;
- $traitEndLine = false;
- $interface = false;
- $interfaceEndLine = false;
-
- foreach ($this->tokens as $token) {
- switch (PHP_Token_Util::getClass($token)) {
- case 'PHP_Token_HALT_COMPILER':
- return;
-
- case 'PHP_Token_INTERFACE':
- $interface = $token->getName();
- $interfaceEndLine = $token->getEndLine();
-
- $this->interfaces[$interface] = [
- 'methods' => [],
- 'parent' => $token->getParent(),
- 'keywords' => $token->getKeywords(),
- 'docblock' => $token->getDocblock(),
- 'startLine' => $token->getLine(),
- 'endLine' => $interfaceEndLine,
- 'package' => $token->getPackage(),
- 'file' => $this->filename
- ];
- break;
-
- case 'PHP_Token_CLASS':
- case 'PHP_Token_TRAIT':
- $tmp = [
- 'methods' => [],
- 'parent' => $token->getParent(),
- 'interfaces'=> $token->getInterfaces(),
- 'keywords' => $token->getKeywords(),
- 'docblock' => $token->getDocblock(),
- 'startLine' => $token->getLine(),
- 'endLine' => $token->getEndLine(),
- 'package' => $token->getPackage(),
- 'file' => $this->filename
- ];
-
- if ($token->getName() !== null) {
- if ($token instanceof PHP_Token_CLASS) {
- $class[] = $token->getName();
- $classEndLine[] = $token->getEndLine();
-
- $this->classes[$class[count($class) - 1]] = $tmp;
- } else {
- $trait = $token->getName();
- $traitEndLine = $token->getEndLine();
- $this->traits[$trait] = $tmp;
- }
- }
- break;
-
- case 'PHP_Token_FUNCTION':
- $name = $token->getName();
- $tmp = [
- 'docblock' => $token->getDocblock(),
- 'keywords' => $token->getKeywords(),
- 'visibility'=> $token->getVisibility(),
- 'signature' => $token->getSignature(),
- 'startLine' => $token->getLine(),
- 'endLine' => $token->getEndLine(),
- 'ccn' => $token->getCCN(),
- 'file' => $this->filename
- ];
-
- if (empty($class) &&
- $trait === false &&
- $interface === false) {
- $this->functions[$name] = $tmp;
-
- $this->addFunctionToMap(
- $name,
- $tmp['startLine'],
- $tmp['endLine']
- );
- } elseif (!empty($class)) {
- $this->classes[$class[count($class) - 1]]['methods'][$name] = $tmp;
-
- $this->addFunctionToMap(
- $class[count($class) - 1] . '::' . $name,
- $tmp['startLine'],
- $tmp['endLine']
- );
- } elseif ($trait !== false) {
- $this->traits[$trait]['methods'][$name] = $tmp;
-
- $this->addFunctionToMap(
- $trait . '::' . $name,
- $tmp['startLine'],
- $tmp['endLine']
- );
- } else {
- $this->interfaces[$interface]['methods'][$name] = $tmp;
- }
- break;
-
- case 'PHP_Token_CLOSE_CURLY':
- if (!empty($classEndLine) &&
- $classEndLine[count($classEndLine) - 1] == $token->getLine()) {
- array_pop($classEndLine);
- array_pop($class);
- } elseif ($traitEndLine !== false &&
- $traitEndLine == $token->getLine()) {
- $trait = false;
- $traitEndLine = false;
- } elseif ($interfaceEndLine !== false &&
- $interfaceEndLine == $token->getLine()) {
- $interface = false;
- $interfaceEndLine = false;
- }
- break;
- }
- }
- }
-
/**
* @return array
*/
@@ -474,47 +293,60 @@ class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator
return $this->linesOfCode;
}
- public function rewind(): void
+ public function rewind()/*: void*/
{
$this->position = 0;
}
- public function valid(): bool
+ /**
+ * @return bool
+ */
+ public function valid()
{
return isset($this->tokens[$this->position]);
}
- #[\ReturnTypeWillChange]
+ /**
+ * @return int
+ */
public function key()
{
return $this->position;
}
- #[\ReturnTypeWillChange]
+ /**
+ * @return PHP_Token
+ */
public function current()
{
return $this->tokens[$this->position];
}
- public function next(): void
+ public function next()/*: void*/
{
$this->position++;
}
/**
* @param int $offset
+ *
+ * @return bool
*/
- public function offsetExists($offset): bool
+ public function offsetExists($offset)
{
return isset($this->tokens[$offset]);
}
- #[\ReturnTypeWillChange]
+ /**
+ * @param int $offset
+ *
+ * @throws OutOfBoundsException
+ */
public function offsetGet($offset)
{
if (!$this->offsetExists($offset)) {
throw new OutOfBoundsException(
- sprintf(
+ \sprintf(
'No token at position "%s"',
$offset
)
@@ -525,10 +357,9 @@ class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator
}
/**
- * @param int $offset
- * @param mixed $value
+ * @param int $offset
*/
- public function offsetSet($offset, $value): void
+ public function offsetSet($offset, $value)/*: void*/
{
$this->tokens[$offset] = $value;
}
@@ -538,11 +369,11 @@ class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator
*
* @throws OutOfBoundsException
*/
- public function offsetUnset($offset): void
+ public function offsetUnset($offset)/*: void*/
{
if (!$this->offsetExists($offset)) {
throw new OutOfBoundsException(
- sprintf(
+ \sprintf(
'No token at position "%s"',
$offset
)
@@ -559,13 +390,13 @@ class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator
*
* @throws OutOfBoundsException
*/
- public function seek($position): void
+ public function seek($position)/*: void*/
{
$this->position = $position;
if (!$this->valid()) {
throw new OutOfBoundsException(
- sprintf(
+ \sprintf(
'No token at position "%s"',
$this->position
)
@@ -573,12 +404,252 @@ class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator
}
}
+ /**
+ * Scans the source for sequences of characters and converts them into a
+ * stream of tokens.
+ *
+ * @param string $sourceCode
+ */
+ protected function scan($sourceCode)/*: void*/
+ {
+ $id = 0;
+ $line = 1;
+ $tokens = \token_get_all($sourceCode);
+ $numTokens = \count($tokens);
+
+ $lastNonWhitespaceTokenWasDoubleColon = false;
+
+ $name = null;
+
+ for ($i = 0; $i < $numTokens; ++$i) {
+ $token = $tokens[$i];
+ $skip = 0;
+
+ if (\is_array($token)) {
+ $name = \substr(\token_name($token[0]), 2);
+ $text = $token[1];
+
+ if ($lastNonWhitespaceTokenWasDoubleColon && $name == 'CLASS') {
+ $name = 'CLASS_NAME_CONSTANT';
+ } elseif ($name == 'USE' && isset($tokens[$i + 2][0]) && $tokens[$i + 2][0] == \T_FUNCTION) {
+ $name = 'USE_FUNCTION';
+ $text .= $tokens[$i + 1][1] . $tokens[$i + 2][1];
+ $skip = 2;
+ }
+
+ /** @var class-string $tokenClass */
+ $tokenClass = 'PHP_Token_' . $name;
+ } else {
+ $text = $token;
+ $tokenClass = self::$customTokens[$token];
+ }
+
+ /*
+ * @see https://github.com/sebastianbergmann/php-token-stream/issues/95
+ */
+ if (PHP_MAJOR_VERSION >= 8 &&
+ $name === 'WHITESPACE' && // Current token is T_WHITESPACE
+ isset($this->tokens[$id - 1]) && // Current token is not the first token
+ $this->tokens[$id - 1] instanceof PHP_Token_COMMENT && // Previous token is T_COMMENT
+ strpos((string) $this->tokens[$id - 1], '/*') === false && // Previous token is comment that starts with '#' or '//'
+ strpos($text, "\n") === 0 // Text of current token begins with newline
+ ) {
+ $this->tokens[$id - 1] = new PHP_Token_COMMENT(
+ $this->tokens[$id - 1] . "\n",
+ $this->tokens[$id - 1]->getLine(),
+ $this,
+ $id - 1
+ );
+
+ $text = substr($text, 1);
+
+ $line++;
+
+ if (empty($text)) {
+ continue;
+ }
+ }
+
+ if (!isset($this->tokensByLine[$line])) {
+ $this->tokensByLine[$line] = [];
+ }
+
+ $token = new $tokenClass($text, $line, $this, $id++);
+
+ $this->tokens[] = $token;
+ $this->tokensByLine[$line][] = $token;
+
+ $line += \substr_count($text, "\n");
+
+ if ($tokenClass == PHP_Token_HALT_COMPILER::class) {
+ break;
+ }
+
+ if ($name == 'DOUBLE_COLON') {
+ $lastNonWhitespaceTokenWasDoubleColon = true;
+ } elseif ($name != 'WHITESPACE') {
+ $lastNonWhitespaceTokenWasDoubleColon = false;
+ }
+
+ $i += $skip;
+ }
+
+ foreach ($this->tokens as $token) {
+ if (!$token instanceof PHP_Token_COMMENT && !$token instanceof PHP_Token_DOC_COMMENT) {
+ continue;
+ }
+
+ foreach ($this->tokensByLine[$token->getLine()] as $_token) {
+ if (!$_token instanceof PHP_Token_COMMENT && !$_token instanceof PHP_Token_DOC_COMMENT && !$_token instanceof PHP_Token_WHITESPACE) {
+ continue 2;
+ }
+ }
+
+ $this->linesOfCode['cloc'] += max(1, \substr_count((string) $token, "\n"));
+ }
+
+ $this->linesOfCode['loc'] = \substr_count($sourceCode, "\n");
+ $this->linesOfCode['ncloc'] = $this->linesOfCode['loc'] -
+ $this->linesOfCode['cloc'];
+ }
+
+ protected function parse()/*: void*/
+ {
+ $this->interfaces = [];
+ $this->classes = [];
+ $this->traits = [];
+ $this->functions = [];
+ $class = [];
+ $classEndLine = [];
+ $trait = false;
+ $traitEndLine = false;
+ $interface = false;
+ $interfaceEndLine = false;
+
+ foreach ($this->tokens as $token) {
+ switch (\get_class($token)) {
+ case PHP_Token_HALT_COMPILER::class:
+ return;
+
+ case PHP_Token_INTERFACE::class:
+ $interface = $token->getName();
+ $interfaceEndLine = $token->getEndLine();
+
+ $this->interfaces[$interface] = [
+ 'methods' => [],
+ 'parent' => $token->getParent(),
+ 'keywords' => $token->getKeywords(),
+ 'docblock' => $token->getDocblock(),
+ 'startLine' => $token->getLine(),
+ 'endLine' => $interfaceEndLine,
+ 'package' => $token->getPackage(),
+ 'file' => $this->filename,
+ ];
+
+ break;
+
+ case PHP_Token_CLASS::class:
+ case PHP_Token_TRAIT::class:
+ $tmp = [
+ 'methods' => [],
+ 'parent' => $token->getParent(),
+ 'interfaces'=> $token->getInterfaces(),
+ 'keywords' => $token->getKeywords(),
+ 'docblock' => $token->getDocblock(),
+ 'startLine' => $token->getLine(),
+ 'endLine' => $token->getEndLine(),
+ 'package' => $token->getPackage(),
+ 'file' => $this->filename,
+ ];
+
+ if ($token instanceof PHP_Token_CLASS) {
+ $class[] = $token->getName();
+ $classEndLine[] = $token->getEndLine();
+
+ if ($token->getName() !== null) {
+ $this->classes[$class[\count($class) - 1]] = $tmp;
+ }
+ } else {
+ $trait = $token->getName();
+ $traitEndLine = $token->getEndLine();
+ $this->traits[$trait] = $tmp;
+ }
+
+ break;
+
+ case PHP_Token_FUNCTION::class:
+ $name = $token->getName();
+ $tmp = [
+ 'docblock' => $token->getDocblock(),
+ 'keywords' => $token->getKeywords(),
+ 'visibility'=> $token->getVisibility(),
+ 'signature' => $token->getSignature(),
+ 'startLine' => $token->getLine(),
+ 'endLine' => $token->getEndLine(),
+ 'ccn' => $token->getCCN(),
+ 'file' => $this->filename,
+ ];
+
+ if (empty($class) &&
+ $trait === false &&
+ $interface === false) {
+ $this->functions[$name] = $tmp;
+
+ $this->addFunctionToMap(
+ $name,
+ $tmp['startLine'],
+ $tmp['endLine']
+ );
+ } elseif (!empty($class)) {
+ if ($class[\count($class) - 1] !== null) {
+ $this->classes[$class[\count($class) - 1]]['methods'][$name] = $tmp;
+
+ $this->addFunctionToMap(
+ $class[\count($class) - 1] . '::' . $name,
+ $tmp['startLine'],
+ $tmp['endLine']
+ );
+ }
+ } elseif ($trait !== false) {
+ $this->traits[$trait]['methods'][$name] = $tmp;
+
+ $this->addFunctionToMap(
+ $trait . '::' . $name,
+ $tmp['startLine'],
+ $tmp['endLine']
+ );
+ } else {
+ $this->interfaces[$interface]['methods'][$name] = $tmp;
+ }
+
+ break;
+
+ case PHP_Token_CLOSE_CURLY::class:
+ if (!empty($classEndLine) &&
+ $classEndLine[\count($classEndLine) - 1] == $token->getLine()) {
+ \array_pop($classEndLine);
+ \array_pop($class);
+ } elseif ($traitEndLine !== false &&
+ $traitEndLine == $token->getLine()) {
+ $trait = false;
+ $traitEndLine = false;
+ } elseif ($interfaceEndLine !== false &&
+ $interfaceEndLine == $token->getLine()) {
+ $interface = false;
+ $interfaceEndLine = false;
+ }
+
+ break;
+ }
+ }
+ }
+
/**
* @param string $name
* @param int $startLine
* @param int $endLine
*/
- private function addFunctionToMap($name, $startLine, $endLine)
+ private function addFunctionToMap($name, $startLine, $endLine): void
{
for ($line = $startLine; $line <= $endLine; $line++) {
$this->lineToFunctionMap[$line] = $name;
diff --git a/vendor/phpunit/php-token-stream/src/String.php b/vendor/phpunit/php-token-stream/src/String.php
new file mode 100644
index 000000000..89deb0048
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/String.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_STRING extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/StringCast.php b/vendor/phpunit/php-token-stream/src/StringCast.php
new file mode 100644
index 000000000..f2df377ce
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/StringCast.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_STRING_CAST extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/StringVarname.php b/vendor/phpunit/php-token-stream/src/StringVarname.php
new file mode 100644
index 000000000..9012f1f9b
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/StringVarname.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_STRING_VARNAME extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Switch.php b/vendor/phpunit/php-token-stream/src/Switch.php
new file mode 100644
index 000000000..030d43b52
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Switch.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_SWITCH extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Throw.php b/vendor/phpunit/php-token-stream/src/Throw.php
new file mode 100644
index 000000000..213fda067
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Throw.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_THROW extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Tilde.php b/vendor/phpunit/php-token-stream/src/Tilde.php
new file mode 100644
index 000000000..c6c6ca5b9
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Tilde.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_TILDE extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Token.php b/vendor/phpunit/php-token-stream/src/Token.php
index 65fdb0677..d6280f3e9 100644
--- a/vendor/phpunit/php-token-stream/src/Token.php
+++ b/vendor/phpunit/php-token-stream/src/Token.php
@@ -1,16 +1,12 @@
-
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
-
-/**
- * A PHP token.
- */
abstract class PHP_Token
{
/**
@@ -34,10 +30,9 @@ abstract class PHP_Token
protected $id;
/**
- * @param string $text
- * @param int $line
- * @param PHP_Token_Stream $tokenStream
- * @param int $id
+ * @param string $text
+ * @param int $line
+ * @param int $id
*/
public function __construct($text, $line, PHP_Token_Stream $tokenStream, $id)
{
@@ -71,1291 +66,3 @@ abstract class PHP_Token
return $this->id;
}
}
-
-abstract class PHP_TokenWithScope extends PHP_Token
-{
- /**
- * @var int
- */
- protected $endTokenId;
-
- /**
- * Get the docblock for this token
- *
- * This method will fetch the docblock belonging to the current token. The
- * docblock must be placed on the line directly above the token to be
- * recognized.
- *
- * @return string|null Returns the docblock as a string if found
- */
- public function getDocblock()
- {
- $tokens = $this->tokenStream->tokens();
- $currentLineNumber = $tokens[$this->id]->getLine();
- $prevLineNumber = $currentLineNumber - 1;
-
- for ($i = $this->id - 1; $i; $i--) {
- if (!isset($tokens[$i])) {
- return;
- }
-
- if ($tokens[$i] instanceof PHP_Token_FUNCTION ||
- $tokens[$i] instanceof PHP_Token_CLASS ||
- $tokens[$i] instanceof PHP_Token_TRAIT) {
- // Some other trait, class or function, no docblock can be
- // used for the current token
- break;
- }
-
- $line = $tokens[$i]->getLine();
-
- if ($line == $currentLineNumber ||
- ($line == $prevLineNumber &&
- $tokens[$i] instanceof PHP_Token_WHITESPACE)) {
- continue;
- }
-
- if ($line < $currentLineNumber &&
- !$tokens[$i] instanceof PHP_Token_DOC_COMMENT) {
- break;
- }
-
- return (string) $tokens[$i];
- }
- }
-
- /**
- * @return int
- */
- public function getEndTokenId()
- {
- $block = 0;
- $i = $this->id;
- $tokens = $this->tokenStream->tokens();
-
- while ($this->endTokenId === null && isset($tokens[$i])) {
- if ($tokens[$i] instanceof PHP_Token_OPEN_CURLY ||
- $tokens[$i] instanceof PHP_Token_DOLLAR_OPEN_CURLY_BRACES ||
- $tokens[$i] instanceof PHP_Token_CURLY_OPEN) {
- $block++;
- } elseif ($tokens[$i] instanceof PHP_Token_CLOSE_CURLY) {
- $block--;
-
- if ($block === 0) {
- $this->endTokenId = $i;
- }
- } elseif (($this instanceof PHP_Token_FUNCTION ||
- $this instanceof PHP_Token_NAMESPACE) &&
- $tokens[$i] instanceof PHP_Token_SEMICOLON) {
- if ($block === 0) {
- $this->endTokenId = $i;
- }
- }
-
- $i++;
- }
-
- if ($this->endTokenId === null) {
- $this->endTokenId = $this->id;
- }
-
- return $this->endTokenId;
- }
-
- /**
- * @return int
- */
- public function getEndLine()
- {
- return $this->tokenStream[$this->getEndTokenId()]->getLine();
- }
-}
-
-abstract class PHP_TokenWithScopeAndVisibility extends PHP_TokenWithScope
-{
- /**
- * @return string
- */
- public function getVisibility()
- {
- $tokens = $this->tokenStream->tokens();
-
- for ($i = $this->id - 2; $i > $this->id - 7; $i -= 2) {
- if (isset($tokens[$i]) &&
- ($tokens[$i] instanceof PHP_Token_PRIVATE ||
- $tokens[$i] instanceof PHP_Token_PROTECTED ||
- $tokens[$i] instanceof PHP_Token_PUBLIC)) {
- return strtolower(
- str_replace('PHP_Token_', '', PHP_Token_Util::getClass($tokens[$i]))
- );
- }
- if (isset($tokens[$i]) &&
- !($tokens[$i] instanceof PHP_Token_STATIC ||
- $tokens[$i] instanceof PHP_Token_FINAL ||
- $tokens[$i] instanceof PHP_Token_ABSTRACT)) {
- // no keywords; stop visibility search
- break;
- }
- }
- }
-
- /**
- * @return string
- */
- public function getKeywords()
- {
- $keywords = [];
- $tokens = $this->tokenStream->tokens();
-
- for ($i = $this->id - 2; $i > $this->id - 7; $i -= 2) {
- if (isset($tokens[$i]) &&
- ($tokens[$i] instanceof PHP_Token_PRIVATE ||
- $tokens[$i] instanceof PHP_Token_PROTECTED ||
- $tokens[$i] instanceof PHP_Token_PUBLIC)) {
- continue;
- }
-
- if (isset($tokens[$i]) &&
- ($tokens[$i] instanceof PHP_Token_STATIC ||
- $tokens[$i] instanceof PHP_Token_FINAL ||
- $tokens[$i] instanceof PHP_Token_ABSTRACT)) {
- $keywords[] = strtolower(
- str_replace('PHP_Token_', '', PHP_Token_Util::getClass($tokens[$i]))
- );
- }
- }
-
- return implode(',', $keywords);
- }
-}
-
-abstract class PHP_Token_Includes extends PHP_Token
-{
- /**
- * @var string
- */
- protected $name;
-
- /**
- * @var string
- */
- protected $type;
-
- /**
- * @return string
- */
- public function getName()
- {
- if ($this->name === null) {
- $this->process();
- }
-
- return $this->name;
- }
-
- /**
- * @return string
- */
- public function getType()
- {
- if ($this->type === null) {
- $this->process();
- }
-
- return $this->type;
- }
-
- private function process()
- {
- $tokens = $this->tokenStream->tokens();
-
- if ($tokens[$this->id + 2] instanceof PHP_Token_CONSTANT_ENCAPSED_STRING) {
- $this->name = trim($tokens[$this->id + 2], "'\"");
- $this->type = strtolower(
- str_replace('PHP_Token_', '', PHP_Token_Util::getClass($tokens[$this->id]))
- );
- }
- }
-}
-
-class PHP_Token_FUNCTION extends PHP_TokenWithScopeAndVisibility
-{
- /**
- * @var array
- */
- protected $arguments;
-
- /**
- * @var int
- */
- protected $ccn;
-
- /**
- * @var string
- */
- protected $name;
-
- /**
- * @var string
- */
- protected $signature;
-
- /**
- * @var bool
- */
- private $anonymous = false;
-
- /**
- * @return array
- */
- public function getArguments()
- {
- if ($this->arguments !== null) {
- return $this->arguments;
- }
-
- $this->arguments = [];
- $tokens = $this->tokenStream->tokens();
- $typeDeclaration = null;
-
- // Search for first token inside brackets
- $i = $this->id + 2;
-
- while (!$tokens[$i - 1] instanceof PHP_Token_OPEN_BRACKET) {
- $i++;
- }
-
- while (!$tokens[$i] instanceof PHP_Token_CLOSE_BRACKET) {
- if ($tokens[$i] instanceof PHP_Token_STRING) {
- $typeDeclaration = (string) $tokens[$i];
- } elseif ($tokens[$i] instanceof PHP_Token_VARIABLE) {
- $this->arguments[(string) $tokens[$i]] = $typeDeclaration;
- $typeDeclaration = null;
- }
-
- $i++;
- }
-
- return $this->arguments;
- }
-
- /**
- * @return string
- */
- public function getName()
- {
- if ($this->name !== null) {
- return $this->name;
- }
-
- $tokens = $this->tokenStream->tokens();
-
- $i = $this->id + 1;
-
- if ($tokens[$i] instanceof PHP_Token_WHITESPACE) {
- $i++;
- }
-
- if ($tokens[$i] instanceof PHP_Token_AMPERSAND) {
- $i++;
- }
-
- if ($tokens[$i + 1] instanceof PHP_Token_OPEN_BRACKET) {
- $this->name = (string) $tokens[$i];
- } elseif ($tokens[$i + 1] instanceof PHP_Token_WHITESPACE && $tokens[$i + 2] instanceof PHP_Token_OPEN_BRACKET) {
- $this->name = (string) $tokens[$i];
- } else {
- $this->anonymous = true;
-
- $this->name = sprintf(
- 'anonymousFunction:%s#%s',
- $this->getLine(),
- $this->getId()
- );
- }
-
- if (!$this->isAnonymous()) {
- for ($i = $this->id; $i; --$i) {
- if ($tokens[$i] instanceof PHP_Token_NAMESPACE) {
- $this->name = $tokens[$i]->getName() . '\\' . $this->name;
-
- break;
- }
-
- if ($tokens[$i] instanceof PHP_Token_INTERFACE) {
- break;
- }
- }
- }
-
- return $this->name;
- }
-
- /**
- * @return int
- */
- public function getCCN()
- {
- if ($this->ccn !== null) {
- return $this->ccn;
- }
-
- $this->ccn = 1;
- $end = $this->getEndTokenId();
- $tokens = $this->tokenStream->tokens();
-
- for ($i = $this->id; $i <= $end; $i++) {
- switch (PHP_Token_Util::getClass($tokens[$i])) {
- case 'PHP_Token_IF':
- case 'PHP_Token_ELSEIF':
- case 'PHP_Token_FOR':
- case 'PHP_Token_FOREACH':
- case 'PHP_Token_WHILE':
- case 'PHP_Token_CASE':
- case 'PHP_Token_CATCH':
- case 'PHP_Token_BOOLEAN_AND':
- case 'PHP_Token_LOGICAL_AND':
- case 'PHP_Token_BOOLEAN_OR':
- case 'PHP_Token_LOGICAL_OR':
- case 'PHP_Token_QUESTION_MARK':
- $this->ccn++;
- break;
- }
- }
-
- return $this->ccn;
- }
-
- /**
- * @return string
- */
- public function getSignature()
- {
- if ($this->signature !== null) {
- return $this->signature;
- }
-
- if ($this->isAnonymous()) {
- $this->signature = 'anonymousFunction';
- $i = $this->id + 1;
- } else {
- $this->signature = '';
- $i = $this->id + 2;
- }
-
- $tokens = $this->tokenStream->tokens();
-
- while (isset($tokens[$i]) &&
- !$tokens[$i] instanceof PHP_Token_OPEN_CURLY &&
- !$tokens[$i] instanceof PHP_Token_SEMICOLON) {
- $this->signature .= $tokens[$i++];
- }
-
- $this->signature = trim($this->signature);
-
- return $this->signature;
- }
-
- /**
- * @return bool
- */
- public function isAnonymous()
- {
- return $this->anonymous;
- }
-}
-
-class PHP_Token_INTERFACE extends PHP_TokenWithScopeAndVisibility
-{
- /**
- * @var array
- */
- protected $interfaces;
-
- /**
- * @return string
- */
- public function getName()
- {
- return (string) $this->tokenStream[$this->id + 2];
- }
-
- /**
- * @return bool
- */
- public function hasParent()
- {
- return $this->tokenStream[$this->id + 4] instanceof PHP_Token_EXTENDS;
- }
-
- /**
- * @return array
- */
- public function getPackage()
- {
- $className = $this->getName();
- $docComment = $this->getDocblock();
-
- $result = [
- 'namespace' => '',
- 'fullPackage' => '',
- 'category' => '',
- 'package' => '',
- 'subpackage' => ''
- ];
-
- for ($i = $this->id; $i; --$i) {
- if ($this->tokenStream[$i] instanceof PHP_Token_NAMESPACE) {
- $result['namespace'] = $this->tokenStream[$i]->getName();
- break;
- }
- }
-
- if (preg_match('/@category[\s]+([\.\w]+)/', $docComment, $matches)) {
- $result['category'] = $matches[1];
- }
-
- if (preg_match('/@package[\s]+([\.\w]+)/', $docComment, $matches)) {
- $result['package'] = $matches[1];
- $result['fullPackage'] = $matches[1];
- }
-
- if (preg_match('/@subpackage[\s]+([\.\w]+)/', $docComment, $matches)) {
- $result['subpackage'] = $matches[1];
- $result['fullPackage'] .= '.' . $matches[1];
- }
-
- if (empty($result['fullPackage'])) {
- $result['fullPackage'] = $this->arrayToName(
- explode('_', str_replace('\\', '_', $className)),
- '.'
- );
- }
-
- return $result;
- }
-
- /**
- * @param array $parts
- * @param string $join
- *
- * @return string
- */
- protected function arrayToName(array $parts, $join = '\\')
- {
- $result = '';
-
- if (count($parts) > 1) {
- array_pop($parts);
-
- $result = implode($join, $parts);
- }
-
- return $result;
- }
-
- /**
- * @return bool|string
- */
- public function getParent()
- {
- if (!$this->hasParent()) {
- return false;
- }
-
- $i = $this->id + 6;
- $tokens = $this->tokenStream->tokens();
- $className = (string) $tokens[$i];
-
- while (isset($tokens[$i + 1]) &&
- !$tokens[$i + 1] instanceof PHP_Token_WHITESPACE) {
- $className .= (string) $tokens[++$i];
- }
-
- return $className;
- }
-
- /**
- * @return bool
- */
- public function hasInterfaces()
- {
- return (isset($this->tokenStream[$this->id + 4]) &&
- $this->tokenStream[$this->id + 4] instanceof PHP_Token_IMPLEMENTS) ||
- (isset($this->tokenStream[$this->id + 8]) &&
- $this->tokenStream[$this->id + 8] instanceof PHP_Token_IMPLEMENTS);
- }
-
- /**
- * @return array|bool
- */
- public function getInterfaces()
- {
- if ($this->interfaces !== null) {
- return $this->interfaces;
- }
-
- if (!$this->hasInterfaces()) {
- return ($this->interfaces = false);
- }
-
- if ($this->tokenStream[$this->id + 4] instanceof PHP_Token_IMPLEMENTS) {
- $i = $this->id + 3;
- } else {
- $i = $this->id + 7;
- }
-
- $tokens = $this->tokenStream->tokens();
-
- while (!$tokens[$i + 1] instanceof PHP_Token_OPEN_CURLY) {
- $i++;
-
- if ($tokens[$i] instanceof PHP_Token_STRING) {
- $this->interfaces[] = (string) $tokens[$i];
- }
- }
-
- return $this->interfaces;
- }
-}
-
-class PHP_Token_ABSTRACT extends PHP_Token
-{
-}
-
-class PHP_Token_AMPERSAND extends PHP_Token
-{
-}
-
-class PHP_Token_AND_EQUAL extends PHP_Token
-{
-}
-
-class PHP_Token_ARRAY extends PHP_Token
-{
-}
-
-class PHP_Token_ARRAY_CAST extends PHP_Token
-{
-}
-
-class PHP_Token_AS extends PHP_Token
-{
-}
-
-class PHP_Token_AT extends PHP_Token
-{
-}
-
-class PHP_Token_BACKTICK extends PHP_Token
-{
-}
-
-class PHP_Token_BAD_CHARACTER extends PHP_Token
-{
-}
-
-class PHP_Token_BOOLEAN_AND extends PHP_Token
-{
-}
-
-class PHP_Token_BOOLEAN_OR extends PHP_Token
-{
-}
-
-class PHP_Token_BOOL_CAST extends PHP_Token
-{
-}
-
-class PHP_Token_BREAK extends PHP_Token
-{
-}
-
-class PHP_Token_CARET extends PHP_Token
-{
-}
-
-class PHP_Token_CASE extends PHP_Token
-{
-}
-
-class PHP_Token_CATCH extends PHP_Token
-{
-}
-
-class PHP_Token_CHARACTER extends PHP_Token
-{
-}
-
-class PHP_Token_CLASS extends PHP_Token_INTERFACE
-{
- /**
- * @var bool
- */
- private $anonymous = false;
-
- /**
- * @var string
- */
- private $name;
-
- /**
- * @return string
- */
- public function getName()
- {
- if ($this->name !== null) {
- return $this->name;
- }
-
- $next = $this->tokenStream[$this->id + 1];
-
- if ($next instanceof PHP_Token_WHITESPACE) {
- $next = $this->tokenStream[$this->id + 2];
- }
-
- if ($next instanceof PHP_Token_STRING) {
- $this->name =(string) $next;
-
- return $this->name;
- }
-
- if ($next instanceof PHP_Token_OPEN_CURLY ||
- $next instanceof PHP_Token_EXTENDS ||
- $next instanceof PHP_Token_IMPLEMENTS) {
-
- $this->name = sprintf(
- 'AnonymousClass:%s#%s',
- $this->getLine(),
- $this->getId()
- );
-
- $this->anonymous = true;
-
- return $this->name;
- }
- }
-
- public function isAnonymous()
- {
- return $this->anonymous;
- }
-}
-
-class PHP_Token_CLASS_C extends PHP_Token
-{
-}
-
-class PHP_Token_CLASS_NAME_CONSTANT extends PHP_Token
-{
-}
-
-class PHP_Token_CLONE extends PHP_Token
-{
-}
-
-class PHP_Token_CLOSE_BRACKET extends PHP_Token
-{
-}
-
-class PHP_Token_CLOSE_CURLY extends PHP_Token
-{
-}
-
-class PHP_Token_CLOSE_SQUARE extends PHP_Token
-{
-}
-
-class PHP_Token_CLOSE_TAG extends PHP_Token
-{
-}
-
-class PHP_Token_COLON extends PHP_Token
-{
-}
-
-class PHP_Token_COMMA extends PHP_Token
-{
-}
-
-class PHP_Token_COMMENT extends PHP_Token
-{
-}
-
-class PHP_Token_CONCAT_EQUAL extends PHP_Token
-{
-}
-
-class PHP_Token_CONST extends PHP_Token
-{
-}
-
-class PHP_Token_CONSTANT_ENCAPSED_STRING extends PHP_Token
-{
-}
-
-class PHP_Token_CONTINUE extends PHP_Token
-{
-}
-
-class PHP_Token_CURLY_OPEN extends PHP_Token
-{
-}
-
-class PHP_Token_DEC extends PHP_Token
-{
-}
-
-class PHP_Token_DECLARE extends PHP_Token
-{
-}
-
-class PHP_Token_DEFAULT extends PHP_Token
-{
-}
-
-class PHP_Token_DIV extends PHP_Token
-{
-}
-
-class PHP_Token_DIV_EQUAL extends PHP_Token
-{
-}
-
-class PHP_Token_DNUMBER extends PHP_Token
-{
-}
-
-class PHP_Token_DO extends PHP_Token
-{
-}
-
-class PHP_Token_DOC_COMMENT extends PHP_Token
-{
-}
-
-class PHP_Token_DOLLAR extends PHP_Token
-{
-}
-
-class PHP_Token_DOLLAR_OPEN_CURLY_BRACES extends PHP_Token
-{
-}
-
-class PHP_Token_DOT extends PHP_Token
-{
-}
-
-class PHP_Token_DOUBLE_ARROW extends PHP_Token
-{
-}
-
-class PHP_Token_DOUBLE_CAST extends PHP_Token
-{
-}
-
-class PHP_Token_DOUBLE_COLON extends PHP_Token
-{
-}
-
-class PHP_Token_DOUBLE_QUOTES extends PHP_Token
-{
-}
-
-class PHP_Token_ECHO extends PHP_Token
-{
-}
-
-class PHP_Token_ELSE extends PHP_Token
-{
-}
-
-class PHP_Token_ELSEIF extends PHP_Token
-{
-}
-
-class PHP_Token_EMPTY extends PHP_Token
-{
-}
-
-class PHP_Token_ENCAPSED_AND_WHITESPACE extends PHP_Token
-{
-}
-
-class PHP_Token_ENDDECLARE extends PHP_Token
-{
-}
-
-class PHP_Token_ENDFOR extends PHP_Token
-{
-}
-
-class PHP_Token_ENDFOREACH extends PHP_Token
-{
-}
-
-class PHP_Token_ENDIF extends PHP_Token
-{
-}
-
-class PHP_Token_ENDSWITCH extends PHP_Token
-{
-}
-
-class PHP_Token_ENDWHILE extends PHP_Token
-{
-}
-
-class PHP_Token_END_HEREDOC extends PHP_Token
-{
-}
-
-class PHP_Token_EQUAL extends PHP_Token
-{
-}
-
-class PHP_Token_EVAL extends PHP_Token
-{
-}
-
-class PHP_Token_EXCLAMATION_MARK extends PHP_Token
-{
-}
-
-class PHP_Token_EXIT extends PHP_Token
-{
-}
-
-class PHP_Token_EXTENDS extends PHP_Token
-{
-}
-
-class PHP_Token_FILE extends PHP_Token
-{
-}
-
-class PHP_Token_FINAL extends PHP_Token
-{
-}
-
-class PHP_Token_FOR extends PHP_Token
-{
-}
-
-class PHP_Token_FOREACH extends PHP_Token
-{
-}
-
-class PHP_Token_FUNC_C extends PHP_Token
-{
-}
-
-class PHP_Token_GLOBAL extends PHP_Token
-{
-}
-
-class PHP_Token_GT extends PHP_Token
-{
-}
-
-class PHP_Token_IF extends PHP_Token
-{
-}
-
-class PHP_Token_IMPLEMENTS extends PHP_Token
-{
-}
-
-class PHP_Token_INC extends PHP_Token
-{
-}
-
-class PHP_Token_INCLUDE extends PHP_Token_Includes
-{
-}
-
-class PHP_Token_INCLUDE_ONCE extends PHP_Token_Includes
-{
-}
-
-class PHP_Token_INLINE_HTML extends PHP_Token
-{
-}
-
-class PHP_Token_INSTANCEOF extends PHP_Token
-{
-}
-
-class PHP_Token_INT_CAST extends PHP_Token
-{
-}
-
-class PHP_Token_ISSET extends PHP_Token
-{
-}
-
-class PHP_Token_IS_EQUAL extends PHP_Token
-{
-}
-
-class PHP_Token_IS_GREATER_OR_EQUAL extends PHP_Token
-{
-}
-
-class PHP_Token_IS_IDENTICAL extends PHP_Token
-{
-}
-
-class PHP_Token_IS_NOT_EQUAL extends PHP_Token
-{
-}
-
-class PHP_Token_IS_NOT_IDENTICAL extends PHP_Token
-{
-}
-
-class PHP_Token_IS_SMALLER_OR_EQUAL extends PHP_Token
-{
-}
-
-class PHP_Token_LINE extends PHP_Token
-{
-}
-
-class PHP_Token_LIST extends PHP_Token
-{
-}
-
-class PHP_Token_LNUMBER extends PHP_Token
-{
-}
-
-class PHP_Token_LOGICAL_AND extends PHP_Token
-{
-}
-
-class PHP_Token_LOGICAL_OR extends PHP_Token
-{
-}
-
-class PHP_Token_LOGICAL_XOR extends PHP_Token
-{
-}
-
-class PHP_Token_LT extends PHP_Token
-{
-}
-
-class PHP_Token_METHOD_C extends PHP_Token
-{
-}
-
-class PHP_Token_MINUS extends PHP_Token
-{
-}
-
-class PHP_Token_MINUS_EQUAL extends PHP_Token
-{
-}
-
-class PHP_Token_MOD_EQUAL extends PHP_Token
-{
-}
-
-class PHP_Token_MULT extends PHP_Token
-{
-}
-
-class PHP_Token_MUL_EQUAL extends PHP_Token
-{
-}
-
-class PHP_Token_NEW extends PHP_Token
-{
-}
-
-class PHP_Token_NUM_STRING extends PHP_Token
-{
-}
-
-class PHP_Token_OBJECT_CAST extends PHP_Token
-{
-}
-
-class PHP_Token_OBJECT_OPERATOR extends PHP_Token
-{
-}
-
-class PHP_Token_OPEN_BRACKET extends PHP_Token
-{
-}
-
-class PHP_Token_OPEN_CURLY extends PHP_Token
-{
-}
-
-class PHP_Token_OPEN_SQUARE extends PHP_Token
-{
-}
-
-class PHP_Token_OPEN_TAG extends PHP_Token
-{
-}
-
-class PHP_Token_OPEN_TAG_WITH_ECHO extends PHP_Token
-{
-}
-
-class PHP_Token_OR_EQUAL extends PHP_Token
-{
-}
-
-class PHP_Token_PAAMAYIM_NEKUDOTAYIM extends PHP_Token
-{
-}
-
-class PHP_Token_PERCENT extends PHP_Token
-{
-}
-
-class PHP_Token_PIPE extends PHP_Token
-{
-}
-
-class PHP_Token_PLUS extends PHP_Token
-{
-}
-
-class PHP_Token_PLUS_EQUAL extends PHP_Token
-{
-}
-
-class PHP_Token_PRINT extends PHP_Token
-{
-}
-
-class PHP_Token_PRIVATE extends PHP_Token
-{
-}
-
-class PHP_Token_PROTECTED extends PHP_Token
-{
-}
-
-class PHP_Token_PUBLIC extends PHP_Token
-{
-}
-
-class PHP_Token_QUESTION_MARK extends PHP_Token
-{
-}
-
-class PHP_Token_REQUIRE extends PHP_Token_Includes
-{
-}
-
-class PHP_Token_REQUIRE_ONCE extends PHP_Token_Includes
-{
-}
-
-class PHP_Token_RETURN extends PHP_Token
-{
-}
-
-class PHP_Token_SEMICOLON extends PHP_Token
-{
-}
-
-class PHP_Token_SL extends PHP_Token
-{
-}
-
-class PHP_Token_SL_EQUAL extends PHP_Token
-{
-}
-
-class PHP_Token_SR extends PHP_Token
-{
-}
-
-class PHP_Token_SR_EQUAL extends PHP_Token
-{
-}
-
-class PHP_Token_START_HEREDOC extends PHP_Token
-{
-}
-
-class PHP_Token_STATIC extends PHP_Token
-{
-}
-
-class PHP_Token_STRING extends PHP_Token
-{
-}
-
-class PHP_Token_STRING_CAST extends PHP_Token
-{
-}
-
-class PHP_Token_STRING_VARNAME extends PHP_Token
-{
-}
-
-class PHP_Token_SWITCH extends PHP_Token
-{
-}
-
-class PHP_Token_THROW extends PHP_Token
-{
-}
-
-class PHP_Token_TILDE extends PHP_Token
-{
-}
-
-class PHP_Token_TRY extends PHP_Token
-{
-}
-
-class PHP_Token_UNSET extends PHP_Token
-{
-}
-
-class PHP_Token_UNSET_CAST extends PHP_Token
-{
-}
-
-class PHP_Token_USE extends PHP_Token
-{
-}
-
-class PHP_Token_USE_FUNCTION extends PHP_Token
-{
-}
-
-class PHP_Token_VAR extends PHP_Token
-{
-}
-
-class PHP_Token_VARIABLE extends PHP_Token
-{
-}
-
-class PHP_Token_WHILE extends PHP_Token
-{
-}
-
-class PHP_Token_WHITESPACE extends PHP_Token
-{
-}
-
-class PHP_Token_XOR_EQUAL extends PHP_Token
-{
-}
-
-// Tokens introduced in PHP 5.1
-class PHP_Token_HALT_COMPILER extends PHP_Token
-{
-}
-
-// Tokens introduced in PHP 5.3
-class PHP_Token_DIR extends PHP_Token
-{
-}
-
-class PHP_Token_GOTO extends PHP_Token
-{
-}
-
-class PHP_Token_NAMESPACE extends PHP_TokenWithScope
-{
- /**
- * @return string
- */
- public function getName()
- {
- $tokens = $this->tokenStream->tokens();
- $namespace = (string) $tokens[$this->id + 2];
-
- for ($i = $this->id + 3;; $i += 2) {
- if (isset($tokens[$i]) &&
- $tokens[$i] instanceof PHP_Token_NS_SEPARATOR) {
- $namespace .= '\\' . $tokens[$i + 1];
- } else {
- break;
- }
- }
-
- return $namespace;
- }
-}
-
-class PHP_Token_NS_C extends PHP_Token
-{
-}
-
-class PHP_Token_NS_SEPARATOR extends PHP_Token
-{
-}
-
-// Tokens introduced in PHP 5.4
-class PHP_Token_CALLABLE extends PHP_Token
-{
-}
-
-class PHP_Token_INSTEADOF extends PHP_Token
-{
-}
-
-class PHP_Token_TRAIT extends PHP_Token_INTERFACE
-{
-}
-
-class PHP_Token_TRAIT_C extends PHP_Token
-{
-}
-
-// Tokens introduced in PHP 5.5
-class PHP_Token_FINALLY extends PHP_Token
-{
-}
-
-class PHP_Token_YIELD extends PHP_Token
-{
-}
-
-// Tokens introduced in PHP 5.6
-class PHP_Token_ELLIPSIS extends PHP_Token
-{
-}
-
-class PHP_Token_POW extends PHP_Token
-{
-}
-
-class PHP_Token_POW_EQUAL extends PHP_Token
-{
-}
-
-// Tokens introduced in PHP 7.0
-class PHP_Token_COALESCE extends PHP_Token
-{
-}
-
-class PHP_Token_SPACESHIP extends PHP_Token
-{
-}
-
-class PHP_Token_YIELD_FROM extends PHP_Token
-{
-}
-
-// Tokens introduced in PHP 7.4
-class PHP_Token_COALESCE_EQUAL extends PHP_Token
-{
-}
-
-class PHP_Token_FN extends PHP_Token
-{
-}
diff --git a/vendor/phpunit/php-token-stream/src/TokenWithScope.php b/vendor/phpunit/php-token-stream/src/TokenWithScope.php
new file mode 100644
index 000000000..876b3508b
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/TokenWithScope.php
@@ -0,0 +1,107 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+abstract class PHP_TokenWithScope extends PHP_Token
+{
+ /**
+ * @var int
+ */
+ protected $endTokenId;
+
+ /**
+ * Get the docblock for this token.
+ *
+ * This method will fetch the docblock belonging to the current token. The
+ * docblock must be placed on the line directly above the token to be
+ * recognized.
+ *
+ * @return null|string Returns the docblock as a string if found
+ */
+ public function getDocblock()
+ {
+ $tokens = $this->tokenStream->tokens();
+ $currentLineNumber = $tokens[$this->id]->getLine();
+ $prevLineNumber = $currentLineNumber - 1;
+
+ for ($i = $this->id - 1; $i; $i--) {
+ if (!isset($tokens[$i])) {
+ return;
+ }
+
+ if ($tokens[$i] instanceof PHP_Token_FUNCTION ||
+ $tokens[$i] instanceof PHP_Token_CLASS ||
+ $tokens[$i] instanceof PHP_Token_TRAIT) {
+ // Some other trait, class or function, no docblock can be
+ // used for the current token
+ break;
+ }
+
+ $line = $tokens[$i]->getLine();
+
+ if ($line == $currentLineNumber ||
+ ($line == $prevLineNumber &&
+ $tokens[$i] instanceof PHP_Token_WHITESPACE)) {
+ continue;
+ }
+
+ if ($line < $currentLineNumber &&
+ !$tokens[$i] instanceof PHP_Token_DOC_COMMENT) {
+ break;
+ }
+
+ return (string) $tokens[$i];
+ }
+ }
+
+ /**
+ * @return int
+ */
+ public function getEndTokenId()
+ {
+ $block = 0;
+ $i = $this->id;
+ $tokens = $this->tokenStream->tokens();
+
+ while ($this->endTokenId === null && isset($tokens[$i])) {
+ if ($tokens[$i] instanceof PHP_Token_OPEN_CURLY ||
+ $tokens[$i] instanceof PHP_Token_DOLLAR_OPEN_CURLY_BRACES ||
+ $tokens[$i] instanceof PHP_Token_CURLY_OPEN) {
+ $block++;
+ } elseif ($tokens[$i] instanceof PHP_Token_CLOSE_CURLY) {
+ $block--;
+
+ if ($block === 0) {
+ $this->endTokenId = $i;
+ }
+ } elseif (($this instanceof PHP_Token_FUNCTION ||
+ $this instanceof PHP_Token_NAMESPACE) &&
+ $tokens[$i] instanceof PHP_Token_SEMICOLON) {
+ if ($block === 0) {
+ $this->endTokenId = $i;
+ }
+ }
+
+ $i++;
+ }
+
+ if ($this->endTokenId === null) {
+ $this->endTokenId = $this->id;
+ }
+
+ return $this->endTokenId;
+ }
+
+ /**
+ * @return int
+ */
+ public function getEndLine()
+ {
+ return $this->tokenStream[$this->getEndTokenId()]->getLine();
+ }
+}
diff --git a/vendor/phpunit/php-token-stream/src/TokenWithScopeAndVisibility.php b/vendor/phpunit/php-token-stream/src/TokenWithScopeAndVisibility.php
new file mode 100644
index 000000000..fce0c8ea2
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/TokenWithScopeAndVisibility.php
@@ -0,0 +1,67 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+abstract class PHP_TokenWithScopeAndVisibility extends PHP_TokenWithScope
+{
+ /**
+ * @return string
+ */
+ public function getVisibility()
+ {
+ $tokens = $this->tokenStream->tokens();
+
+ for ($i = $this->id - 2; $i > $this->id - 7; $i -= 2) {
+ if (isset($tokens[$i]) &&
+ ($tokens[$i] instanceof PHP_Token_PRIVATE ||
+ $tokens[$i] instanceof PHP_Token_PROTECTED ||
+ $tokens[$i] instanceof PHP_Token_PUBLIC)) {
+ return \strtolower(
+ \str_replace('PHP_Token_', '', PHP_Token_Util::getClass($tokens[$i]))
+ );
+ }
+
+ if (isset($tokens[$i]) &&
+ !($tokens[$i] instanceof PHP_Token_STATIC ||
+ $tokens[$i] instanceof PHP_Token_FINAL ||
+ $tokens[$i] instanceof PHP_Token_ABSTRACT)) {
+ // no keywords; stop visibility search
+ break;
+ }
+ }
+ }
+
+ /**
+ * @return string
+ */
+ public function getKeywords()
+ {
+ $keywords = [];
+ $tokens = $this->tokenStream->tokens();
+
+ for ($i = $this->id - 2; $i > $this->id - 7; $i -= 2) {
+ if (isset($tokens[$i]) &&
+ ($tokens[$i] instanceof PHP_Token_PRIVATE ||
+ $tokens[$i] instanceof PHP_Token_PROTECTED ||
+ $tokens[$i] instanceof PHP_Token_PUBLIC)) {
+ continue;
+ }
+
+ if (isset($tokens[$i]) &&
+ ($tokens[$i] instanceof PHP_Token_STATIC ||
+ $tokens[$i] instanceof PHP_Token_FINAL ||
+ $tokens[$i] instanceof PHP_Token_ABSTRACT)) {
+ $keywords[] = \strtolower(
+ \str_replace('PHP_Token_', '', PHP_Token_Util::getClass($tokens[$i]))
+ );
+ }
+ }
+
+ return \implode(',', $keywords);
+ }
+}
diff --git a/vendor/phpunit/php-token-stream/src/Trait.php b/vendor/phpunit/php-token-stream/src/Trait.php
new file mode 100644
index 000000000..f635f5dfb
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Trait.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_TRAIT extends PHP_Token_INTERFACE
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/TraitC.php b/vendor/phpunit/php-token-stream/src/TraitC.php
new file mode 100644
index 000000000..ae4b2a5ae
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/TraitC.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_TRAIT_C extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Try.php b/vendor/phpunit/php-token-stream/src/Try.php
new file mode 100644
index 000000000..8c3783e89
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Try.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_TRY extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Unset.php b/vendor/phpunit/php-token-stream/src/Unset.php
new file mode 100644
index 000000000..3d39d0b68
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Unset.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_UNSET extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/UnsetCast.php b/vendor/phpunit/php-token-stream/src/UnsetCast.php
new file mode 100644
index 000000000..133ef29fc
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/UnsetCast.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_UNSET_CAST extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Use.php b/vendor/phpunit/php-token-stream/src/Use.php
new file mode 100644
index 000000000..e62a54972
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Use.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_USE extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/UseFunction.php b/vendor/phpunit/php-token-stream/src/UseFunction.php
new file mode 100644
index 000000000..8250864a9
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/UseFunction.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_USE_FUNCTION extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Token/Util.php b/vendor/phpunit/php-token-stream/src/Util.php
similarity index 69%
rename from vendor/phpunit/php-token-stream/src/Token/Util.php
rename to vendor/phpunit/php-token-stream/src/Util.php
index 4d82f1a83..13b636c21 100644
--- a/vendor/phpunit/php-token-stream/src/Token/Util.php
+++ b/vendor/phpunit/php-token-stream/src/Util.php
@@ -1,19 +1,18 @@
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
-
final class PHP_Token_Util
{
public static function getClass($object): string
{
- $parts = explode('\\', get_class($object));
+ $parts = \explode('\\', \get_class($object));
- return array_pop($parts);
+ return \array_pop($parts);
}
-}
\ No newline at end of file
+}
diff --git a/vendor/phpunit/php-token-stream/src/Var.php b/vendor/phpunit/php-token-stream/src/Var.php
new file mode 100644
index 000000000..3dbd16ff2
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Var.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_VAR extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Variable.php b/vendor/phpunit/php-token-stream/src/Variable.php
new file mode 100644
index 000000000..921e3ae85
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Variable.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_VARIABLE extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/While.php b/vendor/phpunit/php-token-stream/src/While.php
new file mode 100644
index 000000000..e92409fff
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/While.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_WHILE extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Whitespace.php b/vendor/phpunit/php-token-stream/src/Whitespace.php
new file mode 100644
index 000000000..6b5b641ca
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Whitespace.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_WHITESPACE extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/XorEqual.php b/vendor/phpunit/php-token-stream/src/XorEqual.php
new file mode 100644
index 000000000..0095b283e
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/XorEqual.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_XOR_EQUAL extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Yield.php b/vendor/phpunit/php-token-stream/src/Yield.php
new file mode 100644
index 000000000..3fecb6c10
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Yield.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_YIELD extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/YieldFrom.php b/vendor/phpunit/php-token-stream/src/YieldFrom.php
new file mode 100644
index 000000000..8f1a71680
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/YieldFrom.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_YIELD_FROM extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/break.php b/vendor/phpunit/php-token-stream/src/break.php
new file mode 100644
index 000000000..97e96fee4
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/break.php
@@ -0,0 +1,12 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class PHP_Token_BREAK extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/tests/Token/ClassTest.php b/vendor/phpunit/php-token-stream/tests/Token/ClassTest.php
deleted file mode 100644
index 05eca32f2..000000000
--- a/vendor/phpunit/php-token-stream/tests/Token/ClassTest.php
+++ /dev/null
@@ -1,152 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-use PHPUnit\Framework\TestCase;
-
-class PHP_Token_ClassTest extends TestCase
-{
- /**
- * @var PHP_Token_CLASS
- */
- private $class;
-
- /**
- * @var PHP_Token_FUNCTION
- */
- private $function;
-
- protected function setUp()
- {
- foreach (new PHP_Token_Stream(TEST_FILES_PATH . 'source2.php') as $token) {
- if ($token instanceof PHP_Token_CLASS) {
- $this->class = $token;
- }
-
- if ($token instanceof PHP_Token_FUNCTION) {
- $this->function = $token;
- break;
- }
- }
- }
-
- public function testGetClassKeywords()
- {
- $this->assertEquals('abstract', $this->class->getKeywords());
- }
-
- public function testGetFunctionKeywords()
- {
- $this->assertEquals('abstract,static', $this->function->getKeywords());
- }
-
- public function testGetFunctionVisibility()
- {
- $this->assertEquals('public', $this->function->getVisibility());
- }
-
- public function testIssue19()
- {
- foreach (new PHP_Token_Stream(TEST_FILES_PATH . 'issue19.php') as $token) {
- if ($token instanceof PHP_Token_CLASS) {
- $this->assertFalse($token->hasInterfaces());
- }
- }
- }
-
- public function testIssue30()
- {
- $ts = new PHP_Token_Stream(TEST_FILES_PATH . 'issue30.php');
- $this->assertCount(1, $ts->getClasses());
- }
-
- public function testAnonymousClassesAreHandledCorrectly()
- {
- $ts = new PHP_Token_Stream(TEST_FILES_PATH . 'class_with_method_that_declares_anonymous_class.php');
-
- $classes = $ts->getClasses();
-
- $this->assertEquals(
- [
- 'class_with_method_that_declares_anonymous_class',
- 'AnonymousClass:9#31',
- 'AnonymousClass:10#55',
- 'AnonymousClass:11#75',
- 'AnonymousClass:12#91',
- 'AnonymousClass:13#107'
- ],
- array_keys($classes)
- );
- }
-
- /**
- * @ticket https://github.com/sebastianbergmann/php-token-stream/issues/52
- */
- public function testAnonymousClassesAreHandledCorrectly2()
- {
- $ts = new PHP_Token_Stream(TEST_FILES_PATH . 'class_with_method_that_declares_anonymous_class2.php');
-
- $classes = $ts->getClasses();
-
- $this->assertEquals(['Test', 'AnonymousClass:4#23'], array_keys($classes));
- $this->assertEquals(['methodOne', 'methodTwo'], array_keys($classes['Test']['methods']));
-
- $this->assertEmpty($ts->getFunctions());
- }
-
- public function testImportedFunctionsAreHandledCorrectly()
- {
- $ts = new PHP_Token_Stream(TEST_FILES_PATH . 'classUsesNamespacedFunction.php');
-
- $this->assertEmpty($ts->getFunctions());
- $this->assertCount(1, $ts->getClasses());
- }
-
- /**
- * @ticket https://github.com/sebastianbergmann/php-code-coverage/issues/543
- */
- public function testClassWithMultipleAnonymousClassesAndFunctionsIsHandledCorrectly()
- {
- $ts = new PHP_Token_Stream(TEST_FILES_PATH . 'class_with_multiple_anonymous_classes_and_functions.php');
-
- $classes = $ts->getClasses();
-
- $this->assertArrayHasKey('class_with_multiple_anonymous_classes_and_functions', $classes);
- $this->assertArrayHasKey('AnonymousClass:6#23', $classes);
- $this->assertArrayHasKey('AnonymousClass:12#53', $classes);
- $this->assertArrayHasKey('m', $classes['class_with_multiple_anonymous_classes_and_functions']['methods']);
- $this->assertArrayHasKey('anonymousFunction:18#81', $classes['class_with_multiple_anonymous_classes_and_functions']['methods']);
- $this->assertArrayHasKey('anonymousFunction:22#108', $classes['class_with_multiple_anonymous_classes_and_functions']['methods']);
- }
-
- /**
- * @ticket https://github.com/sebastianbergmann/php-token-stream/issues/68
- */
- public function testClassWithMethodNamedEmptyIsHandledCorrectly()
- {
- $classes = (new PHP_Token_Stream(TEST_FILES_PATH . 'class_with_method_named_empty.php'))->getClasses();
-
- $this->assertArrayHasKey('class_with_method_named_empty', $classes);
- $this->assertArrayHasKey('empty', $classes['class_with_method_named_empty']['methods']);
- }
-
- /**
- * @ticket https://github.com/sebastianbergmann/php-code-coverage/issues/424
- */
- public function testAnonymousFunctionDoesNotAffectStartAndEndLineOfMethod()
- {
- $classes = (new PHP_Token_Stream(TEST_FILES_PATH . 'php-code-coverage-issue-424.php'))->getClasses();
-
- $this->assertSame(5, $classes['Example']['methods']['even']['startLine']);
- $this->assertSame(12, $classes['Example']['methods']['even']['endLine']);
-
- $this->assertSame(7, $classes['Example']['methods']['anonymousFunction:7#28']['startLine']);
- $this->assertSame(9, $classes['Example']['methods']['anonymousFunction:7#28']['endLine']);
- }
-}
diff --git a/vendor/phpunit/php-token-stream/tests/Token/ClosureTest.php b/vendor/phpunit/php-token-stream/tests/Token/ClosureTest.php
deleted file mode 100644
index 4e893d8d1..000000000
--- a/vendor/phpunit/php-token-stream/tests/Token/ClosureTest.php
+++ /dev/null
@@ -1,64 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-use PHPUnit\Framework\TestCase;
-
-class PHP_Token_ClosureTest extends TestCase
-{
- /**
- * @var PHP_Token_FUNCTION[]
- */
- private $functions;
-
- protected function setUp()
- {
- foreach (new PHP_Token_Stream(TEST_FILES_PATH . 'closure.php') as $token) {
- if ($token instanceof PHP_Token_FUNCTION) {
- $this->functions[] = $token;
- }
- }
- }
-
- public function testGetArguments()
- {
- $this->assertEquals(['$foo' => null, '$bar' => null], $this->functions[0]->getArguments());
- $this->assertEquals(['$foo' => 'Foo', '$bar' => null], $this->functions[1]->getArguments());
- $this->assertEquals(['$foo' => null, '$bar' => null, '$baz' => null], $this->functions[2]->getArguments());
- $this->assertEquals(['$foo' => 'Foo', '$bar' => null, '$baz' => null], $this->functions[3]->getArguments());
- $this->assertEquals([], $this->functions[4]->getArguments());
- $this->assertEquals([], $this->functions[5]->getArguments());
- }
-
- public function testGetName()
- {
- $this->assertEquals('anonymousFunction:2#5', $this->functions[0]->getName());
- $this->assertEquals('anonymousFunction:3#27', $this->functions[1]->getName());
- $this->assertEquals('anonymousFunction:4#51', $this->functions[2]->getName());
- $this->assertEquals('anonymousFunction:5#71', $this->functions[3]->getName());
- $this->assertEquals('anonymousFunction:6#93', $this->functions[4]->getName());
- $this->assertEquals('anonymousFunction:7#106', $this->functions[5]->getName());
- }
-
- public function testGetLine()
- {
- $this->assertEquals(2, $this->functions[0]->getLine());
- $this->assertEquals(3, $this->functions[1]->getLine());
- $this->assertEquals(4, $this->functions[2]->getLine());
- $this->assertEquals(5, $this->functions[3]->getLine());
- }
-
- public function testGetEndLine()
- {
- $this->assertEquals(2, $this->functions[0]->getLine());
- $this->assertEquals(3, $this->functions[1]->getLine());
- $this->assertEquals(4, $this->functions[2]->getLine());
- $this->assertEquals(5, $this->functions[3]->getLine());
- }
-}
diff --git a/vendor/phpunit/php-token-stream/tests/Token/FunctionTest.php b/vendor/phpunit/php-token-stream/tests/Token/FunctionTest.php
deleted file mode 100644
index c88454b9c..000000000
--- a/vendor/phpunit/php-token-stream/tests/Token/FunctionTest.php
+++ /dev/null
@@ -1,124 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-use PHPUnit\Framework\TestCase;
-
-class PHP_Token_FunctionTest extends TestCase
-{
- /**
- * @var PHP_Token_FUNCTION[]
- */
- private $functions;
-
- protected function setUp()
- {
- foreach (new PHP_Token_Stream(TEST_FILES_PATH . 'source.php') as $token) {
- if ($token instanceof PHP_Token_FUNCTION) {
- $this->functions[] = $token;
- }
- }
- }
-
- public function testGetArguments()
- {
- $this->assertEquals([], $this->functions[0]->getArguments());
-
- $this->assertEquals(
- ['$baz' => 'Baz'], $this->functions[1]->getArguments()
- );
-
- $this->assertEquals(
- ['$foobar' => 'Foobar'], $this->functions[2]->getArguments()
- );
-
- $this->assertEquals(
- ['$barfoo' => 'Barfoo'], $this->functions[3]->getArguments()
- );
-
- $this->assertEquals([], $this->functions[4]->getArguments());
-
- $this->assertEquals(['$x' => null, '$y' => null], $this->functions[5]->getArguments());
- }
-
- public function testGetName()
- {
- $this->assertEquals('foo', $this->functions[0]->getName());
- $this->assertEquals('bar', $this->functions[1]->getName());
- $this->assertEquals('foobar', $this->functions[2]->getName());
- $this->assertEquals('barfoo', $this->functions[3]->getName());
- $this->assertEquals('baz', $this->functions[4]->getName());
- }
-
- public function testGetLine()
- {
- $this->assertEquals(5, $this->functions[0]->getLine());
- $this->assertEquals(10, $this->functions[1]->getLine());
- $this->assertEquals(17, $this->functions[2]->getLine());
- $this->assertEquals(21, $this->functions[3]->getLine());
- $this->assertEquals(29, $this->functions[4]->getLine());
- $this->assertEquals(37, $this->functions[6]->getLine());
- }
-
- public function testGetEndLine()
- {
- $this->assertEquals(5, $this->functions[0]->getEndLine());
- $this->assertEquals(12, $this->functions[1]->getEndLine());
- $this->assertEquals(19, $this->functions[2]->getEndLine());
- $this->assertEquals(23, $this->functions[3]->getEndLine());
- $this->assertEquals(31, $this->functions[4]->getEndLine());
- $this->assertEquals(41, $this->functions[6]->getEndLine());
- }
-
- public function testGetDocblock()
- {
- $this->assertNull($this->functions[0]->getDocblock());
-
- $this->assertEquals(
- "/**\n * @param Baz \$baz\n */",
- $this->functions[1]->getDocblock()
- );
-
- $this->assertEquals(
- "/**\n * @param Foobar \$foobar\n */",
- $this->functions[2]->getDocblock()
- );
-
- $this->assertNull($this->functions[3]->getDocblock());
- $this->assertNull($this->functions[4]->getDocblock());
- }
-
- public function testSignature()
- {
- $tokens = new PHP_Token_Stream(TEST_FILES_PATH . 'source5.php');
- $functions = $tokens->getFunctions();
- $classes = $tokens->getClasses();
- $interfaces = $tokens->getInterfaces();
-
- $this->assertEquals(
- 'foo($a, array $b, array $c = array())',
- $functions['foo']['signature']
- );
-
- $this->assertEquals(
- 'm($a, array $b, array $c = array())',
- $classes['c']['methods']['m']['signature']
- );
-
- $this->assertEquals(
- 'm($a, array $b, array $c = array())',
- $classes['a']['methods']['m']['signature']
- );
-
- $this->assertEquals(
- 'm($a, array $b, array $c = array())',
- $interfaces['i']['methods']['m']['signature']
- );
- }
-}
diff --git a/vendor/phpunit/php-token-stream/tests/Token/IncludeTest.php b/vendor/phpunit/php-token-stream/tests/Token/IncludeTest.php
deleted file mode 100644
index 7f83a7360..000000000
--- a/vendor/phpunit/php-token-stream/tests/Token/IncludeTest.php
+++ /dev/null
@@ -1,53 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-use PHPUnit\Framework\TestCase;
-
-class PHP_Token_IncludeTest extends TestCase
-{
- /**
- * @var PHP_Token_Stream
- */
- private $ts;
-
- protected function setUp()
- {
- $this->ts = new PHP_Token_Stream(TEST_FILES_PATH . 'source3.php');
- }
-
- public function testGetIncludes()
- {
- $this->assertSame(
- ['test4.php', 'test3.php', 'test2.php', 'test1.php'],
- $this->ts->getIncludes()
- );
- }
-
- public function testGetIncludesCategorized()
- {
- $this->assertSame(
- [
- 'require_once' => ['test4.php'],
- 'require' => ['test3.php'],
- 'include_once' => ['test2.php'],
- 'include' => ['test1.php']
- ],
- $this->ts->getIncludes(true)
- );
- }
-
- public function testGetIncludesCategory()
- {
- $this->assertSame(
- ['test4.php'],
- $this->ts->getIncludes(true, 'require_once')
- );
- }
-}
diff --git a/vendor/phpunit/php-token-stream/tests/Token/InterfaceTest.php b/vendor/phpunit/php-token-stream/tests/Token/InterfaceTest.php
deleted file mode 100644
index c61ec3871..000000000
--- a/vendor/phpunit/php-token-stream/tests/Token/InterfaceTest.php
+++ /dev/null
@@ -1,169 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-use PHPUnit\Framework\TestCase;
-
-class PHP_Token_InterfaceTest extends TestCase
-{
- /**
- * @var PHP_Token_CLASS
- */
- private $class;
-
- /**
- * @var PHP_Token_INTERFACE[]
- */
- private $interfaces;
-
- protected function setUp()
- {
- $ts = new PHP_Token_Stream(TEST_FILES_PATH . 'source4.php');
- $i = 0;
-
- foreach ($ts as $token) {
- if ($token instanceof PHP_Token_CLASS) {
- $this->class = $token;
- } elseif ($token instanceof PHP_Token_INTERFACE) {
- $this->interfaces[$i] = $token;
- $i++;
- }
- }
- }
-
- public function testGetName()
- {
- $this->assertEquals(
- 'iTemplate', $this->interfaces[0]->getName()
- );
- }
-
- public function testGetParentNotExists()
- {
- $this->assertFalse(
- $this->interfaces[0]->getParent()
- );
- }
-
- public function testHasParentNotExists()
- {
- $this->assertFalse(
- $this->interfaces[0]->hasParent()
- );
- }
-
- public function testGetParentExists()
- {
- $this->assertEquals(
- 'a', $this->interfaces[2]->getParent()
- );
- }
-
- public function testHasParentExists()
- {
- $this->assertTrue(
- $this->interfaces[2]->hasParent()
- );
- }
-
- public function testGetInterfacesExists()
- {
- $this->assertEquals(
- ['b'],
- $this->class->getInterfaces()
- );
- }
-
- public function testHasInterfacesExists()
- {
- $this->assertTrue(
- $this->class->hasInterfaces()
- );
- }
-
- public function testGetPackageNamespace()
- {
- foreach (new PHP_Token_Stream(TEST_FILES_PATH . 'classInNamespace.php') as $token) {
- if ($token instanceof PHP_Token_INTERFACE) {
- $package = $token->getPackage();
- $this->assertSame('Foo\\Bar', $package['namespace']);
- }
- }
- }
-
- public function provideFilesWithClassesWithinMultipleNamespaces()
- {
- return [
- [TEST_FILES_PATH . 'multipleNamespacesWithOneClassUsingBraces.php'],
- [TEST_FILES_PATH . 'multipleNamespacesWithOneClassUsingNonBraceSyntax.php'],
- ];
- }
-
- /**
- * @dataProvider provideFilesWithClassesWithinMultipleNamespaces
- */
- public function testGetPackageNamespaceForFileWithMultipleNamespaces($filepath)
- {
- $tokenStream = new PHP_Token_Stream($filepath);
- $firstClassFound = false;
-
- foreach ($tokenStream as $token) {
- if ($firstClassFound === false && $token instanceof PHP_Token_INTERFACE) {
- $package = $token->getPackage();
- $this->assertSame('TestClassInBar', $token->getName());
- $this->assertSame('Foo\\Bar', $package['namespace']);
- $firstClassFound = true;
- continue;
- }
- // Secound class
- if ($token instanceof PHP_Token_INTERFACE) {
- $package = $token->getPackage();
- $this->assertSame('TestClassInBaz', $token->getName());
- $this->assertSame('Foo\\Baz', $package['namespace']);
-
- return;
- }
- }
- $this->fail('Searching for 2 classes failed');
- }
-
- public function testGetPackageNamespaceIsEmptyForInterfacesThatAreNotWithinNamespaces()
- {
- foreach ($this->interfaces as $token) {
- $package = $token->getPackage();
- $this->assertSame('', $package['namespace']);
- }
- }
-
- public function testGetPackageNamespaceWhenExtentingFromNamespaceClass()
- {
- $tokenStream = new PHP_Token_Stream(TEST_FILES_PATH . 'classExtendsNamespacedClass.php');
- $firstClassFound = false;
-
- foreach ($tokenStream as $token) {
- if ($firstClassFound === false && $token instanceof PHP_Token_INTERFACE) {
- $package = $token->getPackage();
- $this->assertSame('Baz', $token->getName());
- $this->assertSame('Foo\\Bar', $package['namespace']);
- $firstClassFound = true;
- continue;
- }
-
- if ($token instanceof PHP_Token_INTERFACE) {
- $package = $token->getPackage();
- $this->assertSame('Extender', $token->getName());
- $this->assertSame('Other\\Space', $package['namespace']);
-
- return;
- }
- }
-
- $this->fail('Searching for 2 classes failed');
- }
-}
diff --git a/vendor/phpunit/php-token-stream/tests/Token/NamespaceTest.php b/vendor/phpunit/php-token-stream/tests/Token/NamespaceTest.php
deleted file mode 100644
index 97a922498..000000000
--- a/vendor/phpunit/php-token-stream/tests/Token/NamespaceTest.php
+++ /dev/null
@@ -1,62 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-use PHPUnit\Framework\TestCase;
-
-class PHP_Token_NamespaceTest extends TestCase
-{
- public function testGetName()
- {
- $tokenStream = new PHP_Token_Stream(
- TEST_FILES_PATH . 'classInNamespace.php'
- );
-
- foreach ($tokenStream as $token) {
- if ($token instanceof PHP_Token_NAMESPACE) {
- $this->assertSame('Foo\\Bar', $token->getName());
- }
- }
- }
-
- public function testGetStartLineWithUnscopedNamespace()
- {
- foreach (new PHP_Token_Stream(TEST_FILES_PATH . 'classInNamespace.php') as $token) {
- if ($token instanceof PHP_Token_NAMESPACE) {
- $this->assertSame(2, $token->getLine());
- }
- }
- }
-
- public function testGetEndLineWithUnscopedNamespace()
- {
- foreach (new PHP_Token_Stream(TEST_FILES_PATH . 'classInNamespace.php') as $token) {
- if ($token instanceof PHP_Token_NAMESPACE) {
- $this->assertSame(2, $token->getEndLine());
- }
- }
- }
- public function testGetStartLineWithScopedNamespace()
- {
- foreach (new PHP_Token_Stream(TEST_FILES_PATH . 'classInScopedNamespace.php') as $token) {
- if ($token instanceof PHP_Token_NAMESPACE) {
- $this->assertSame(2, $token->getLine());
- }
- }
- }
-
- public function testGetEndLineWithScopedNamespace()
- {
- foreach (new PHP_Token_Stream(TEST_FILES_PATH . 'classInScopedNamespace.php') as $token) {
- if ($token instanceof PHP_Token_NAMESPACE) {
- $this->assertSame(8, $token->getEndLine());
- }
- }
- }
-}
diff --git a/vendor/phpunit/php-token-stream/tests/_fixture/classExtendsNamespacedClass.php b/vendor/phpunit/php-token-stream/tests/_fixture/classExtendsNamespacedClass.php
deleted file mode 100644
index 560eec94c..000000000
--- a/vendor/phpunit/php-token-stream/tests/_fixture/classExtendsNamespacedClass.php
+++ /dev/null
@@ -1,10 +0,0 @@
-method_in_anonymous_class();
- }
-
- public function methodTwo() {
- return false;
- }
-}
diff --git a/vendor/phpunit/php-token-stream/tests/_fixture/class_with_multiple_anonymous_classes_and_functions.php b/vendor/phpunit/php-token-stream/tests/_fixture/class_with_multiple_anonymous_classes_and_functions.php
deleted file mode 100644
index 3267ba561..000000000
--- a/vendor/phpunit/php-token-stream/tests/_fixture/class_with_multiple_anonymous_classes_and_functions.php
+++ /dev/null
@@ -1,26 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-require __DIR__ . '/../vendor/autoload.php';
-
-define(
- 'TEST_FILES_PATH',
- __DIR__ . DIRECTORY_SEPARATOR . '_fixture' . DIRECTORY_SEPARATOR
-);
diff --git a/vendor/phpunit/phpunit/ChangeLog-8.5.md b/vendor/phpunit/phpunit/ChangeLog-8.5.md
index 9d0f4a1f9..6485b8e53 100644
--- a/vendor/phpunit/phpunit/ChangeLog-8.5.md
+++ b/vendor/phpunit/phpunit/ChangeLog-8.5.md
@@ -2,6 +2,12 @@
All notable changes of the PHPUnit 8.5 release series are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles.
+## [8.5.32] - 2023-01-26
+
+### Fixed
+
+* [#5120](https://github.com/sebastianbergmann/phpunit/issues/5120): Test Runner incorrectly treats `--testsuite` and `--list-tests` as not combinable options
+
## [8.5.31] - 2022-10-28
### Fixed
@@ -256,6 +262,7 @@ All notable changes of the PHPUnit 8.5 release series are documented in this fil
* [#3967](https://github.com/sebastianbergmann/phpunit/issues/3967): Cannot double interface that extends interface that extends `\Throwable`
* [#3968](https://github.com/sebastianbergmann/phpunit/pull/3968): Test class run in a separate PHP process are passing when `exit` called inside
+[8.5.32]: https://github.com/sebastianbergmann/phpunit/compare/8.5.31...8.5.32
[8.5.31]: https://github.com/sebastianbergmann/phpunit/compare/8.5.30...8.5.31
[8.5.30]: https://github.com/sebastianbergmann/phpunit/compare/8.5.29...8.5.30
[8.5.29]: https://github.com/sebastianbergmann/phpunit/compare/8.5.28...8.5.29
diff --git a/vendor/phpunit/phpunit/LICENSE b/vendor/phpunit/phpunit/LICENSE
index 567141f2d..73e955128 100644
--- a/vendor/phpunit/phpunit/LICENSE
+++ b/vendor/phpunit/phpunit/LICENSE
@@ -1,6 +1,6 @@
BSD 3-Clause License
-Copyright (c) 2001-2022, Sebastian Bergmann
+Copyright (c) 2001-2023, Sebastian Bergmann
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/vendor/phpunit/phpunit/README.md b/vendor/phpunit/phpunit/README.md
index d8694bf04..e0f451c55 100644
--- a/vendor/phpunit/phpunit/README.md
+++ b/vendor/phpunit/phpunit/README.md
@@ -2,12 +2,12 @@
# PHPUnit
-PHPUnit is a programmer-oriented testing framework for PHP. It is an instance of the xUnit architecture for unit testing frameworks.
-
-[](https://packagist.org/packages/phpunit/phpunit)
-[](https://php.net/)
-[](https://phpunit.de/build-status.html)
+[](https://packagist.org/packages/phpunit/phpunit)
+[](https://github.com/sebastianbergmann/phpunit/actions)
[](https://shepherd.dev/github/sebastianbergmann/phpunit)
+[](https://codecov.io/gh/sebastianbergmann/phpunit)
+
+PHPUnit is a programmer-oriented testing framework for PHP. It is an instance of the xUnit architecture for unit testing frameworks.
## Installation
diff --git a/vendor/phpunit/phpunit/src/Framework/Assert.php b/vendor/phpunit/phpunit/src/Framework/Assert.php
index 3e2abfa01..12536edcd 100644
--- a/vendor/phpunit/phpunit/src/Framework/Assert.php
+++ b/vendor/phpunit/phpunit/src/Framework/Assert.php
@@ -3458,7 +3458,7 @@ abstract class Assert
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php b/vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php
index c42964cf5..6107a5aa1 100644
--- a/vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php
@@ -59,7 +59,7 @@ class ClassHasAttribute extends Constraint
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php b/vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php
index 16e2917f6..6171d6730 100644
--- a/vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php
@@ -51,7 +51,7 @@ final class ClassHasStaticAttribute extends ClassHasAttribute
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Generator.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator.php
index 121b16936..49fbd2e52 100644
--- a/vendor/phpunit/phpunit/src/Framework/MockObject/Generator.php
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator.php
@@ -234,7 +234,7 @@ EOT;
} catch (ReflectionException $e) {
throw new RuntimeException(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -301,7 +301,7 @@ EOT;
} catch (ReflectionException $e) {
throw new RuntimeException(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -481,7 +481,7 @@ EOT;
} catch (SoapFault $e) {
throw new RuntimeException(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -568,7 +568,7 @@ EOT;
} catch (ReflectionException $e) {
throw new RuntimeException(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -598,7 +598,7 @@ EOT;
} catch (ReflectionException $e) {
throw new RuntimeException(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -628,7 +628,7 @@ EOT;
} catch (ReflectionException $e) {
throw new RuntimeException(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -656,7 +656,7 @@ EOT;
} catch (ReflectionException $e) {
throw new RuntimeException(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -689,7 +689,7 @@ EOT;
} catch (ReflectionException $e) {
throw new RuntimeException(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -716,7 +716,7 @@ EOT;
} catch (ReflectionException $e) {
throw new RuntimeException(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -773,7 +773,7 @@ EOT;
} catch (ReflectionException $e) {
throw new RuntimeException(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -795,7 +795,7 @@ EOT;
} catch (ReflectionException $e) {
throw new RuntimeException(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -845,7 +845,7 @@ EOT;
} catch (ReflectionException $e) {
throw new RuntimeException(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -872,7 +872,7 @@ EOT;
} catch (ReflectionException $e) {
throw new RuntimeException(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -888,7 +888,7 @@ EOT;
} catch (ReflectionException $e) {
throw new RuntimeException(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -929,7 +929,7 @@ EOT;
} catch (ReflectionException $e) {
throw new RuntimeException(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -968,7 +968,7 @@ EOT;
} catch (ReflectionException $e) {
throw new RuntimeException(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -1024,10 +1024,10 @@ EOT;
$isInterface,
$additionalInterfaces
),
- 'clone' => $cloneTrait,
- 'mock_class_name' => $mockClassName['className'],
- 'mocked_methods' => $mockedMethods,
- 'method' => $method,
+ 'clone' => $cloneTrait,
+ 'mock_class_name' => $mockClassName['className'],
+ 'mocked_methods' => $mockedMethods,
+ 'method' => $method,
]
);
diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/MockBuilder.php b/vendor/phpunit/phpunit/src/Framework/MockObject/MockBuilder.php
index 6ff2b264e..955b9d7fa 100644
--- a/vendor/phpunit/phpunit/src/Framework/MockObject/MockBuilder.php
+++ b/vendor/phpunit/phpunit/src/Framework/MockObject/MockBuilder.php
@@ -230,7 +230,7 @@ final class MockBuilder
} catch (ReflectionException $e) {
throw new RuntimeException(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -276,7 +276,7 @@ final class MockBuilder
} catch (ReflectionException $e) {
throw new RuntimeException(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
diff --git a/vendor/phpunit/phpunit/src/Framework/TestCase.php b/vendor/phpunit/phpunit/src/Framework/TestCase.php
index 9ec27f923..d00b97771 100644
--- a/vendor/phpunit/phpunit/src/Framework/TestCase.php
+++ b/vendor/phpunit/phpunit/src/Framework/TestCase.php
@@ -518,7 +518,7 @@ abstract class TestCase extends Assert implements SelfDescribing, Test
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -728,7 +728,7 @@ abstract class TestCase extends Assert implements SelfDescribing, Test
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -2542,7 +2542,7 @@ abstract class TestCase extends Assert implements SelfDescribing, Test
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
diff --git a/vendor/phpunit/phpunit/src/Framework/TestResult.php b/vendor/phpunit/phpunit/src/Framework/TestResult.php
index e72bd260a..57f1a5ef0 100644
--- a/vendor/phpunit/phpunit/src/Framework/TestResult.php
+++ b/vendor/phpunit/phpunit/src/Framework/TestResult.php
@@ -877,7 +877,7 @@ final class TestResult implements Countable
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -892,7 +892,7 @@ final class TestResult implements Countable
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
diff --git a/vendor/phpunit/phpunit/src/Framework/TestSuite.php b/vendor/phpunit/phpunit/src/Framework/TestSuite.php
index 4c3075cc1..6c1c799cd 100644
--- a/vendor/phpunit/phpunit/src/Framework/TestSuite.php
+++ b/vendor/phpunit/phpunit/src/Framework/TestSuite.php
@@ -43,6 +43,8 @@ use ReflectionMethod;
use Throwable;
/**
+ * @template-implements IteratorAggregate
+ *
* @internal This class is not covered by the backward compatibility promise for PHPUnit
*/
class TestSuite implements IteratorAggregate, SelfDescribing, Test
@@ -170,7 +172,7 @@ class TestSuite implements IteratorAggregate, SelfDescribing, Test
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -253,7 +255,7 @@ class TestSuite implements IteratorAggregate, SelfDescribing, Test
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -308,7 +310,7 @@ class TestSuite implements IteratorAggregate, SelfDescribing, Test
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -329,7 +331,7 @@ class TestSuite implements IteratorAggregate, SelfDescribing, Test
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -404,7 +406,7 @@ class TestSuite implements IteratorAggregate, SelfDescribing, Test
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -426,7 +428,7 @@ class TestSuite implements IteratorAggregate, SelfDescribing, Test
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -446,7 +448,7 @@ class TestSuite implements IteratorAggregate, SelfDescribing, Test
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
diff --git a/vendor/phpunit/phpunit/src/Framework/TestSuiteIterator.php b/vendor/phpunit/phpunit/src/Framework/TestSuiteIterator.php
index e351622f3..76b12fcfb 100644
--- a/vendor/phpunit/phpunit/src/Framework/TestSuiteIterator.php
+++ b/vendor/phpunit/phpunit/src/Framework/TestSuiteIterator.php
@@ -14,6 +14,8 @@ use function count;
use RecursiveIterator;
/**
+ * @template-implements RecursiveIterator
+ *
* @internal This class is not covered by the backward compatibility promise for PHPUnit
*/
final class TestSuiteIterator implements RecursiveIterator
diff --git a/vendor/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php b/vendor/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php
index b658dfcc4..3131e764a 100644
--- a/vendor/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php
+++ b/vendor/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php
@@ -64,7 +64,7 @@ final class StandardTestSuiteLoader implements TestSuiteLoader
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -89,7 +89,7 @@ final class StandardTestSuiteLoader implements TestSuiteLoader
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -113,7 +113,7 @@ final class StandardTestSuiteLoader implements TestSuiteLoader
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -137,7 +137,7 @@ final class StandardTestSuiteLoader implements TestSuiteLoader
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
diff --git a/vendor/phpunit/phpunit/src/Runner/Version.php b/vendor/phpunit/phpunit/src/Runner/Version.php
index 4e3537f81..d191c6967 100644
--- a/vendor/phpunit/phpunit/src/Runner/Version.php
+++ b/vendor/phpunit/phpunit/src/Runner/Version.php
@@ -38,7 +38,7 @@ final class Version
}
if (self::$version === '') {
- self::$version = (new VersionId('8.5.31', dirname(__DIR__, 2)))->getVersion();
+ self::$version = (new VersionId('8.5.32', dirname(__DIR__, 2)))->getVersion();
}
return self::$version;
diff --git a/vendor/phpunit/phpunit/src/TextUI/Command.php b/vendor/phpunit/phpunit/src/TextUI/Command.php
index 4b8e5367c..93ca12837 100644
--- a/vendor/phpunit/phpunit/src/TextUI/Command.php
+++ b/vendor/phpunit/phpunit/src/TextUI/Command.php
@@ -1017,7 +1017,7 @@ class Command
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -1082,7 +1082,7 @@ class Command
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
// @codeCoverageIgnoreEnd
@@ -1314,7 +1314,6 @@ class Command
'filter',
'groups',
'excludeGroups',
- 'testsuite',
]
);
@@ -1342,7 +1341,6 @@ class Command
'filter',
'groups',
'excludeGroups',
- 'testsuite',
]
);
diff --git a/vendor/phpunit/phpunit/src/TextUI/Help.php b/vendor/phpunit/phpunit/src/TextUI/Help.php
index 2dd895604..5fa918fca 100644
--- a/vendor/phpunit/phpunit/src/TextUI/Help.php
+++ b/vendor/phpunit/phpunit/src/TextUI/Help.php
@@ -29,11 +29,11 @@ final class Help
private const LEFT_MARGIN = ' ';
private const HELP_TEXT = [
- 'Usage' => [
+ 'Usage' => [
['text' => 'phpunit [options] UnitTest [UnitTest.php]'],
['text' => 'phpunit [options] '],
],
- 'Code Coverage Options' => [
+ 'Code Coverage Options' => [
['arg' => '--coverage-clover ', 'desc' => 'Generate code coverage report in Clover XML format'],
['arg' => '--coverage-crap4j ', 'desc' => 'Generate code coverage report in Crap4J XML format'],
['arg' => '--coverage-html ', 'desc' => 'Generate code coverage report in HTML format'],
@@ -46,7 +46,7 @@ final class Help
['arg' => '--dump-xdebug-filter ', 'desc' => 'Generate script to set Xdebug code coverage filter'],
],
- 'Logging Options' => [
+ 'Logging Options' => [
['arg' => '--log-junit ', 'desc' => 'Log test execution in JUnit XML format to file'],
['arg' => '--log-teamcity ', 'desc' => 'Log test execution in TeamCity format to file'],
['arg' => '--testdox-html ', 'desc' => 'Write agile documentation in HTML format to file'],
@@ -111,13 +111,13 @@ final class Help
['arg' => '--printer ', 'desc' => 'TestListener implementation to use'],
['spacer' => ''],
- ['arg' => '--order-by=', 'desc' => 'Run tests in order: default|defects|duration|no-depends|random|reverse|size'],
- ['arg' => '--random-order-seed=', 'desc' => 'Use a specific random seed for random order'],
- ['arg' => '--cache-result', 'desc' => 'Write test results to cache file'],
- ['arg' => '--do-not-cache-result', 'desc' => 'Do not write test results to cache file'],
+ ['arg' => '--order-by=', 'desc' => 'Run tests in order: default|defects|duration|no-depends|random|reverse|size'],
+ ['arg' => '--random-order-seed=', 'desc' => 'Use a specific random seed for random order'],
+ ['arg' => '--cache-result', 'desc' => 'Write test results to cache file'],
+ ['arg' => '--do-not-cache-result', 'desc' => 'Do not write test results to cache file'],
],
- 'Configuration Options' => [
+ 'Configuration Options' => [
['arg' => '--prepend ', 'desc' => 'A PHP script that is included as early as possible'],
['arg' => '--bootstrap ', 'desc' => 'A PHP script that is included before the tests run'],
['arg' => '-c|--configuration ', 'desc' => 'Read configuration from XML file'],
@@ -129,7 +129,7 @@ final class Help
['arg' => '--cache-result-file=', 'desc' => 'Specify result cache path and filename'],
],
- 'Miscellaneous Options' => [
+ 'Miscellaneous Options' => [
['arg' => '-h|--help', 'desc' => 'Prints this usage information'],
['arg' => '--version', 'desc' => 'Prints the version and exits'],
['arg' => '--atleast-version ', 'desc' => 'Checks that version is greater than min and exits'],
diff --git a/vendor/phpunit/phpunit/src/TextUI/TestRunner.php b/vendor/phpunit/phpunit/src/TextUI/TestRunner.php
index ebf0e8dda..70b1340b1 100644
--- a/vendor/phpunit/phpunit/src/TextUI/TestRunner.php
+++ b/vendor/phpunit/phpunit/src/TextUI/TestRunner.php
@@ -296,7 +296,7 @@ final class TestRunner extends BaseTestRunner
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -1073,7 +1073,7 @@ final class TestRunner extends BaseTestRunner
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -1121,7 +1121,7 @@ final class TestRunner extends BaseTestRunner
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
diff --git a/vendor/phpunit/phpunit/src/Util/Annotation/DocBlock.php b/vendor/phpunit/phpunit/src/Util/Annotation/DocBlock.php
index 22d33130f..84aad5f9c 100644
--- a/vendor/phpunit/phpunit/src/Util/Annotation/DocBlock.php
+++ b/vendor/phpunit/phpunit/src/Util/Annotation/DocBlock.php
@@ -480,7 +480,7 @@ final class DocBlock
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
// @codeCoverageIgnoreEnd
diff --git a/vendor/phpunit/phpunit/src/Util/Annotation/Registry.php b/vendor/phpunit/phpunit/src/Util/Annotation/Registry.php
index 798305be4..8ee6c8395 100644
--- a/vendor/phpunit/phpunit/src/Util/Annotation/Registry.php
+++ b/vendor/phpunit/phpunit/src/Util/Annotation/Registry.php
@@ -58,7 +58,7 @@ final class Registry
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -84,7 +84,7 @@ final class Registry
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
diff --git a/vendor/phpunit/phpunit/src/Util/Blacklist.php b/vendor/phpunit/phpunit/src/Util/Blacklist.php
index dd89dcd55..6d95db91b 100644
--- a/vendor/phpunit/phpunit/src/Util/Blacklist.php
+++ b/vendor/phpunit/phpunit/src/Util/Blacklist.php
@@ -57,91 +57,91 @@ final class Blacklist
*/
public static $blacklistedClassNames = [
// composer
- ClassLoader::class => 1,
+ ClassLoader::class => 1,
// doctrine/instantiator
- Instantiator::class => 1,
+ Instantiator::class => 1,
// myclabs/deepcopy
- DeepCopy::class => 1,
+ DeepCopy::class => 1,
// phar-io/manifest
- Manifest::class => 1,
+ Manifest::class => 1,
// phar-io/version
- PharIoVersion::class => 1,
+ PharIoVersion::class => 1,
// phpdocumentor/reflection-common
- Project::class => 1,
+ Project::class => 1,
// phpdocumentor/reflection-docblock
- DocBlock::class => 1,
+ DocBlock::class => 1,
// phpdocumentor/type-resolver
- Type::class => 1,
+ Type::class => 1,
// phpspec/prophecy
- Prophet::class => 1,
+ Prophet::class => 1,
// phpunit/phpunit
- TestCase::class => 2,
+ TestCase::class => 2,
// phpunit/php-code-coverage
- CodeCoverage::class => 1,
+ CodeCoverage::class => 1,
// phpunit/php-file-iterator
FileIteratorFacade::class => 1,
// phpunit/php-invoker
- Invoker::class => 1,
+ Invoker::class => 1,
// phpunit/php-text-template
- Text_Template::class => 1,
+ Text_Template::class => 1,
// phpunit/php-timer
- Timer::class => 1,
+ Timer::class => 1,
// phpunit/php-token-stream
- PHP_Token::class => 1,
+ PHP_Token::class => 1,
// sebastian/code-unit-reverse-lookup
- Wizard::class => 1,
+ Wizard::class => 1,
// sebastian/comparator
- Comparator::class => 1,
+ Comparator::class => 1,
// sebastian/diff
- Diff::class => 1,
+ Diff::class => 1,
// sebastian/environment
- Runtime::class => 1,
+ Runtime::class => 1,
// sebastian/exporter
- Exporter::class => 1,
+ Exporter::class => 1,
// sebastian/global-state
- Snapshot::class => 1,
+ Snapshot::class => 1,
// sebastian/object-enumerator
- Enumerator::class => 1,
+ Enumerator::class => 1,
// sebastian/recursion-context
- Context::class => 1,
+ Context::class => 1,
// sebastian/resource-operations
ResourceOperations::class => 1,
// sebastian/type
- TypeName::class => 1,
+ TypeName::class => 1,
// sebastian/version
- Version::class => 1,
+ Version::class => 1,
// theseer/tokenizer
- Tokenizer::class => 1,
+ Tokenizer::class => 1,
// webmozart/assert
- Assert::class => 1,
+ Assert::class => 1,
];
/**
@@ -200,7 +200,7 @@ final class Blacklist
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
diff --git a/vendor/phpunit/phpunit/src/Util/Configuration.php b/vendor/phpunit/phpunit/src/Util/Configuration.php
index 1cb5f772d..029b225d7 100644
--- a/vendor/phpunit/phpunit/src/Util/Configuration.php
+++ b/vendor/phpunit/phpunit/src/Util/Configuration.php
@@ -226,7 +226,7 @@ final class Configuration
'directory' => $includeDirectory,
'file' => $includeFile,
],
- 'exclude' => [
+ 'exclude' => [
'directory' => $excludeDirectory,
'file' => $excludeFile,
],
diff --git a/vendor/phpunit/phpunit/src/Util/Log/JUnit.php b/vendor/phpunit/phpunit/src/Util/Log/JUnit.php
index 710e2c47d..bdf04f76b 100644
--- a/vendor/phpunit/phpunit/src/Util/Log/JUnit.php
+++ b/vendor/phpunit/phpunit/src/Util/Log/JUnit.php
@@ -302,7 +302,7 @@ final class JUnit extends Printer implements TestListener
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -317,7 +317,7 @@ final class JUnit extends Printer implements TestListener
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
diff --git a/vendor/phpunit/phpunit/src/Util/Log/TeamCity.php b/vendor/phpunit/phpunit/src/Util/Log/TeamCity.php
index 695760d95..7964b9ae8 100644
--- a/vendor/phpunit/phpunit/src/Util/Log/TeamCity.php
+++ b/vendor/phpunit/phpunit/src/Util/Log/TeamCity.php
@@ -369,7 +369,7 @@ final class TeamCity extends ResultPrinter
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
diff --git a/vendor/phpunit/phpunit/src/Util/Test.php b/vendor/phpunit/phpunit/src/Util/Test.php
index 0a8e3c5d8..82aec6806 100644
--- a/vendor/phpunit/phpunit/src/Util/Test.php
+++ b/vendor/phpunit/phpunit/src/Util/Test.php
@@ -376,7 +376,7 @@ final class Test
public static function getBackupSettings(string $className, string $methodName): array
{
return [
- 'backupGlobals' => self::getBooleanAnnotationSetting(
+ 'backupGlobals' => self::getBooleanAnnotationSetting(
$className,
$methodName,
'backupGlobals'
@@ -686,7 +686,7 @@ final class Test
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -716,7 +716,7 @@ final class Test
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -752,7 +752,7 @@ final class Test
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -778,7 +778,7 @@ final class Test
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -823,7 +823,7 @@ final class Test
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
diff --git a/vendor/phpunit/phpunit/src/Util/TestDox/CliTestDoxPrinter.php b/vendor/phpunit/phpunit/src/Util/TestDox/CliTestDoxPrinter.php
index 5c6621190..76136ebdc 100644
--- a/vendor/phpunit/phpunit/src/Util/TestDox/CliTestDoxPrinter.php
+++ b/vendor/phpunit/phpunit/src/Util/TestDox/CliTestDoxPrinter.php
@@ -67,26 +67,26 @@ class CliTestDoxPrinter extends TestDoxPrinter
];
private const STATUS_STYLES = [
- BaseTestRunner::STATUS_PASSED => [
+ BaseTestRunner::STATUS_PASSED => [
'symbol' => '✔',
'color' => 'fg-green',
],
- BaseTestRunner::STATUS_ERROR => [
+ BaseTestRunner::STATUS_ERROR => [
'symbol' => '✘',
'color' => 'fg-yellow',
'message' => 'bg-yellow,fg-black',
],
- BaseTestRunner::STATUS_FAILURE => [
+ BaseTestRunner::STATUS_FAILURE => [
'symbol' => '✘',
'color' => 'fg-red',
'message' => 'bg-red,fg-white',
],
- BaseTestRunner::STATUS_SKIPPED => [
+ BaseTestRunner::STATUS_SKIPPED => [
'symbol' => '↩',
'color' => 'fg-cyan',
'message' => 'fg-cyan',
],
- BaseTestRunner::STATUS_RISKY => [
+ BaseTestRunner::STATUS_RISKY => [
'symbol' => '☢',
'color' => 'fg-yellow',
'message' => 'fg-yellow',
@@ -96,12 +96,12 @@ class CliTestDoxPrinter extends TestDoxPrinter
'color' => 'fg-yellow',
'message' => 'fg-yellow',
],
- BaseTestRunner::STATUS_WARNING => [
+ BaseTestRunner::STATUS_WARNING => [
'symbol' => '⚠',
'color' => 'fg-yellow',
'message' => 'fg-yellow',
],
- BaseTestRunner::STATUS_UNKNOWN => [
+ BaseTestRunner::STATUS_UNKNOWN => [
'symbol' => '?',
'color' => 'fg-blue',
'message' => 'fg-white,bg-blue',
diff --git a/vendor/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php b/vendor/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php
index ca5af055a..d6d3ce2dd 100644
--- a/vendor/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php
+++ b/vendor/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php
@@ -238,7 +238,7 @@ final class NamePrettifier
} catch (ReflectionException $e) {
throw new UtilException(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
@@ -258,7 +258,7 @@ final class NamePrettifier
} catch (ReflectionException $e) {
throw new UtilException(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
diff --git a/vendor/phpunit/phpunit/src/Util/TestDox/XmlResultPrinter.php b/vendor/phpunit/phpunit/src/Util/TestDox/XmlResultPrinter.php
index fc511edd4..5d98c8e21 100644
--- a/vendor/phpunit/phpunit/src/Util/TestDox/XmlResultPrinter.php
+++ b/vendor/phpunit/phpunit/src/Util/TestDox/XmlResultPrinter.php
@@ -233,7 +233,7 @@ final class XmlResultPrinter extends Printer implements TestListener
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
diff --git a/vendor/phpunit/phpunit/src/Util/Xml.php b/vendor/phpunit/phpunit/src/Util/Xml.php
index 1bf6a6146..ab053b57c 100644
--- a/vendor/phpunit/phpunit/src/Util/Xml.php
+++ b/vendor/phpunit/phpunit/src/Util/Xml.php
@@ -247,7 +247,7 @@ final class Xml
} catch (ReflectionException $e) {
throw new Exception(
$e->getMessage(),
- (int) $e->getCode(),
+ $e->getCode(),
$e
);
}
diff --git a/vendor/psr/container/composer.json b/vendor/psr/container/composer.json
index 3797a2538..017f41ea6 100644
--- a/vendor/psr/container/composer.json
+++ b/vendor/psr/container/composer.json
@@ -12,7 +12,7 @@
}
],
"require": {
- "php": ">=7.2.0"
+ "php": ">=7.4.0"
},
"autoload": {
"psr-4": {
diff --git a/vendor/psr/container/src/ContainerExceptionInterface.php b/vendor/psr/container/src/ContainerExceptionInterface.php
index cf10b8b4f..0f213f2fe 100644
--- a/vendor/psr/container/src/ContainerExceptionInterface.php
+++ b/vendor/psr/container/src/ContainerExceptionInterface.php
@@ -2,9 +2,11 @@
namespace Psr\Container;
+use Throwable;
+
/**
* Base interface representing a generic exception in a container.
*/
-interface ContainerExceptionInterface
+interface ContainerExceptionInterface extends Throwable
{
}
diff --git a/vendor/psr/http-client/CHANGELOG.md b/vendor/psr/http-client/CHANGELOG.md
new file mode 100644
index 000000000..e2dc25f51
--- /dev/null
+++ b/vendor/psr/http-client/CHANGELOG.md
@@ -0,0 +1,23 @@
+# Changelog
+
+All notable changes to this project will be documented in this file, in reverse chronological order by release.
+
+## 1.0.1
+
+Allow installation with PHP 8. No code changes.
+
+## 1.0.0
+
+First stable release. No changes since 0.3.0.
+
+## 0.3.0
+
+Added Interface suffix on exceptions
+
+## 0.2.0
+
+All exceptions are in `Psr\Http\Client` namespace
+
+## 0.1.0
+
+First release
diff --git a/vendor/psr/http-client/LICENSE b/vendor/psr/http-client/LICENSE
new file mode 100644
index 000000000..cd5e0020a
--- /dev/null
+++ b/vendor/psr/http-client/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2017 PHP Framework Interoperability Group
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/psr/http-client/README.md b/vendor/psr/http-client/README.md
new file mode 100644
index 000000000..6876b8403
--- /dev/null
+++ b/vendor/psr/http-client/README.md
@@ -0,0 +1,12 @@
+HTTP Client
+===========
+
+This repository holds all the common code related to [PSR-18 (HTTP Client)][psr-url].
+
+Note that this is not a HTTP Client implementation of its own. It is merely abstractions that describe the components of a HTTP Client.
+
+The installable [package][package-url] and [implementations][implementation-url] are listed on Packagist.
+
+[psr-url]: http://www.php-fig.org/psr/psr-18
+[package-url]: https://packagist.org/packages/psr/http-client
+[implementation-url]: https://packagist.org/providers/psr/http-client-implementation
diff --git a/vendor/psr/http-client/composer.json b/vendor/psr/http-client/composer.json
new file mode 100644
index 000000000..c195f8ff1
--- /dev/null
+++ b/vendor/psr/http-client/composer.json
@@ -0,0 +1,27 @@
+{
+ "name": "psr/http-client",
+ "description": "Common interface for HTTP clients",
+ "keywords": ["psr", "psr-18", "http", "http-client"],
+ "homepage": "https://github.com/php-fig/http-client",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "require": {
+ "php": "^7.0 || ^8.0",
+ "psr/http-message": "^1.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Client\\": "src/"
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ }
+}
diff --git a/vendor/psr/http-client/src/ClientExceptionInterface.php b/vendor/psr/http-client/src/ClientExceptionInterface.php
new file mode 100644
index 000000000..aa0b9cf14
--- /dev/null
+++ b/vendor/psr/http-client/src/ClientExceptionInterface.php
@@ -0,0 +1,10 @@
+=7.0.0",
+ "psr/http-message": "^1.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Message\\": "src/"
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ }
+}
diff --git a/vendor/psr/http-factory/src/RequestFactoryInterface.php b/vendor/psr/http-factory/src/RequestFactoryInterface.php
new file mode 100644
index 000000000..cb39a08bf
--- /dev/null
+++ b/vendor/psr/http-factory/src/RequestFactoryInterface.php
@@ -0,0 +1,18 @@
+=5.3.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Message\\": "src/"
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ }
+}
diff --git a/vendor/psr/http-message/src/MessageInterface.php b/vendor/psr/http-message/src/MessageInterface.php
new file mode 100644
index 000000000..dd46e5ec8
--- /dev/null
+++ b/vendor/psr/http-message/src/MessageInterface.php
@@ -0,0 +1,187 @@
+getHeaders() as $name => $values) {
+ * echo $name . ": " . implode(", ", $values);
+ * }
+ *
+ * // Emit headers iteratively:
+ * foreach ($message->getHeaders() as $name => $values) {
+ * foreach ($values as $value) {
+ * header(sprintf('%s: %s', $name, $value), false);
+ * }
+ * }
+ *
+ * While header names are not case-sensitive, getHeaders() will preserve the
+ * exact case in which headers were originally specified.
+ *
+ * @return string[][] Returns an associative array of the message's headers. Each
+ * key MUST be a header name, and each value MUST be an array of strings
+ * for that header.
+ */
+ public function getHeaders();
+
+ /**
+ * Checks if a header exists by the given case-insensitive name.
+ *
+ * @param string $name Case-insensitive header field name.
+ * @return bool Returns true if any header names match the given header
+ * name using a case-insensitive string comparison. Returns false if
+ * no matching header name is found in the message.
+ */
+ public function hasHeader($name);
+
+ /**
+ * Retrieves a message header value by the given case-insensitive name.
+ *
+ * This method returns an array of all the header values of the given
+ * case-insensitive header name.
+ *
+ * If the header does not appear in the message, this method MUST return an
+ * empty array.
+ *
+ * @param string $name Case-insensitive header field name.
+ * @return string[] An array of string values as provided for the given
+ * header. If the header does not appear in the message, this method MUST
+ * return an empty array.
+ */
+ public function getHeader($name);
+
+ /**
+ * Retrieves a comma-separated string of the values for a single header.
+ *
+ * This method returns all of the header values of the given
+ * case-insensitive header name as a string concatenated together using
+ * a comma.
+ *
+ * NOTE: Not all header values may be appropriately represented using
+ * comma concatenation. For such headers, use getHeader() instead
+ * and supply your own delimiter when concatenating.
+ *
+ * If the header does not appear in the message, this method MUST return
+ * an empty string.
+ *
+ * @param string $name Case-insensitive header field name.
+ * @return string A string of values as provided for the given header
+ * concatenated together using a comma. If the header does not appear in
+ * the message, this method MUST return an empty string.
+ */
+ public function getHeaderLine($name);
+
+ /**
+ * Return an instance with the provided value replacing the specified header.
+ *
+ * While header names are case-insensitive, the casing of the header will
+ * be preserved by this function, and returned from getHeaders().
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * new and/or updated header and value.
+ *
+ * @param string $name Case-insensitive header field name.
+ * @param string|string[] $value Header value(s).
+ * @return static
+ * @throws \InvalidArgumentException for invalid header names or values.
+ */
+ public function withHeader($name, $value);
+
+ /**
+ * Return an instance with the specified header appended with the given value.
+ *
+ * Existing values for the specified header will be maintained. The new
+ * value(s) will be appended to the existing list. If the header did not
+ * exist previously, it will be added.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * new header and/or value.
+ *
+ * @param string $name Case-insensitive header field name to add.
+ * @param string|string[] $value Header value(s).
+ * @return static
+ * @throws \InvalidArgumentException for invalid header names or values.
+ */
+ public function withAddedHeader($name, $value);
+
+ /**
+ * Return an instance without the specified header.
+ *
+ * Header resolution MUST be done without case-sensitivity.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that removes
+ * the named header.
+ *
+ * @param string $name Case-insensitive header field name to remove.
+ * @return static
+ */
+ public function withoutHeader($name);
+
+ /**
+ * Gets the body of the message.
+ *
+ * @return StreamInterface Returns the body as a stream.
+ */
+ public function getBody();
+
+ /**
+ * Return an instance with the specified message body.
+ *
+ * The body MUST be a StreamInterface object.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return a new instance that has the
+ * new body stream.
+ *
+ * @param StreamInterface $body Body.
+ * @return static
+ * @throws \InvalidArgumentException When the body is not valid.
+ */
+ public function withBody(StreamInterface $body);
+}
diff --git a/vendor/psr/http-message/src/RequestInterface.php b/vendor/psr/http-message/src/RequestInterface.php
new file mode 100644
index 000000000..a96d4fd63
--- /dev/null
+++ b/vendor/psr/http-message/src/RequestInterface.php
@@ -0,0 +1,129 @@
+getQuery()`
+ * or from the `QUERY_STRING` server param.
+ *
+ * @return array
+ */
+ public function getQueryParams();
+
+ /**
+ * Return an instance with the specified query string arguments.
+ *
+ * These values SHOULD remain immutable over the course of the incoming
+ * request. They MAY be injected during instantiation, such as from PHP's
+ * $_GET superglobal, or MAY be derived from some other value such as the
+ * URI. In cases where the arguments are parsed from the URI, the data
+ * MUST be compatible with what PHP's parse_str() would return for
+ * purposes of how duplicate query parameters are handled, and how nested
+ * sets are handled.
+ *
+ * Setting query string arguments MUST NOT change the URI stored by the
+ * request, nor the values in the server params.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * updated query string arguments.
+ *
+ * @param array $query Array of query string arguments, typically from
+ * $_GET.
+ * @return static
+ */
+ public function withQueryParams(array $query);
+
+ /**
+ * Retrieve normalized file upload data.
+ *
+ * This method returns upload metadata in a normalized tree, with each leaf
+ * an instance of Psr\Http\Message\UploadedFileInterface.
+ *
+ * These values MAY be prepared from $_FILES or the message body during
+ * instantiation, or MAY be injected via withUploadedFiles().
+ *
+ * @return array An array tree of UploadedFileInterface instances; an empty
+ * array MUST be returned if no data is present.
+ */
+ public function getUploadedFiles();
+
+ /**
+ * Create a new instance with the specified uploaded files.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * updated body parameters.
+ *
+ * @param array $uploadedFiles An array tree of UploadedFileInterface instances.
+ * @return static
+ * @throws \InvalidArgumentException if an invalid structure is provided.
+ */
+ public function withUploadedFiles(array $uploadedFiles);
+
+ /**
+ * Retrieve any parameters provided in the request body.
+ *
+ * If the request Content-Type is either application/x-www-form-urlencoded
+ * or multipart/form-data, and the request method is POST, this method MUST
+ * return the contents of $_POST.
+ *
+ * Otherwise, this method may return any results of deserializing
+ * the request body content; as parsing returns structured content, the
+ * potential types MUST be arrays or objects only. A null value indicates
+ * the absence of body content.
+ *
+ * @return null|array|object The deserialized body parameters, if any.
+ * These will typically be an array or object.
+ */
+ public function getParsedBody();
+
+ /**
+ * Return an instance with the specified body parameters.
+ *
+ * These MAY be injected during instantiation.
+ *
+ * If the request Content-Type is either application/x-www-form-urlencoded
+ * or multipart/form-data, and the request method is POST, use this method
+ * ONLY to inject the contents of $_POST.
+ *
+ * The data IS NOT REQUIRED to come from $_POST, but MUST be the results of
+ * deserializing the request body content. Deserialization/parsing returns
+ * structured data, and, as such, this method ONLY accepts arrays or objects,
+ * or a null value if nothing was available to parse.
+ *
+ * As an example, if content negotiation determines that the request data
+ * is a JSON payload, this method could be used to create a request
+ * instance with the deserialized parameters.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * updated body parameters.
+ *
+ * @param null|array|object $data The deserialized body data. This will
+ * typically be in an array or object.
+ * @return static
+ * @throws \InvalidArgumentException if an unsupported argument type is
+ * provided.
+ */
+ public function withParsedBody($data);
+
+ /**
+ * Retrieve attributes derived from the request.
+ *
+ * The request "attributes" may be used to allow injection of any
+ * parameters derived from the request: e.g., the results of path
+ * match operations; the results of decrypting cookies; the results of
+ * deserializing non-form-encoded message bodies; etc. Attributes
+ * will be application and request specific, and CAN be mutable.
+ *
+ * @return array Attributes derived from the request.
+ */
+ public function getAttributes();
+
+ /**
+ * Retrieve a single derived request attribute.
+ *
+ * Retrieves a single derived request attribute as described in
+ * getAttributes(). If the attribute has not been previously set, returns
+ * the default value as provided.
+ *
+ * This method obviates the need for a hasAttribute() method, as it allows
+ * specifying a default value to return if the attribute is not found.
+ *
+ * @see getAttributes()
+ * @param string $name The attribute name.
+ * @param mixed $default Default value to return if the attribute does not exist.
+ * @return mixed
+ */
+ public function getAttribute($name, $default = null);
+
+ /**
+ * Return an instance with the specified derived request attribute.
+ *
+ * This method allows setting a single derived request attribute as
+ * described in getAttributes().
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * updated attribute.
+ *
+ * @see getAttributes()
+ * @param string $name The attribute name.
+ * @param mixed $value The value of the attribute.
+ * @return static
+ */
+ public function withAttribute($name, $value);
+
+ /**
+ * Return an instance that removes the specified derived request attribute.
+ *
+ * This method allows removing a single derived request attribute as
+ * described in getAttributes().
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that removes
+ * the attribute.
+ *
+ * @see getAttributes()
+ * @param string $name The attribute name.
+ * @return static
+ */
+ public function withoutAttribute($name);
+}
diff --git a/vendor/psr/http-message/src/StreamInterface.php b/vendor/psr/http-message/src/StreamInterface.php
new file mode 100644
index 000000000..f68f39126
--- /dev/null
+++ b/vendor/psr/http-message/src/StreamInterface.php
@@ -0,0 +1,158 @@
+
+ * [user-info@]host[:port]
+ *
+ *
+ * If the port component is not set or is the standard port for the current
+ * scheme, it SHOULD NOT be included.
+ *
+ * @see https://tools.ietf.org/html/rfc3986#section-3.2
+ * @return string The URI authority, in "[user-info@]host[:port]" format.
+ */
+ public function getAuthority();
+
+ /**
+ * Retrieve the user information component of the URI.
+ *
+ * If no user information is present, this method MUST return an empty
+ * string.
+ *
+ * If a user is present in the URI, this will return that value;
+ * additionally, if the password is also present, it will be appended to the
+ * user value, with a colon (":") separating the values.
+ *
+ * The trailing "@" character is not part of the user information and MUST
+ * NOT be added.
+ *
+ * @return string The URI user information, in "username[:password]" format.
+ */
+ public function getUserInfo();
+
+ /**
+ * Retrieve the host component of the URI.
+ *
+ * If no host is present, this method MUST return an empty string.
+ *
+ * The value returned MUST be normalized to lowercase, per RFC 3986
+ * Section 3.2.2.
+ *
+ * @see http://tools.ietf.org/html/rfc3986#section-3.2.2
+ * @return string The URI host.
+ */
+ public function getHost();
+
+ /**
+ * Retrieve the port component of the URI.
+ *
+ * If a port is present, and it is non-standard for the current scheme,
+ * this method MUST return it as an integer. If the port is the standard port
+ * used with the current scheme, this method SHOULD return null.
+ *
+ * If no port is present, and no scheme is present, this method MUST return
+ * a null value.
+ *
+ * If no port is present, but a scheme is present, this method MAY return
+ * the standard port for that scheme, but SHOULD return null.
+ *
+ * @return null|int The URI port.
+ */
+ public function getPort();
+
+ /**
+ * Retrieve the path component of the URI.
+ *
+ * The path can either be empty or absolute (starting with a slash) or
+ * rootless (not starting with a slash). Implementations MUST support all
+ * three syntaxes.
+ *
+ * Normally, the empty path "" and absolute path "/" are considered equal as
+ * defined in RFC 7230 Section 2.7.3. But this method MUST NOT automatically
+ * do this normalization because in contexts with a trimmed base path, e.g.
+ * the front controller, this difference becomes significant. It's the task
+ * of the user to handle both "" and "/".
+ *
+ * The value returned MUST be percent-encoded, but MUST NOT double-encode
+ * any characters. To determine what characters to encode, please refer to
+ * RFC 3986, Sections 2 and 3.3.
+ *
+ * As an example, if the value should include a slash ("/") not intended as
+ * delimiter between path segments, that value MUST be passed in encoded
+ * form (e.g., "%2F") to the instance.
+ *
+ * @see https://tools.ietf.org/html/rfc3986#section-2
+ * @see https://tools.ietf.org/html/rfc3986#section-3.3
+ * @return string The URI path.
+ */
+ public function getPath();
+
+ /**
+ * Retrieve the query string of the URI.
+ *
+ * If no query string is present, this method MUST return an empty string.
+ *
+ * The leading "?" character is not part of the query and MUST NOT be
+ * added.
+ *
+ * The value returned MUST be percent-encoded, but MUST NOT double-encode
+ * any characters. To determine what characters to encode, please refer to
+ * RFC 3986, Sections 2 and 3.4.
+ *
+ * As an example, if a value in a key/value pair of the query string should
+ * include an ampersand ("&") not intended as a delimiter between values,
+ * that value MUST be passed in encoded form (e.g., "%26") to the instance.
+ *
+ * @see https://tools.ietf.org/html/rfc3986#section-2
+ * @see https://tools.ietf.org/html/rfc3986#section-3.4
+ * @return string The URI query string.
+ */
+ public function getQuery();
+
+ /**
+ * Retrieve the fragment component of the URI.
+ *
+ * If no fragment is present, this method MUST return an empty string.
+ *
+ * The leading "#" character is not part of the fragment and MUST NOT be
+ * added.
+ *
+ * The value returned MUST be percent-encoded, but MUST NOT double-encode
+ * any characters. To determine what characters to encode, please refer to
+ * RFC 3986, Sections 2 and 3.5.
+ *
+ * @see https://tools.ietf.org/html/rfc3986#section-2
+ * @see https://tools.ietf.org/html/rfc3986#section-3.5
+ * @return string The URI fragment.
+ */
+ public function getFragment();
+
+ /**
+ * Return an instance with the specified scheme.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified scheme.
+ *
+ * Implementations MUST support the schemes "http" and "https" case
+ * insensitively, and MAY accommodate other schemes if required.
+ *
+ * An empty scheme is equivalent to removing the scheme.
+ *
+ * @param string $scheme The scheme to use with the new instance.
+ * @return static A new instance with the specified scheme.
+ * @throws \InvalidArgumentException for invalid or unsupported schemes.
+ */
+ public function withScheme($scheme);
+
+ /**
+ * Return an instance with the specified user information.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified user information.
+ *
+ * Password is optional, but the user information MUST include the
+ * user; an empty string for the user is equivalent to removing user
+ * information.
+ *
+ * @param string $user The user name to use for authority.
+ * @param null|string $password The password associated with $user.
+ * @return static A new instance with the specified user information.
+ */
+ public function withUserInfo($user, $password = null);
+
+ /**
+ * Return an instance with the specified host.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified host.
+ *
+ * An empty host value is equivalent to removing the host.
+ *
+ * @param string $host The hostname to use with the new instance.
+ * @return static A new instance with the specified host.
+ * @throws \InvalidArgumentException for invalid hostnames.
+ */
+ public function withHost($host);
+
+ /**
+ * Return an instance with the specified port.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified port.
+ *
+ * Implementations MUST raise an exception for ports outside the
+ * established TCP and UDP port ranges.
+ *
+ * A null value provided for the port is equivalent to removing the port
+ * information.
+ *
+ * @param null|int $port The port to use with the new instance; a null value
+ * removes the port information.
+ * @return static A new instance with the specified port.
+ * @throws \InvalidArgumentException for invalid ports.
+ */
+ public function withPort($port);
+
+ /**
+ * Return an instance with the specified path.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified path.
+ *
+ * The path can either be empty or absolute (starting with a slash) or
+ * rootless (not starting with a slash). Implementations MUST support all
+ * three syntaxes.
+ *
+ * If the path is intended to be domain-relative rather than path relative then
+ * it must begin with a slash ("/"). Paths not starting with a slash ("/")
+ * are assumed to be relative to some base path known to the application or
+ * consumer.
+ *
+ * Users can provide both encoded and decoded path characters.
+ * Implementations ensure the correct encoding as outlined in getPath().
+ *
+ * @param string $path The path to use with the new instance.
+ * @return static A new instance with the specified path.
+ * @throws \InvalidArgumentException for invalid paths.
+ */
+ public function withPath($path);
+
+ /**
+ * Return an instance with the specified query string.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified query string.
+ *
+ * Users can provide both encoded and decoded query characters.
+ * Implementations ensure the correct encoding as outlined in getQuery().
+ *
+ * An empty query string value is equivalent to removing the query string.
+ *
+ * @param string $query The query string to use with the new instance.
+ * @return static A new instance with the specified query string.
+ * @throws \InvalidArgumentException for invalid query strings.
+ */
+ public function withQuery($query);
+
+ /**
+ * Return an instance with the specified URI fragment.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified URI fragment.
+ *
+ * Users can provide both encoded and decoded fragment characters.
+ * Implementations ensure the correct encoding as outlined in getFragment().
+ *
+ * An empty fragment value is equivalent to removing the fragment.
+ *
+ * @param string $fragment The fragment to use with the new instance.
+ * @return static A new instance with the specified fragment.
+ */
+ public function withFragment($fragment);
+
+ /**
+ * Return the string representation as a URI reference.
+ *
+ * Depending on which components of the URI are present, the resulting
+ * string is either a full URI or relative reference according to RFC 3986,
+ * Section 4.1. The method concatenates the various components of the URI,
+ * using the appropriate delimiters:
+ *
+ * - If a scheme is present, it MUST be suffixed by ":".
+ * - If an authority is present, it MUST be prefixed by "//".
+ * - The path can be concatenated without delimiters. But there are two
+ * cases where the path has to be adjusted to make the URI reference
+ * valid as PHP does not allow to throw an exception in __toString():
+ * - If the path is rootless and an authority is present, the path MUST
+ * be prefixed by "/".
+ * - If the path is starting with more than one "/" and no authority is
+ * present, the starting slashes MUST be reduced to one.
+ * - If a query is present, it MUST be prefixed by "?".
+ * - If a fragment is present, it MUST be prefixed by "#".
+ *
+ * @see http://tools.ietf.org/html/rfc3986#section-4.1
+ * @return string
+ */
+ public function __toString();
+}
diff --git a/vendor/psy/psysh/LICENSE b/vendor/psy/psysh/LICENSE
index 2c6a45137..007634a5f 100644
--- a/vendor/psy/psysh/LICENSE
+++ b/vendor/psy/psysh/LICENSE
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2012-2018 Justin Hileman
+Copyright (c) 2012-2023 Justin Hileman
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/vendor/psy/psysh/README.md b/vendor/psy/psysh/README.md
index 0be99d7a6..fc731d115 100644
--- a/vendor/psy/psysh/README.md
+++ b/vendor/psy/psysh/README.md
@@ -7,7 +7,7 @@ PsySH is a runtime developer console, interactive debugger and [REPL](https://en
[](https://packagist.org/packages/psy/psysh)
[](http://psysh.org)
-[](https://github.com/bobthecow/psysh/actions?query=branch:main)
+[](https://github.com/bobthecow/psysh/actions?query=branch:main)
[](https://styleci.io/repos/4549925)
@@ -30,6 +30,7 @@ PsySH is a runtime developer console, interactive debugger and [REPL](https://en
### [🛠 Configuration](https://github.com/bobthecow/psysh/wiki/Configuration)
* [🎛 Config options](https://github.com/bobthecow/psysh/wiki/Config-options)
+ * [🎨 Themes](https://github.com/bobthecow/psysh/wiki/Themes)
* [📄 Sample config file](https://github.com/bobthecow/psysh/wiki/Sample-config)
### [🔌 Integrations](https://github.com/bobthecow/psysh/wiki/Integrations)
diff --git a/vendor/psy/psysh/bin/psysh b/vendor/psy/psysh/bin/psysh
index ccb68f1b7..a20a3e115 100755
--- a/vendor/psy/psysh/bin/psysh
+++ b/vendor/psy/psysh/bin/psysh
@@ -4,7 +4,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2017 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
diff --git a/vendor/psy/psysh/composer.json b/vendor/psy/psysh/composer.json
index 95e6641da..c076d041f 100644
--- a/vendor/psy/psysh/composer.json
+++ b/vendor/psy/psysh/composer.json
@@ -13,23 +13,21 @@
}
],
"require": {
- "php": "^8.0 || ^7.0 || ^5.5.9",
+ "php": "^8.0 || ^7.0.8",
"ext-json": "*",
"ext-tokenizer": "*",
- "symfony/console": "~5.0|~4.0|~3.0|^2.4.2|~2.3.10",
- "symfony/var-dumper": "~5.0|~4.0|~3.0|~2.7",
- "nikic/php-parser": "~4.0|~3.0|~2.0|~1.3"
+ "symfony/console": "^6.0 || ^5.0 || ^4.0 || ^3.4",
+ "symfony/var-dumper": "^6.0 || ^5.0 || ^4.0 || ^3.4",
+ "nikic/php-parser": "^4.0 || ^3.1"
},
"require-dev": {
- "hoa/console": "3.17.*",
"bamarni/composer-bin-plugin": "^1.2"
},
"suggest": {
"ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)",
"ext-posix": "If you have PCNTL, you'll want the POSIX extension as well.",
"ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history.",
- "ext-pdo-sqlite": "The doc command requires SQLite to work.",
- "hoa/console": "A pure PHP readline implementation. You'll want this if your PHP install doesn't already support readline or libedit."
+ "ext-pdo-sqlite": "The doc command requires SQLite to work."
},
"autoload": {
"files": ["src/functions.php"],
@@ -43,9 +41,17 @@
}
},
"bin": ["bin/psysh"],
+ "config": {
+ "allow-plugins": {
+ "bamarni/composer-bin-plugin": true
+ }
+ },
"extra": {
"branch-alias": {
- "dev-main": "0.10.x-dev"
+ "dev-main": "0.11.x-dev"
}
+ },
+ "conflict": {
+ "symfony/console": "4.4.37 || 5.3.14 || 5.3.15 || 5.4.3 || 5.4.4 || 6.0.3 || 6.0.4"
}
}
diff --git a/vendor/psy/psysh/src/CodeCleaner.php b/vendor/psy/psysh/src/CodeCleaner.php
index c23bd2b36..d5f2720c3 100644
--- a/vendor/psy/psysh/src/CodeCleaner.php
+++ b/vendor/psy/psysh/src/CodeCleaner.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -18,6 +18,7 @@ use Psy\CodeCleaner\AbstractClassPass;
use Psy\CodeCleaner\AssignThisVariablePass;
use Psy\CodeCleaner\CalledClassPass;
use Psy\CodeCleaner\CallTimePassByReferencePass;
+use Psy\CodeCleaner\CodeCleanerPass;
use Psy\CodeCleaner\EmptyArrayDimFetchPass;
use Psy\CodeCleaner\ExitPass;
use Psy\CodeCleaner\FinalClassPass;
@@ -38,7 +39,6 @@ use Psy\CodeCleaner\ReturnTypePass;
use Psy\CodeCleaner\StrictTypesPass;
use Psy\CodeCleaner\UseStatementPass;
use Psy\CodeCleaner\ValidClassNamePass;
-use Psy\CodeCleaner\ValidConstantPass;
use Psy\CodeCleaner\ValidConstructorPass;
use Psy\CodeCleaner\ValidFunctionNamePass;
use Psy\Exception\ParseErrorException;
@@ -63,7 +63,7 @@ class CodeCleaner
* @param NodeTraverser|null $traverser A PhpParser NodeTraverser instance. One will be created if not explicitly supplied
* @param bool $yolo run without input validation
*/
- public function __construct(Parser $parser = null, Printer $printer = null, NodeTraverser $traverser = null, $yolo = false)
+ public function __construct(Parser $parser = null, Printer $printer = null, NodeTraverser $traverser = null, bool $yolo = false)
{
$this->yolo = $yolo;
@@ -83,10 +83,8 @@ class CodeCleaner
/**
* Check whether this CodeCleaner is in YOLO mode.
- *
- * @return bool
*/
- public function yolo()
+ public function yolo(): bool
{
return $this->yolo;
}
@@ -94,9 +92,9 @@ class CodeCleaner
/**
* Get default CodeCleaner passes.
*
- * @return array
+ * @return CodeCleanerPass[]
*/
- private function getDefaultPasses()
+ private function getDefaultPasses(): array
{
if ($this->yolo) {
return $this->getYoloPasses();
@@ -140,7 +138,6 @@ class CodeCleaner
// Namespace-aware validation (which depends on aforementioned shenanigans)
new ValidClassNamePass(),
- new ValidConstantPass(),
new ValidFunctionNamePass(),
];
}
@@ -152,9 +149,9 @@ class CodeCleaner
* This list should stay in sync with the "rewriting shenanigans" in
* getDefaultPasses above.
*
- * @return array
+ * @return CodeCleanerPass[]
*/
- private function getYoloPasses()
+ private function getYoloPasses(): array
{
$useStatementPass = new UseStatementPass();
$namespacePass = new NamespacePass($this);
@@ -211,8 +208,6 @@ class CodeCleaner
$traverser->traverse($stmts);
} catch (\Throwable $e) {
// Don't care.
- } catch (\Exception $e) {
- // Still don't care.
}
}
@@ -244,10 +239,8 @@ class CodeCleaner
* Check whether a given backtrace frame is a call to Psy\debug.
*
* @param array $stackFrame
- *
- * @return bool
*/
- private static function isDebugCall(array $stackFrame)
+ private static function isDebugCall(array $stackFrame): bool
{
$class = isset($stackFrame['class']) ? $stackFrame['class'] : null;
$function = isset($stackFrame['function']) ? $stackFrame['function'] : null;
@@ -266,7 +259,7 @@ class CodeCleaner
*
* @return string|false Cleaned PHP code, False if the input is incomplete
*/
- public function clean(array $codeLines, $requireSemicolons = false)
+ public function clean(array $codeLines, bool $requireSemicolons = false)
{
$stmts = $this->parse('parser->parse($code);
@@ -357,7 +348,7 @@ class CodeCleaner
}
}
- private function parseErrorIsEOF(\PhpParser\Error $e)
+ private function parseErrorIsEOF(\PhpParser\Error $e): bool
{
$msg = $e->getRawMessage();
@@ -373,10 +364,8 @@ class CodeCleaner
*
* @param \PhpParser\Error $e
* @param string $code
- *
- * @return bool
*/
- private function parseErrorIsUnclosedString(\PhpParser\Error $e, $code)
+ private function parseErrorIsUnclosedString(\PhpParser\Error $e, string $code): bool
{
if ($e->getRawMessage() !== 'Syntax error, unexpected T_ENCAPSED_AND_WHITESPACE') {
return false;
@@ -384,19 +373,19 @@ class CodeCleaner
try {
$this->parser->parse($code."';");
- } catch (\Exception $e) {
+ } catch (\Throwable $e) {
return false;
}
return true;
}
- private function parseErrorIsUnterminatedComment(\PhpParser\Error $e, $code)
+ private function parseErrorIsUnterminatedComment(\PhpParser\Error $e, $code): bool
{
return $e->getRawMessage() === 'Unterminated comment';
}
- private function parseErrorIsTrailingComma(\PhpParser\Error $e, $code)
+ private function parseErrorIsTrailingComma(\PhpParser\Error $e, $code): bool
{
return ($e->getRawMessage() === 'A trailing comma is not allowed here') && (\substr(\rtrim($code), -1) === ',');
}
diff --git a/vendor/psy/psysh/src/CodeCleaner/AbstractClassPass.php b/vendor/psy/psysh/src/CodeCleaner/AbstractClassPass.php
index 4c0c859d0..af32fca25 100644
--- a/vendor/psy/psysh/src/CodeCleaner/AbstractClassPass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/AbstractClassPass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -28,6 +28,8 @@ class AbstractClassPass extends CodeCleanerPass
* @throws FatalErrorException if the node is an abstract function with a body
*
* @param Node $node
+ *
+ * @return int|Node|null Replacement node (or special return value)
*/
public function enterNode(Node $node)
{
@@ -51,6 +53,8 @@ class AbstractClassPass extends CodeCleanerPass
* @throws FatalErrorException if the node is a non-abstract class with abstract methods
*
* @param Node $node
+ *
+ * @return int|Node|Node[]|null Replacement node (or special return value)
*/
public function leaveNode(Node $node)
{
diff --git a/vendor/psy/psysh/src/CodeCleaner/AssignThisVariablePass.php b/vendor/psy/psysh/src/CodeCleaner/AssignThisVariablePass.php
index ed3b4c812..0a884f0cf 100644
--- a/vendor/psy/psysh/src/CodeCleaner/AssignThisVariablePass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/AssignThisVariablePass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -29,6 +29,8 @@ class AssignThisVariablePass extends CodeCleanerPass
* @throws FatalErrorException if the user assign the `$this` variable
*
* @param Node $node
+ *
+ * @return int|Node|null Replacement node (or special return value)
*/
public function enterNode(Node $node)
{
diff --git a/vendor/psy/psysh/src/CodeCleaner/CallTimePassByReferencePass.php b/vendor/psy/psysh/src/CodeCleaner/CallTimePassByReferencePass.php
index e686d1799..3efaa6267 100644
--- a/vendor/psy/psysh/src/CodeCleaner/CallTimePassByReferencePass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/CallTimePassByReferencePass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -15,6 +15,7 @@ use PhpParser\Node;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticCall;
+use PhpParser\Node\VariadicPlaceholder;
use Psy\Exception\FatalErrorException;
/**
@@ -34,6 +35,8 @@ class CallTimePassByReferencePass extends CodeCleanerPass
* @throws FatalErrorException if the user used call-time pass-by-reference
*
* @param Node $node
+ *
+ * @return int|Node|null Replacement node (or special return value)
*/
public function enterNode(Node $node)
{
@@ -42,6 +45,10 @@ class CallTimePassByReferencePass extends CodeCleanerPass
}
foreach ($node->args as $arg) {
+ if ($arg instanceof VariadicPlaceholder) {
+ continue;
+ }
+
if ($arg->byRef) {
throw new FatalErrorException(self::EXCEPTION_MESSAGE, 0, \E_ERROR, null, $node->getLine());
}
diff --git a/vendor/psy/psysh/src/CodeCleaner/CalledClassPass.php b/vendor/psy/psysh/src/CodeCleaner/CalledClassPass.php
index 1e85ae359..b1dd00e10 100644
--- a/vendor/psy/psysh/src/CodeCleaner/CalledClassPass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/CalledClassPass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -17,6 +17,7 @@ use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Trait_;
+use PhpParser\Node\VariadicPlaceholder;
use Psy\Exception\ErrorException;
/**
@@ -29,6 +30,8 @@ class CalledClassPass extends CodeCleanerPass
/**
* @param array $nodes
+ *
+ * @return Node[]|null Array of nodes
*/
public function beforeTraverse(array $nodes)
{
@@ -39,6 +42,8 @@ class CalledClassPass extends CodeCleanerPass
* @throws ErrorException if get_class or get_called_class is called without an object from outside a class
*
* @param Node $node
+ *
+ * @return int|Node|null Replacement node (or special return value)
*/
public function enterNode(Node $node)
{
@@ -68,6 +73,8 @@ class CalledClassPass extends CodeCleanerPass
/**
* @param Node $node
+ *
+ * @return int|Node|Node[]|null Replacement node (or special return value)
*/
public function leaveNode(Node $node)
{
@@ -76,8 +83,12 @@ class CalledClassPass extends CodeCleanerPass
}
}
- private function isNull(Node $node)
+ private function isNull(Node $node): bool
{
+ if ($node instanceof VariadicPlaceholder) {
+ return false;
+ }
+
return $node->value instanceof ConstFetch && \strtolower($node->value->name) === 'null';
}
}
diff --git a/vendor/psy/psysh/src/CodeCleaner/CodeCleanerPass.php b/vendor/psy/psysh/src/CodeCleaner/CodeCleanerPass.php
index 7d80ac896..244c9d4e8 100644
--- a/vendor/psy/psysh/src/CodeCleaner/CodeCleanerPass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/CodeCleanerPass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
diff --git a/vendor/psy/psysh/src/CodeCleaner/EmptyArrayDimFetchPass.php b/vendor/psy/psysh/src/CodeCleaner/EmptyArrayDimFetchPass.php
index 60f5c5641..d4dd6777c 100644
--- a/vendor/psy/psysh/src/CodeCleaner/EmptyArrayDimFetchPass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/EmptyArrayDimFetchPass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -25,6 +25,9 @@ class EmptyArrayDimFetchPass extends CodeCleanerPass
private $theseOnesAreFine = [];
+ /**
+ * @return Node[]|null Array of nodes
+ */
public function beforeTraverse(array $nodes)
{
$this->theseOnesAreFine = [];
@@ -34,6 +37,8 @@ class EmptyArrayDimFetchPass extends CodeCleanerPass
* @throws FatalErrorException if the user used empty empty array dim fetch outside of assignment
*
* @param Node $node
+ *
+ * @return int|Node|null Replacement node (or special return value)
*/
public function enterNode(Node $node)
{
diff --git a/vendor/psy/psysh/src/CodeCleaner/ExitPass.php b/vendor/psy/psysh/src/CodeCleaner/ExitPass.php
index 6571bb755..e58a8d68a 100644
--- a/vendor/psy/psysh/src/CodeCleaner/ExitPass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/ExitPass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -23,6 +23,8 @@ class ExitPass extends CodeCleanerPass
* Converts exit calls to BreakExceptions.
*
* @param \PhpParser\Node $node
+ *
+ * @return int|Node|Node[]|null Replacement node (or special return value)
*/
public function leaveNode(Node $node)
{
diff --git a/vendor/psy/psysh/src/CodeCleaner/FinalClassPass.php b/vendor/psy/psysh/src/CodeCleaner/FinalClassPass.php
index 1051f07e9..889176f05 100644
--- a/vendor/psy/psysh/src/CodeCleaner/FinalClassPass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/FinalClassPass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -24,6 +24,8 @@ class FinalClassPass extends CodeCleanerPass
/**
* @param array $nodes
+ *
+ * @return Node[]|null Array of nodes
*/
public function beforeTraverse(array $nodes)
{
@@ -34,6 +36,8 @@ class FinalClassPass extends CodeCleanerPass
* @throws FatalErrorException if the node is a class that extends a final class
*
* @param Node $node
+ *
+ * @return int|Node|null Replacement node (or special return value)
*/
public function enterNode(Node $node)
{
@@ -54,10 +58,8 @@ class FinalClassPass extends CodeCleanerPass
/**
* @param string $name Class name
- *
- * @return bool
*/
- private function isFinalClass($name)
+ private function isFinalClass(string $name): bool
{
if (!\class_exists($name)) {
return isset($this->finalClasses[\strtolower($name)]);
diff --git a/vendor/psy/psysh/src/CodeCleaner/FunctionContextPass.php b/vendor/psy/psysh/src/CodeCleaner/FunctionContextPass.php
index ea646e9c0..e73e85b3b 100644
--- a/vendor/psy/psysh/src/CodeCleaner/FunctionContextPass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/FunctionContextPass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -23,12 +23,17 @@ class FunctionContextPass extends CodeCleanerPass
/**
* @param array $nodes
+ *
+ * @return Node[]|null Array of nodes
*/
public function beforeTraverse(array $nodes)
{
$this->functionDepth = 0;
}
+ /**
+ * @return int|Node|null Replacement node (or special return value)
+ */
public function enterNode(Node $node)
{
if ($node instanceof FunctionLike) {
@@ -51,6 +56,8 @@ class FunctionContextPass extends CodeCleanerPass
/**
* @param \PhpParser\Node $node
+ *
+ * @return int|Node|Node[]|null Replacement node (or special return value)
*/
public function leaveNode(Node $node)
{
diff --git a/vendor/psy/psysh/src/CodeCleaner/FunctionReturnInWriteContextPass.php b/vendor/psy/psysh/src/CodeCleaner/FunctionReturnInWriteContextPass.php
index e3b764d7b..a0c74d012 100644
--- a/vendor/psy/psysh/src/CodeCleaner/FunctionReturnInWriteContextPass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/FunctionReturnInWriteContextPass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -19,6 +19,7 @@ use PhpParser\Node\Expr\Isset_;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Stmt\Unset_;
+use PhpParser\Node\VariadicPlaceholder;
use Psy\Exception\FatalErrorException;
/**
@@ -39,12 +40,18 @@ class FunctionReturnInWriteContextPass extends CodeCleanerPass
* @throws FatalErrorException if a value is assigned to a function
*
* @param Node $node
+ *
+ * @return int|Node|null Replacement node (or special return value)
*/
public function enterNode(Node $node)
{
if ($node instanceof Array_ || $this->isCallNode($node)) {
$items = $node instanceof Array_ ? $node->items : $node->args;
foreach ($items as $item) {
+ if ($item instanceof VariadicPlaceholder) {
+ continue;
+ }
+
if ($item && $item->byRef && $this->isCallNode($item->value)) {
throw new FatalErrorException(self::EXCEPTION_MESSAGE, 0, \E_ERROR, null, $node->getLine());
}
@@ -63,7 +70,7 @@ class FunctionReturnInWriteContextPass extends CodeCleanerPass
}
}
- private function isCallNode(Node $node)
+ private function isCallNode(Node $node): bool
{
return $node instanceof FuncCall || $node instanceof MethodCall || $node instanceof StaticCall;
}
diff --git a/vendor/psy/psysh/src/CodeCleaner/ImplicitReturnPass.php b/vendor/psy/psysh/src/CodeCleaner/ImplicitReturnPass.php
index 94f886337..04481db99 100644
--- a/vendor/psy/psysh/src/CodeCleaner/ImplicitReturnPass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/ImplicitReturnPass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -32,7 +32,7 @@ class ImplicitReturnPass extends CodeCleanerPass
*
* @return array
*/
- public function beforeTraverse(array $nodes)
+ public function beforeTraverse(array $nodes): array
{
return $this->addImplicitReturn($nodes);
}
@@ -42,7 +42,7 @@ class ImplicitReturnPass extends CodeCleanerPass
*
* @return array
*/
- private function addImplicitReturn(array $nodes)
+ private function addImplicitReturn(array $nodes): array
{
// If nodes is empty, it can't have a return value.
if (empty($nodes)) {
@@ -115,10 +115,8 @@ class ImplicitReturnPass extends CodeCleanerPass
* we'll exclude them here.
*
* @param Node $node
- *
- * @return bool
*/
- private static function isNonExpressionStmt(Node $node)
+ private static function isNonExpressionStmt(Node $node): bool
{
return $node instanceof Stmt &&
!$node instanceof Expression &&
diff --git a/vendor/psy/psysh/src/CodeCleaner/InstanceOfPass.php b/vendor/psy/psysh/src/CodeCleaner/InstanceOfPass.php
index a976df6c4..f5cc704a4 100644
--- a/vendor/psy/psysh/src/CodeCleaner/InstanceOfPass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/InstanceOfPass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -43,6 +43,8 @@ class InstanceOfPass extends CodeCleanerPass
* @throws FatalErrorException if a scalar or a non-class constant is given
*
* @param Node $node
+ *
+ * @return int|Node|null Replacement node (or special return value)
*/
public function enterNode(Node $node)
{
diff --git a/vendor/psy/psysh/src/CodeCleaner/IssetPass.php b/vendor/psy/psysh/src/CodeCleaner/IssetPass.php
index d0be550e4..2729bea1c 100644
--- a/vendor/psy/psysh/src/CodeCleaner/IssetPass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/IssetPass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -31,6 +31,8 @@ class IssetPass extends CodeCleanerPass
* @throws FatalErrorException
*
* @param Node $node
+ *
+ * @return int|Node|null Replacement node (or special return value)
*/
public function enterNode(Node $node)
{
diff --git a/vendor/psy/psysh/src/CodeCleaner/LabelContextPass.php b/vendor/psy/psysh/src/CodeCleaner/LabelContextPass.php
index c640de862..f34424d5c 100644
--- a/vendor/psy/psysh/src/CodeCleaner/LabelContextPass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/LabelContextPass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -41,6 +41,8 @@ class LabelContextPass extends CodeCleanerPass
/**
* @param array $nodes
+ *
+ * @return Node[]|null Array of nodes
*/
public function beforeTraverse(array $nodes)
{
@@ -49,6 +51,9 @@ class LabelContextPass extends CodeCleanerPass
$this->labelGotos = [];
}
+ /**
+ * @return int|Node|null Replacement node (or special return value)
+ */
public function enterNode(Node $node)
{
if ($node instanceof FunctionLike) {
@@ -71,6 +76,8 @@ class LabelContextPass extends CodeCleanerPass
/**
* @param \PhpParser\Node $node
+ *
+ * @return int|Node|Node[]|null Replacement node (or special return value)
*/
public function leaveNode(Node $node)
{
@@ -79,6 +86,9 @@ class LabelContextPass extends CodeCleanerPass
}
}
+ /**
+ * @return Node[]|null Array of nodes
+ */
public function afterTraverse(array $nodes)
{
foreach ($this->labelGotos as $name => $line) {
diff --git a/vendor/psy/psysh/src/CodeCleaner/LeavePsyshAlonePass.php b/vendor/psy/psysh/src/CodeCleaner/LeavePsyshAlonePass.php
index 2c2823863..67ba68b16 100644
--- a/vendor/psy/psysh/src/CodeCleaner/LeavePsyshAlonePass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/LeavePsyshAlonePass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -26,6 +26,8 @@ class LeavePsyshAlonePass extends CodeCleanerPass
* @throws RuntimeException if the user is messing with $__psysh__
*
* @param Node $node
+ *
+ * @return int|Node|null Replacement node (or special return value)
*/
public function enterNode(Node $node)
{
diff --git a/vendor/psy/psysh/src/CodeCleaner/ListPass.php b/vendor/psy/psysh/src/CodeCleaner/ListPass.php
index ef1d63bdd..a44ba003d 100644
--- a/vendor/psy/psysh/src/CodeCleaner/ListPass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/ListPass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -42,6 +42,8 @@ class ListPass extends CodeCleanerPass
* @throws ParseErrorException if the user used empty with anything but a variable
*
* @param Node $node
+ *
+ * @return int|Node|null Replacement node (or special return value)
*/
public function enterNode(Node $node)
{
@@ -94,10 +96,8 @@ class ListPass extends CodeCleanerPass
* Validate whether a given item in an array is valid for short assignment.
*
* @param Expr $item
- *
- * @return bool
*/
- private static function isValidArrayItem(Expr $item)
+ private static function isValidArrayItem(Expr $item): bool
{
$value = ($item instanceof ArrayItem) ? $item->value : $item;
diff --git a/vendor/psy/psysh/src/CodeCleaner/LoopContextPass.php b/vendor/psy/psysh/src/CodeCleaner/LoopContextPass.php
index 44582baa8..c41d4b8a5 100644
--- a/vendor/psy/psysh/src/CodeCleaner/LoopContextPass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/LoopContextPass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -32,6 +32,8 @@ class LoopContextPass extends CodeCleanerPass
/**
* {@inheritdoc}
+ *
+ * @return Node[]|null Array of nodes
*/
public function beforeTraverse(array $nodes)
{
@@ -45,6 +47,8 @@ class LoopContextPass extends CodeCleanerPass
* @throws FatalErrorException if the node is a break or continue and has an argument less than 1
*
* @param Node $node
+ *
+ * @return int|Node|null Replacement node (or special return value)
*/
public function enterNode(Node $node)
{
@@ -87,6 +91,8 @@ class LoopContextPass extends CodeCleanerPass
/**
* @param Node $node
+ *
+ * @return int|Node|Node[]|null Replacement node (or special return value)
*/
public function leaveNode(Node $node)
{
diff --git a/vendor/psy/psysh/src/CodeCleaner/MagicConstantsPass.php b/vendor/psy/psysh/src/CodeCleaner/MagicConstantsPass.php
index adf92fba1..3c468af09 100644
--- a/vendor/psy/psysh/src/CodeCleaner/MagicConstantsPass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/MagicConstantsPass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
diff --git a/vendor/psy/psysh/src/CodeCleaner/NamespaceAwarePass.php b/vendor/psy/psysh/src/CodeCleaner/NamespaceAwarePass.php
index 55318fede..ba82f9d8d 100644
--- a/vendor/psy/psysh/src/CodeCleaner/NamespaceAwarePass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/NamespaceAwarePass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -29,6 +29,8 @@ abstract class NamespaceAwarePass extends CodeCleanerPass
* use afterTraverse or call parent::beforeTraverse() when overloading.
*
* Reset the namespace and the current scope before beginning analysis
+ *
+ * @return Node[]|null Array of nodes
*/
public function beforeTraverse(array $nodes)
{
@@ -41,6 +43,8 @@ abstract class NamespaceAwarePass extends CodeCleanerPass
* leaveNode or call parent::enterNode() when overloading
*
* @param Node $node
+ *
+ * @return int|Node|null Replacement node (or special return value)
*/
public function enterNode(Node $node)
{
@@ -53,10 +57,8 @@ abstract class NamespaceAwarePass extends CodeCleanerPass
* Get a fully-qualified name (class, function, interface, etc).
*
* @param mixed $name
- *
- * @return string
*/
- protected function getFullyQualifiedName($name)
+ protected function getFullyQualifiedName($name): string
{
if ($name instanceof FullyQualifiedName) {
return \implode('\\', $name->parts);
diff --git a/vendor/psy/psysh/src/CodeCleaner/NamespacePass.php b/vendor/psy/psysh/src/CodeCleaner/NamespacePass.php
index 1f11072ef..470f0fa41 100644
--- a/vendor/psy/psysh/src/CodeCleaner/NamespacePass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/NamespacePass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -11,6 +11,7 @@
namespace Psy\CodeCleaner;
+use PhpParser\Node;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt\Namespace_;
use Psy\CodeCleaner;
@@ -46,6 +47,8 @@ class NamespacePass extends CodeCleanerPass
* is encountered.
*
* @param array $nodes
+ *
+ * @return Node[]|null Array of nodes
*/
public function beforeTraverse(array $nodes)
{
diff --git a/vendor/psy/psysh/src/CodeCleaner/NoReturnValue.php b/vendor/psy/psysh/src/CodeCleaner/NoReturnValue.php
index d9c920bc7..53f30a221 100644
--- a/vendor/psy/psysh/src/CodeCleaner/NoReturnValue.php
+++ b/vendor/psy/psysh/src/CodeCleaner/NoReturnValue.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -25,10 +25,8 @@ class NoReturnValue
{
/**
* Get PhpParser AST expression for creating a new NoReturnValue.
- *
- * @return \PhpParser\Node\Expr\New_
*/
- public static function create()
+ public static function create(): New_
{
return new New_(new FullyQualifiedName(self::class));
}
diff --git a/vendor/psy/psysh/src/CodeCleaner/PassableByReferencePass.php b/vendor/psy/psysh/src/CodeCleaner/PassableByReferencePass.php
index 8d7a8bfaa..9a911e4be 100644
--- a/vendor/psy/psysh/src/CodeCleaner/PassableByReferencePass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/PassableByReferencePass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -34,6 +34,8 @@ class PassableByReferencePass extends CodeCleanerPass
* @throws FatalErrorException if non-variables are passed by reference
*
* @param Node $node
+ *
+ * @return int|Node|null Replacement node (or special return value)
*/
public function enterNode(Node $node)
{
@@ -68,7 +70,7 @@ class PassableByReferencePass extends CodeCleanerPass
}
}
- private function isPassableByReference(Node $arg)
+ private function isPassableByReference(Node $arg): bool
{
// Unpacked arrays can be passed by reference
if ($arg->value instanceof Array_) {
diff --git a/vendor/psy/psysh/src/CodeCleaner/RequirePass.php b/vendor/psy/psysh/src/CodeCleaner/RequirePass.php
index 4f7c36abe..15cb3a0a7 100644
--- a/vendor/psy/psysh/src/CodeCleaner/RequirePass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/RequirePass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -29,6 +29,8 @@ class RequirePass extends CodeCleanerPass
/**
* {@inheritdoc}
+ *
+ * @return int|Node|null Replacement node (or special return value)
*/
public function enterNode(Node $origNode)
{
@@ -73,7 +75,7 @@ class RequirePass extends CodeCleanerPass
*
* @return string Exactly the same as $file, unless $file collides with a path in the currently running phar
*/
- public static function resolve($file, $lineNumber = null)
+ public static function resolve($file, $lineNumber = null): string
{
$file = (string) $file;
@@ -115,12 +117,12 @@ class RequirePass extends CodeCleanerPass
return $file;
}
- private function isRequireNode(Node $node)
+ private function isRequireNode(Node $node): bool
{
return $node instanceof Include_ && \in_array($node->type, self::$requireTypes);
}
- private static function getIncludePath()
+ private static function getIncludePath(): array
{
if (\PATH_SEPARATOR === ':') {
return \preg_split('#:(?!//)#', \get_include_path());
diff --git a/vendor/psy/psysh/src/CodeCleaner/ReturnTypePass.php b/vendor/psy/psysh/src/CodeCleaner/ReturnTypePass.php
index 6a43ba42c..626e5a625 100644
--- a/vendor/psy/psysh/src/CodeCleaner/ReturnTypePass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/ReturnTypePass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -18,6 +18,7 @@ use PhpParser\Node\Identifier;
use PhpParser\Node\NullableType;
use PhpParser\Node\Stmt\Function_;
use PhpParser\Node\Stmt\Return_;
+use PhpParser\Node\UnionType;
use Psy\Exception\FatalErrorException;
/**
@@ -41,6 +42,8 @@ class ReturnTypePass extends CodeCleanerPass
/**
* {@inheritdoc}
+ *
+ * @return int|Node|null Replacement node (or special return value)
*/
public function enterNode(Node $node)
{
@@ -86,6 +89,8 @@ class ReturnTypePass extends CodeCleanerPass
/**
* {@inheritdoc}
+ *
+ * @return int|Node|Node[]|null Replacement node (or special return value)
*/
public function leaveNode(Node $node)
{
@@ -98,13 +103,17 @@ class ReturnTypePass extends CodeCleanerPass
}
}
- private function isFunctionNode(Node $node)
+ private function isFunctionNode(Node $node): bool
{
return $node instanceof Function_ || $node instanceof Closure;
}
- private function typeName(Node $node)
+ private function typeName(Node $node): string
{
+ if ($node instanceof UnionType) {
+ return \implode('|', \array_map([$this, 'typeName'], $node->types));
+ }
+
if ($node instanceof NullableType) {
return \strtolower($node->type->name);
}
diff --git a/vendor/psy/psysh/src/CodeCleaner/StrictTypesPass.php b/vendor/psy/psysh/src/CodeCleaner/StrictTypesPass.php
index d0fe4c3f4..13c35b66d 100644
--- a/vendor/psy/psysh/src/CodeCleaner/StrictTypesPass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/StrictTypesPass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -11,6 +11,7 @@
namespace Psy\CodeCleaner;
+use PhpParser\Node;
use PhpParser\Node\Identifier;
use PhpParser\Node\Scalar\LNumber;
use PhpParser\Node\Stmt\Declare_;
@@ -32,12 +33,6 @@ class StrictTypesPass extends CodeCleanerPass
const EXCEPTION_MESSAGE = 'strict_types declaration must have 0 or 1 as its value';
private $strictTypes = false;
- private $atLeastPhp7;
-
- public function __construct()
- {
- $this->atLeastPhp7 = \version_compare(\PHP_VERSION, '7.0', '>=');
- }
/**
* If this is a standalone strict types declaration, remember it for later.
@@ -48,13 +43,11 @@ class StrictTypesPass extends CodeCleanerPass
* @throws FatalErrorException if an invalid `strict_types` declaration is found
*
* @param array $nodes
+ *
+ * @return Node[]|null Array of nodes
*/
public function beforeTraverse(array $nodes)
{
- if (!$this->atLeastPhp7) {
- return; // @codeCoverageIgnore
- }
-
$prependStrictTypes = $this->strictTypes;
foreach ($nodes as $node) {
diff --git a/vendor/psy/psysh/src/CodeCleaner/UseStatementPass.php b/vendor/psy/psysh/src/CodeCleaner/UseStatementPass.php
index 112728a10..862785139 100644
--- a/vendor/psy/psysh/src/CodeCleaner/UseStatementPass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/UseStatementPass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -44,13 +44,15 @@ class UseStatementPass extends CodeCleanerPass
* work like you'd expect.
*
* @param Node $node
+ *
+ * @return int|Node|null Replacement node (or special return value)
*/
public function enterNode(Node $node)
{
if ($node instanceof Namespace_) {
// If this is the same namespace as last namespace, let's do ourselves
// a favor and reload all the aliases...
- if (\strtolower($node->name) === \strtolower($this->lastNamespace)) {
+ if (\strtolower($node->name ?: '') === \strtolower($this->lastNamespace ?: '')) {
$this->aliases = $this->lastAliases;
}
}
@@ -63,6 +65,8 @@ class UseStatementPass extends CodeCleanerPass
* remembered aliases to the code.
*
* @param Node $node
+ *
+ * @return int|Node|Node[]|null Replacement node (or special return value)
*/
public function leaveNode(Node $node)
{
diff --git a/vendor/psy/psysh/src/CodeCleaner/ValidClassNamePass.php b/vendor/psy/psysh/src/CodeCleaner/ValidClassNamePass.php
index 11f69f5c9..d068ff50f 100644
--- a/vendor/psy/psysh/src/CodeCleaner/ValidClassNamePass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/ValidClassNamePass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -13,9 +13,6 @@ namespace Psy\CodeCleaner;
use PhpParser\Node;
use PhpParser\Node\Expr;
-use PhpParser\Node\Expr\ClassConstFetch;
-use PhpParser\Node\Expr\New_;
-use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Expr\Ternary;
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Class_;
@@ -40,12 +37,6 @@ class ValidClassNamePass extends NamespaceAwarePass
const TRAIT_TYPE = 'trait';
private $conditionalScopes = 0;
- private $atLeastPhp7;
-
- public function __construct()
- {
- $this->atLeastPhp7 = \version_compare(\PHP_VERSION, '7.0', '>=');
- }
/**
* Validate class, interface and trait definitions.
@@ -55,6 +46,8 @@ class ValidClassNamePass extends NamespaceAwarePass
* trait methods.
*
* @param Node $node
+ *
+ * @return int|Node|null Replacement node (or special return value)
*/
public function enterNode(Node $node)
{
@@ -78,15 +71,9 @@ class ValidClassNamePass extends NamespaceAwarePass
}
/**
- * Validate `new` expressions, class constant fetches, and static calls.
- *
- * @throws FatalErrorException if a class, interface or trait is referenced which does not exist
- * @throws FatalErrorException if a class extends something that is not a class
- * @throws FatalErrorException if a class implements something that is not an interface
- * @throws FatalErrorException if an interface extends something that is not an interface
- * @throws FatalErrorException if a class, interface or trait redefines an existing class, interface or trait name
- *
* @param Node $node
+ *
+ * @return int|Node|Node[]|null Replacement node (or special return value)
*/
public function leaveNode(Node $node)
{
@@ -95,19 +82,9 @@ class ValidClassNamePass extends NamespaceAwarePass
return;
}
-
- if (!$this->atLeastPhp7) {
- if ($node instanceof New_) {
- $this->validateNewExpression($node);
- } elseif ($node instanceof ClassConstFetch) {
- $this->validateClassConstFetchExpression($node);
- } elseif ($node instanceof StaticCall) {
- $this->validateStaticCallExpression($node);
- }
- }
}
- private static function isConditional(Node $node)
+ private static function isConditional(Node $node): bool
{
return $node instanceof If_ ||
$node instanceof While_ ||
@@ -151,50 +128,6 @@ class ValidClassNamePass extends NamespaceAwarePass
$this->ensureCanDefine($stmt, self::TRAIT_TYPE);
}
- /**
- * Validate a `new` expression.
- *
- * @param New_ $stmt
- */
- protected function validateNewExpression(New_ $stmt)
- {
- // if class name is an expression or an anonymous class, give it a pass for now
- if (!$stmt->class instanceof Expr && !$stmt->class instanceof Class_) {
- $this->ensureClassExists($this->getFullyQualifiedName($stmt->class), $stmt);
- }
- }
-
- /**
- * Validate a class constant fetch expression's class.
- *
- * @param ClassConstFetch $stmt
- */
- protected function validateClassConstFetchExpression(ClassConstFetch $stmt)
- {
- // there is no need to check exists for ::class const
- if (\strtolower($stmt->name) === 'class') {
- return;
- }
-
- // if class name is an expression, give it a pass for now
- if (!$stmt->class instanceof Expr) {
- $this->ensureClassOrInterfaceExists($this->getFullyQualifiedName($stmt->class), $stmt);
- }
- }
-
- /**
- * Validate a class constant fetch expression's class.
- *
- * @param StaticCall $stmt
- */
- protected function validateStaticCallExpression(StaticCall $stmt)
- {
- // if class name is an expression, give it a pass for now
- if (!$stmt->class instanceof Expr) {
- $this->ensureMethodExists($this->getFullyQualifiedName($stmt->class), $stmt->name, $stmt);
- }
- }
-
/**
* Ensure that no class, interface or trait name collides with a new definition.
*
@@ -203,7 +136,7 @@ class ValidClassNamePass extends NamespaceAwarePass
* @param Stmt $stmt
* @param string $scopeType
*/
- protected function ensureCanDefine(Stmt $stmt, $scopeType = self::CLASS_TYPE)
+ protected function ensureCanDefine(Stmt $stmt, string $scopeType = self::CLASS_TYPE)
{
// Anonymous classes don't have a name, and uniqueness shouldn't be enforced.
if ($stmt->name === null) {
@@ -239,7 +172,7 @@ class ValidClassNamePass extends NamespaceAwarePass
* @param string $name
* @param Stmt $stmt
*/
- protected function ensureClassExists($name, $stmt)
+ protected function ensureClassExists(string $name, Stmt $stmt)
{
if (!$this->classExists($name)) {
throw $this->createError(\sprintf('Class \'%s\' not found', $name), $stmt);
@@ -254,7 +187,7 @@ class ValidClassNamePass extends NamespaceAwarePass
* @param string $name
* @param Stmt $stmt
*/
- protected function ensureClassOrInterfaceExists($name, $stmt)
+ protected function ensureClassOrInterfaceExists(string $name, Stmt $stmt)
{
if (!$this->classExists($name) && !$this->interfaceExists($name)) {
throw $this->createError(\sprintf('Class \'%s\' not found', $name), $stmt);
@@ -269,7 +202,7 @@ class ValidClassNamePass extends NamespaceAwarePass
* @param string $name
* @param Stmt $stmt
*/
- protected function ensureClassOrTraitExists($name, $stmt)
+ protected function ensureClassOrTraitExists(string $name, Stmt $stmt)
{
if (!$this->classExists($name) && !$this->traitExists($name)) {
throw $this->createError(\sprintf('Class \'%s\' not found', $name), $stmt);
@@ -285,7 +218,7 @@ class ValidClassNamePass extends NamespaceAwarePass
* @param string $name
* @param Stmt $stmt
*/
- protected function ensureMethodExists($class, $name, $stmt)
+ protected function ensureMethodExists(string $class, string $name, Stmt $stmt)
{
$this->ensureClassOrTraitExists($class, $stmt);
@@ -317,7 +250,7 @@ class ValidClassNamePass extends NamespaceAwarePass
* @param Interface_[] $interfaces
* @param Stmt $stmt
*/
- protected function ensureInterfacesExist($interfaces, $stmt)
+ protected function ensureInterfacesExist(array $interfaces, Stmt $stmt)
{
foreach ($interfaces as $interface) {
/** @var string $name */
@@ -334,11 +267,11 @@ class ValidClassNamePass extends NamespaceAwarePass
* @deprecated No longer used. Scope type should be passed into ensureCanDefine directly.
* @codeCoverageIgnore
*
- * @param Stmt $stmt
+ * @throws FatalErrorException
*
- * @return string
+ * @param Stmt $stmt
*/
- protected function getScopeType(Stmt $stmt)
+ protected function getScopeType(Stmt $stmt): string
{
if ($stmt instanceof Class_) {
return self::CLASS_TYPE;
@@ -347,6 +280,8 @@ class ValidClassNamePass extends NamespaceAwarePass
} elseif ($stmt instanceof Trait_) {
return self::TRAIT_TYPE;
}
+
+ throw $this->createError('Unsupported statement type', $stmt);
}
/**
@@ -355,10 +290,8 @@ class ValidClassNamePass extends NamespaceAwarePass
* Gives `self`, `static` and `parent` a free pass.
*
* @param string $name
- *
- * @return bool
*/
- protected function classExists($name)
+ protected function classExists(string $name): bool
{
// Give `self`, `static` and `parent` a pass. This will actually let
// some errors through, since we're not checking whether the keyword is
@@ -374,10 +307,8 @@ class ValidClassNamePass extends NamespaceAwarePass
* Check whether an interface exists, or has been defined in the current code snippet.
*
* @param string $name
- *
- * @return bool
*/
- protected function interfaceExists($name)
+ protected function interfaceExists(string $name): bool
{
return \interface_exists($name) || $this->findInScope($name) === self::INTERFACE_TYPE;
}
@@ -386,10 +317,8 @@ class ValidClassNamePass extends NamespaceAwarePass
* Check whether a trait exists, or has been defined in the current code snippet.
*
* @param string $name
- *
- * @return bool
*/
- protected function traitExists($name)
+ protected function traitExists(string $name): bool
{
return \trait_exists($name) || $this->findInScope($name) === self::TRAIT_TYPE;
}
@@ -401,7 +330,7 @@ class ValidClassNamePass extends NamespaceAwarePass
*
* @return string|null
*/
- protected function findInScope($name)
+ protected function findInScope(string $name)
{
$name = \strtolower($name);
if (isset($this->currentScope[$name])) {
@@ -414,10 +343,8 @@ class ValidClassNamePass extends NamespaceAwarePass
*
* @param string $msg
* @param Stmt $stmt
- *
- * @return FatalErrorException
*/
- protected function createError($msg, $stmt)
+ protected function createError(string $msg, Stmt $stmt): FatalErrorException
{
return new FatalErrorException($msg, 0, \E_ERROR, null, $stmt->getLine());
}
diff --git a/vendor/psy/psysh/src/CodeCleaner/ValidConstantPass.php b/vendor/psy/psysh/src/CodeCleaner/ValidConstantPass.php
deleted file mode 100644
index 8e69813a3..000000000
--- a/vendor/psy/psysh/src/CodeCleaner/ValidConstantPass.php
+++ /dev/null
@@ -1,90 +0,0 @@
-name->parts) > 1) {
- $name = $this->getFullyQualifiedName($node->name);
- if (!\defined($name)) {
- $msg = \sprintf('Undefined constant %s', $name);
- throw new FatalErrorException($msg, 0, \E_ERROR, null, $node->getLine());
- }
- } elseif ($node instanceof ClassConstFetch) {
- $this->validateClassConstFetchExpression($node);
- }
- }
-
- /**
- * Validate a class constant fetch expression.
- *
- * @throws FatalErrorException if a class constant is not defined
- *
- * @param ClassConstFetch $stmt
- */
- protected function validateClassConstFetchExpression(ClassConstFetch $stmt)
- {
- // For PHP Parser 4.x
- $constName = $stmt->name instanceof Identifier ? $stmt->name->toString() : $stmt->name;
-
- // give the `class` pseudo-constant a pass
- if ($constName === 'class') {
- return;
- }
-
- // if class name is an expression, give it a pass for now
- if (!$stmt->class instanceof Expr) {
- $className = $this->getFullyQualifiedName($stmt->class);
-
- // if the class doesn't exist, don't throw an exception… it might be
- // defined in the same line it's used or something stupid like that.
- if (\class_exists($className) || \interface_exists($className)) {
- $refl = new \ReflectionClass($className);
- if (!$refl->hasConstant($constName)) {
- $constType = \class_exists($className) ? 'Class' : 'Interface';
- $msg = \sprintf('%s constant \'%s::%s\' not found', $constType, $className, $constName);
- throw new FatalErrorException($msg, 0, \E_ERROR, null, $stmt->getLine());
- }
- }
- }
- }
-}
diff --git a/vendor/psy/psysh/src/CodeCleaner/ValidConstructorPass.php b/vendor/psy/psysh/src/CodeCleaner/ValidConstructorPass.php
index 44928cc8f..817104a61 100644
--- a/vendor/psy/psysh/src/CodeCleaner/ValidConstructorPass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/ValidConstructorPass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -35,6 +35,9 @@ class ValidConstructorPass extends CodeCleanerPass
{
private $namespace;
+ /**
+ * @return Node[]|null Array of nodes
+ */
public function beforeTraverse(array $nodes)
{
$this->namespace = [];
@@ -47,6 +50,8 @@ class ValidConstructorPass extends CodeCleanerPass
* @throws FatalErrorException the constructor function has a return type
*
* @param Node $node
+ *
+ * @return int|Node|null Replacement node (or special return value)
*/
public function enterNode(Node $node)
{
diff --git a/vendor/psy/psysh/src/CodeCleaner/ValidFunctionNamePass.php b/vendor/psy/psysh/src/CodeCleaner/ValidFunctionNamePass.php
index 9c1e669f1..7703d7d37 100644
--- a/vendor/psy/psysh/src/CodeCleaner/ValidFunctionNamePass.php
+++ b/vendor/psy/psysh/src/CodeCleaner/ValidFunctionNamePass.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -12,9 +12,6 @@
namespace Psy\CodeCleaner;
use PhpParser\Node;
-use PhpParser\Node\Expr;
-use PhpParser\Node\Expr\FuncCall;
-use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt\Do_;
use PhpParser\Node\Stmt\Function_;
use PhpParser\Node\Stmt\If_;
@@ -35,7 +32,11 @@ class ValidFunctionNamePass extends NamespaceAwarePass
/**
* Store newly defined function names on the way in, to allow recursion.
*
+ * @throws FatalErrorException if a function is redefined in a non-conditional scope
+ *
* @param Node $node
+ *
+ * @return int|Node|null Replacement node (or special return value)
*/
public function enterNode(Node $node)
{
@@ -61,29 +62,14 @@ class ValidFunctionNamePass extends NamespaceAwarePass
}
/**
- * Validate that function calls will succeed.
- *
- * @throws FatalErrorException if a function is redefined
- * @throws FatalErrorException if the function name is a string (not an expression) and is not defined
- *
* @param Node $node
+ *
+ * @return int|Node|Node[]|null Replacement node (or special return value)
*/
public function leaveNode(Node $node)
{
if (self::isConditional($node)) {
$this->conditionalScopes--;
- } elseif ($node instanceof FuncCall) {
- // if function name is an expression or a variable, give it a pass for now.
- $name = $node->name;
- if (!$name instanceof Expr && !$name instanceof Variable) {
- $shortName = \implode('\\', $name->parts);
- $fullName = $this->getFullyQualifiedName($name);
- $inScope = isset($this->currentScope[\strtolower($fullName)]);
- if (!$inScope && !\function_exists($shortName) && !\function_exists($fullName)) {
- $message = \sprintf('Call to undefined function %s()', $name);
- throw new FatalErrorException($message, 0, \E_ERROR, null, $node->getLine());
- }
- }
}
}
diff --git a/vendor/psy/psysh/src/Command/BufferCommand.php b/vendor/psy/psysh/src/Command/BufferCommand.php
index 6e16ac536..81d8ff912 100644
--- a/vendor/psy/psysh/src/Command/BufferCommand.php
+++ b/vendor/psy/psysh/src/Command/BufferCommand.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -11,6 +11,7 @@
namespace Psy\Command;
+use Psy\Exception\RuntimeException;
use Psy\Output\ShellOutput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
@@ -46,12 +47,19 @@ HELP
/**
* {@inheritdoc}
+ *
+ * @return int 0 if everything went fine, or an exit code
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
- $buf = $this->getApplication()->getCodeBuffer();
+ $app = $this->getApplication();
+ if (!$app instanceof \Psy\Shell) {
+ throw new RuntimeException('Buffer command requires a \Psy\Shell application');
+ }
+
+ $buf = $app->getCodeBuffer();
if ($input->getOption('clear')) {
- $this->getApplication()->resetCodeBuffer();
+ $app->resetCodeBuffer();
$output->writeln($this->formatLines($buf, 'urgent'), ShellOutput::NUMBER_LINES);
} else {
$output->writeln($this->formatLines($buf), ShellOutput::NUMBER_LINES);
@@ -68,7 +76,7 @@ HELP
*
* @return array Formatted strings
*/
- protected function formatLines(array $lines, $type = 'return')
+ protected function formatLines(array $lines, string $type = 'return'): array
{
$template = \sprintf('<%s>%%s%s>', $type, $type);
diff --git a/vendor/psy/psysh/src/Command/ClearCommand.php b/vendor/psy/psysh/src/Command/ClearCommand.php
index d20abab12..baca9af03 100644
--- a/vendor/psy/psysh/src/Command/ClearCommand.php
+++ b/vendor/psy/psysh/src/Command/ClearCommand.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -41,6 +41,8 @@ HELP
/**
* {@inheritdoc}
+ *
+ * @return int 0 if everything went fine, or an exit code
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
diff --git a/vendor/psy/psysh/src/Command/Command.php b/vendor/psy/psysh/src/Command/Command.php
index 2a58eece8..182e358c4 100644
--- a/vendor/psy/psysh/src/Command/Command.php
+++ b/vendor/psy/psysh/src/Command/Command.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -43,7 +43,7 @@ abstract class Command extends BaseCommand
/**
* {@inheritdoc}
*/
- public function asText()
+ public function asText(): string
{
$messages = [
'Usage: ',
@@ -74,7 +74,7 @@ abstract class Command extends BaseCommand
/**
* {@inheritdoc}
*/
- private function getArguments()
+ private function getArguments(): array
{
$hidden = $this->getHiddenArguments();
@@ -86,9 +86,9 @@ abstract class Command extends BaseCommand
/**
* These arguments will be excluded from help output.
*
- * @return array
+ * @return string[]
*/
- protected function getHiddenArguments()
+ protected function getHiddenArguments(): array
{
return ['command'];
}
@@ -96,7 +96,7 @@ abstract class Command extends BaseCommand
/**
* {@inheritdoc}
*/
- private function getOptions()
+ private function getOptions(): array
{
$hidden = $this->getHiddenOptions();
@@ -108,29 +108,25 @@ abstract class Command extends BaseCommand
/**
* These options will be excluded from help output.
*
- * @return array
+ * @return string[]
*/
- protected function getHiddenOptions()
+ protected function getHiddenOptions(): array
{
return ['verbose'];
}
/**
* Format command aliases as text..
- *
- * @return string
*/
- private function aliasesAsText()
+ private function aliasesAsText(): string
{
return 'Aliases: '.\implode(', ', $this->getAliases()).' '.\PHP_EOL;
}
/**
* Format command arguments as text.
- *
- * @return string
*/
- private function argumentsAsText()
+ private function argumentsAsText(): string
{
$max = $this->getMaxWidth();
$messages = [];
@@ -147,7 +143,7 @@ abstract class Command extends BaseCommand
$description = \str_replace("\n", "\n".\str_pad('', $max + 2, ' '), $argument->getDescription());
- $messages[] = \sprintf(" %-${max}s %s%s", $argument->getName(), $description, $default);
+ $messages[] = \sprintf(" %-{$max}s %s%s", $argument->getName(), $description, $default);
}
$messages[] = '';
@@ -158,10 +154,8 @@ abstract class Command extends BaseCommand
/**
* Format options as text.
- *
- * @return string
*/
- private function optionsAsText()
+ private function optionsAsText(): string
{
$max = $this->getMaxWidth();
$messages = [];
@@ -182,7 +176,7 @@ abstract class Command extends BaseCommand
$optionMax = $max - \strlen($option->getName()) - 2;
$messages[] = \sprintf(
- " %s %-${optionMax}s%s%s%s",
+ " %s %-{$optionMax}s%s%s%s",
'--'.$option->getName(),
$option->getShortcut() ? \sprintf('(-%s) ', $option->getShortcut()) : '',
$description,
@@ -199,10 +193,8 @@ abstract class Command extends BaseCommand
/**
* Calculate the maximum padding width for a set of lines.
- *
- * @return int
*/
- private function getMaxWidth()
+ private function getMaxWidth(): int
{
$max = 0;
@@ -226,10 +218,8 @@ abstract class Command extends BaseCommand
* Format an option default as text.
*
* @param mixed $default
- *
- * @return string
*/
- private function formatDefaultValue($default)
+ private function formatDefaultValue($default): string
{
if (\is_array($default) && $default === \array_values($default)) {
return \sprintf("['%s']", \implode("', '", $default));
@@ -273,10 +263,8 @@ abstract class Command extends BaseCommand
/**
* Legacy fallback for getTable.
- *
- * @return TableHelper
*/
- protected function getTableHelper()
+ protected function getTableHelper(): TableHelper
{
$table = $this->getApplication()->getHelperSet()->get('table');
diff --git a/vendor/psy/psysh/src/Command/DocCommand.php b/vendor/psy/psysh/src/Command/DocCommand.php
index 40fbd0f82..5360832a3 100644
--- a/vendor/psy/psysh/src/Command/DocCommand.php
+++ b/vendor/psy/psysh/src/Command/DocCommand.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -14,6 +14,7 @@ namespace Psy\Command;
use Psy\Formatter\DocblockFormatter;
use Psy\Formatter\SignatureFormatter;
use Psy\Input\CodeArgument;
+use Psy\Output\ShellOutput;
use Psy\Reflection\ReflectionClassConstant;
use Psy\Reflection\ReflectionConstant_;
use Psy\Reflection\ReflectionLanguageConstruct;
@@ -59,6 +60,8 @@ HELP
/**
* {@inheritdoc}
+ *
+ * @return int 0 if everything went fine, or an exit code
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
@@ -169,9 +172,9 @@ HELP
* yield Reflectors for the same-named method or property on all traits and
* parent classes.
*
- * @return Generator a whole bunch of \Reflector instances
+ * @return \Generator a whole bunch of \Reflector instances
*/
- private function getParentReflectors($reflector)
+ private function getParentReflectors($reflector): \Generator
{
$seenClasses = [];
@@ -242,9 +245,10 @@ HELP
private function getManualDocById($id)
{
if ($db = $this->getApplication()->getManualDb()) {
- return $db
- ->query(\sprintf('SELECT doc FROM php_manual WHERE id = %s', $db->quote($id)))
- ->fetchColumn(0);
+ $result = $db->query(\sprintf('SELECT doc FROM php_manual WHERE id = %s', $db->quote($id)));
+ if ($result !== false) {
+ return $result->fetchColumn(0);
+ }
}
}
}
diff --git a/vendor/psy/psysh/src/Command/DumpCommand.php b/vendor/psy/psysh/src/Command/DumpCommand.php
index 9e279e761..c44bb40a8 100644
--- a/vendor/psy/psysh/src/Command/DumpCommand.php
+++ b/vendor/psy/psysh/src/Command/DumpCommand.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -66,6 +66,8 @@ HELP
/**
* {@inheritdoc}
+ *
+ * @return int 0 if everything went fine, or an exit code
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
@@ -87,7 +89,7 @@ HELP
*
* @return mixed
*/
- protected function resolveTarget($name)
+ protected function resolveTarget(string $name)
{
@\trigger_error('`resolveTarget` is deprecated; use `resolveCode` instead.', \E_USER_DEPRECATED);
diff --git a/vendor/psy/psysh/src/Command/EditCommand.php b/vendor/psy/psysh/src/Command/EditCommand.php
index 6b3f98b1e..af2914d58 100644
--- a/vendor/psy/psysh/src/Command/EditCommand.php
+++ b/vendor/psy/psysh/src/Command/EditCommand.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -74,6 +74,8 @@ class EditCommand extends Command implements ContextAware
* @param InputInterface $input
* @param OutputInterface $output
*
+ * @return int 0 if everything went fine, or an exit code
+ *
* @throws \InvalidArgumentException when both exec and no-exec flags are given or if a given variable is not found in the current context
* @throws \UnexpectedValueException if file_get_contents on the edited file returns false instead of a string
*/
@@ -112,10 +114,8 @@ class EditCommand extends Command implements ContextAware
* @param bool $execOption
* @param bool $noExecOption
* @param string|null $filePath
- *
- * @return bool
*/
- private function shouldExecuteFile($execOption, $noExecOption, $filePath)
+ private function shouldExecuteFile(bool $execOption, bool $noExecOption, string $filePath = null): bool
{
if ($execOption) {
return true;
@@ -136,7 +136,7 @@ class EditCommand extends Command implements ContextAware
*
* @throws \InvalidArgumentException If the variable is not found in the current context
*/
- private function extractFilePath($fileArgument)
+ private function extractFilePath(string $fileArgument = null)
{
// If the file argument was a variable, get it from the context
if ($fileArgument !== null &&
@@ -152,11 +152,9 @@ class EditCommand extends Command implements ContextAware
* @param string $filePath
* @param bool $shouldRemoveFile
*
- * @return string
- *
* @throws \UnexpectedValueException if file_get_contents on $filePath returns false instead of a string
*/
- private function editFile($filePath, $shouldRemoveFile)
+ private function editFile(string $filePath, bool $shouldRemoveFile): string
{
$escapedFilePath = \escapeshellarg($filePath);
$editor = (isset($_SERVER['EDITOR']) && $_SERVER['EDITOR']) ? $_SERVER['EDITOR'] : 'nano';
diff --git a/vendor/psy/psysh/src/Command/ExitCommand.php b/vendor/psy/psysh/src/Command/ExitCommand.php
index 3e51a3462..01f72d9f9 100644
--- a/vendor/psy/psysh/src/Command/ExitCommand.php
+++ b/vendor/psy/psysh/src/Command/ExitCommand.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -44,6 +44,8 @@ HELP
/**
* {@inheritdoc}
+ *
+ * @return int 0 if everything went fine, or an exit code
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
diff --git a/vendor/psy/psysh/src/Command/HelpCommand.php b/vendor/psy/psysh/src/Command/HelpCommand.php
index d3cdb9402..5aa72fa6c 100644
--- a/vendor/psy/psysh/src/Command/HelpCommand.php
+++ b/vendor/psy/psysh/src/Command/HelpCommand.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -46,13 +46,15 @@ class HelpCommand extends Command
*
* @param Command $command
*/
- public function setCommand($command)
+ public function setCommand(Command $command)
{
$this->command = $command;
}
/**
* {@inheritdoc}
+ *
+ * @return int 0 if everything went fine, or an exit code
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
diff --git a/vendor/psy/psysh/src/Command/HistoryCommand.php b/vendor/psy/psysh/src/Command/HistoryCommand.php
index 22318a4dc..94306e401 100644
--- a/vendor/psy/psysh/src/Command/HistoryCommand.php
+++ b/vendor/psy/psysh/src/Command/HistoryCommand.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -90,6 +90,8 @@ HELP
/**
* {@inheritdoc}
+ *
+ * @return int 0 if everything went fine, or an exit code
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
@@ -156,7 +158,7 @@ HELP
*
* @return array [ start, end ]
*/
- private function extractRange($range)
+ private function extractRange(string $range): array
{
if (\preg_match('/^\d+$/', $range)) {
return [$range, $range + 1];
@@ -176,13 +178,13 @@ HELP
/**
* Retrieve a slice of the readline history.
*
- * @param string $show
- * @param string $head
- * @param string $tail
+ * @param string|null $show
+ * @param string|null $head
+ * @param string|null $tail
*
- * @return array A slilce of history
+ * @return array A slice of history
*/
- private function getHistorySlice($show, $head, $tail)
+ private function getHistorySlice($show, $head, $tail): array
{
$history = $this->readline->listHistory();
@@ -241,7 +243,7 @@ HELP
$this->readline->clearHistory();
}
- public static function escape($string)
+ public static function escape(string $string): string
{
return OutputFormatter::escape($string);
}
diff --git a/vendor/psy/psysh/src/Command/ListCommand.php b/vendor/psy/psysh/src/Command/ListCommand.php
index bcc1f33ff..41f56c9c4 100644
--- a/vendor/psy/psysh/src/Command/ListCommand.php
+++ b/vendor/psy/psysh/src/Command/ListCommand.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -112,6 +112,8 @@ HELP
/**
* {@inheritdoc}
+ *
+ * @return int 0 if everything went fine, or an exit code
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
@@ -223,10 +225,8 @@ HELP
* Format an item name given its visibility.
*
* @param array $item
- *
- * @return string
*/
- private function formatItemName($item)
+ private function formatItemName(array $item): string
{
return \sprintf('<%s>%s%s>', $item['style'], OutputFormatter::escape($item['name']), $item['style']);
}
diff --git a/vendor/psy/psysh/src/Command/ListCommand/ClassConstantEnumerator.php b/vendor/psy/psysh/src/Command/ListCommand/ClassConstantEnumerator.php
index 3b5b0dfaa..2ae84b123 100644
--- a/vendor/psy/psysh/src/Command/ListCommand/ClassConstantEnumerator.php
+++ b/vendor/psy/psysh/src/Command/ListCommand/ClassConstantEnumerator.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -22,7 +22,7 @@ class ClassConstantEnumerator extends Enumerator
/**
* {@inheritdoc}
*/
- protected function listItems(InputInterface $input, \Reflector $reflector = null, $target = null)
+ protected function listItems(InputInterface $input, \Reflector $reflector = null, $target = null): array
{
// only list constants when a Reflector is present.
if ($reflector === null) {
@@ -56,12 +56,12 @@ class ClassConstantEnumerator extends Enumerator
/**
* Get defined constants for the given class or object Reflector.
*
- * @param \Reflector $reflector
- * @param bool $noInherit Exclude inherited constants
+ * @param \ReflectionClass $reflector
+ * @param bool $noInherit Exclude inherited constants
*
* @return array
*/
- protected function getConstants(\Reflector $reflector, $noInherit = false)
+ protected function getConstants(\ReflectionClass $reflector, bool $noInherit = false): array
{
$className = $reflector->getName();
@@ -88,7 +88,7 @@ class ClassConstantEnumerator extends Enumerator
*
* @return array
*/
- protected function prepareConstants(array $constants)
+ protected function prepareConstants(array $constants): array
{
// My kingdom for a generator.
$ret = [];
@@ -110,10 +110,8 @@ class ClassConstantEnumerator extends Enumerator
* Get a label for the particular kind of "class" represented.
*
* @param \ReflectionClass $reflector
- *
- * @return string
*/
- protected function getKindLabel(\ReflectionClass $reflector)
+ protected function getKindLabel(\ReflectionClass $reflector): string
{
if ($reflector->isInterface()) {
return 'Interface Constants';
diff --git a/vendor/psy/psysh/src/Command/ListCommand/ClassEnumerator.php b/vendor/psy/psysh/src/Command/ListCommand/ClassEnumerator.php
index c939a0bb8..cf80ba726 100644
--- a/vendor/psy/psysh/src/Command/ListCommand/ClassEnumerator.php
+++ b/vendor/psy/psysh/src/Command/ListCommand/ClassEnumerator.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -22,7 +22,7 @@ class ClassEnumerator extends Enumerator
/**
* {@inheritdoc}
*/
- protected function listItems(InputInterface $input, \Reflector $reflector = null, $target = null)
+ protected function listItems(InputInterface $input, \Reflector $reflector = null, $target = null): array
{
// if we have a reflector, ensure that it's a namespace reflector
if (($target !== null || $reflector !== null) && !$reflector instanceof ReflectionNamespace) {
@@ -66,7 +66,7 @@ class ClassEnumerator extends Enumerator
*
* @return array
*/
- protected function filterClasses($key, $classes, $internal, $user, $prefix = null)
+ protected function filterClasses(string $key, array $classes, bool $internal, bool $user, string $prefix = null): array
{
$ret = [];
@@ -110,7 +110,7 @@ class ClassEnumerator extends Enumerator
*
* @return array
*/
- protected function prepareClasses(array $classes)
+ protected function prepareClasses(array $classes): array
{
\natcasesort($classes);
diff --git a/vendor/psy/psysh/src/Command/ListCommand/ConstantEnumerator.php b/vendor/psy/psysh/src/Command/ListCommand/ConstantEnumerator.php
index 7471c2d23..c8346e946 100644
--- a/vendor/psy/psysh/src/Command/ListCommand/ConstantEnumerator.php
+++ b/vendor/psy/psysh/src/Command/ListCommand/ConstantEnumerator.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -49,7 +49,7 @@ class ConstantEnumerator extends Enumerator
/**
* {@inheritdoc}
*/
- protected function listItems(InputInterface $input, \Reflector $reflector = null, $target = null)
+ protected function listItems(InputInterface $input, \Reflector $reflector = null, $target = null): array
{
// if we have a reflector, ensure that it's a namespace reflector
if (($target !== null || $reflector !== null) && !$reflector instanceof ReflectionNamespace) {
@@ -122,7 +122,7 @@ class ConstantEnumerator extends Enumerator
*
* @return array
*/
- protected function getConstants($category = null)
+ protected function getConstants(string $category = null): array
{
if (!$category) {
return \get_defined_constants();
@@ -133,7 +133,7 @@ class ConstantEnumerator extends Enumerator
if ($category === 'internal') {
unset($consts['user']);
- return \call_user_func_array('array_merge', \array_values($consts));
+ return \array_merge(...\array_values($consts));
}
foreach ($consts as $key => $value) {
@@ -152,7 +152,7 @@ class ConstantEnumerator extends Enumerator
*
* @return array
*/
- protected function prepareConstants(array $constants)
+ protected function prepareConstants(array $constants): array
{
// My kingdom for a generator.
$ret = [];
diff --git a/vendor/psy/psysh/src/Command/ListCommand/Enumerator.php b/vendor/psy/psysh/src/Command/ListCommand/Enumerator.php
index f6705d08e..ecc4613f8 100644
--- a/vendor/psy/psysh/src/Command/ListCommand/Enumerator.php
+++ b/vendor/psy/psysh/src/Command/ListCommand/Enumerator.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -54,7 +54,7 @@ abstract class Enumerator
*
* @return array
*/
- public function enumerate(InputInterface $input, \Reflector $reflector = null, $target = null)
+ public function enumerate(InputInterface $input, \Reflector $reflector = null, $target = null): array
{
$this->filter->bind($input);
@@ -82,7 +82,7 @@ abstract class Enumerator
*
* @return array
*/
- abstract protected function listItems(InputInterface $input, \Reflector $reflector = null, $target = null);
+ abstract protected function listItems(InputInterface $input, \Reflector $reflector = null, $target = null): array;
protected function showItem($name)
{
diff --git a/vendor/psy/psysh/src/Command/ListCommand/FunctionEnumerator.php b/vendor/psy/psysh/src/Command/ListCommand/FunctionEnumerator.php
index c651c707f..beccb4bdc 100644
--- a/vendor/psy/psysh/src/Command/ListCommand/FunctionEnumerator.php
+++ b/vendor/psy/psysh/src/Command/ListCommand/FunctionEnumerator.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -22,7 +22,7 @@ class FunctionEnumerator extends Enumerator
/**
* {@inheritdoc}
*/
- protected function listItems(InputInterface $input, \Reflector $reflector = null, $target = null)
+ protected function listItems(InputInterface $input, \Reflector $reflector = null, $target = null): array
{
// if we have a reflector, ensure that it's a namespace reflector
if (($target !== null || $reflector !== null) && !$reflector instanceof ReflectionNamespace) {
@@ -67,7 +67,7 @@ class FunctionEnumerator extends Enumerator
*
* @return array
*/
- protected function getFunctions($type = null)
+ protected function getFunctions(string $type = null): array
{
$funcs = \get_defined_functions();
@@ -86,7 +86,7 @@ class FunctionEnumerator extends Enumerator
*
* @return array
*/
- protected function prepareFunctions(array $functions, $prefix = null)
+ protected function prepareFunctions(array $functions, string $prefix = null): array
{
\natcasesort($functions);
@@ -105,8 +105,8 @@ class FunctionEnumerator extends Enumerator
'style' => self::IS_FUNCTION,
'value' => $this->presentSignature($name),
];
- } catch (\Exception $e) {
- // Ignore failures. HHVM does this sometimes for internal functions.
+ } catch (\Throwable $e) {
+ // Ignore failures.
}
}
}
diff --git a/vendor/psy/psysh/src/Command/ListCommand/GlobalVariableEnumerator.php b/vendor/psy/psysh/src/Command/ListCommand/GlobalVariableEnumerator.php
index a2a4d83f7..fab59704d 100644
--- a/vendor/psy/psysh/src/Command/ListCommand/GlobalVariableEnumerator.php
+++ b/vendor/psy/psysh/src/Command/ListCommand/GlobalVariableEnumerator.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -21,7 +21,7 @@ class GlobalVariableEnumerator extends Enumerator
/**
* {@inheritdoc}
*/
- protected function listItems(InputInterface $input, \Reflector $reflector = null, $target = null)
+ protected function listItems(InputInterface $input, \Reflector $reflector = null, $target = null): array
{
// only list globals when no Reflector is present.
if ($reflector !== null || $target !== null) {
@@ -49,7 +49,7 @@ class GlobalVariableEnumerator extends Enumerator
*
* @return array
*/
- protected function getGlobals()
+ protected function getGlobals(): array
{
global $GLOBALS;
@@ -71,7 +71,7 @@ class GlobalVariableEnumerator extends Enumerator
*
* @return array
*/
- protected function prepareGlobals($globals)
+ protected function prepareGlobals(array $globals): array
{
// My kingdom for a generator.
$ret = [];
diff --git a/vendor/psy/psysh/src/Command/ListCommand/MethodEnumerator.php b/vendor/psy/psysh/src/Command/ListCommand/MethodEnumerator.php
index 66b988c7e..68c74dd4f 100644
--- a/vendor/psy/psysh/src/Command/ListCommand/MethodEnumerator.php
+++ b/vendor/psy/psysh/src/Command/ListCommand/MethodEnumerator.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -21,7 +21,7 @@ class MethodEnumerator extends Enumerator
/**
* {@inheritdoc}
*/
- protected function listItems(InputInterface $input, \Reflector $reflector = null, $target = null)
+ protected function listItems(InputInterface $input, \Reflector $reflector = null, $target = null): array
{
// only list methods when a Reflector is present.
if ($reflector === null) {
@@ -55,13 +55,13 @@ class MethodEnumerator extends Enumerator
/**
* Get defined methods for the given class or object Reflector.
*
- * @param bool $showAll Include private and protected methods
- * @param \Reflector $reflector
- * @param bool $noInherit Exclude inherited methods
+ * @param bool $showAll Include private and protected methods
+ * @param \ReflectionClass $reflector
+ * @param bool $noInherit Exclude inherited methods
*
* @return array
*/
- protected function getMethods($showAll, \Reflector $reflector, $noInherit = false)
+ protected function getMethods(bool $showAll, \ReflectionClass $reflector, bool $noInherit = false): array
{
$className = $reflector->getName();
@@ -90,7 +90,7 @@ class MethodEnumerator extends Enumerator
*
* @return array
*/
- protected function prepareMethods(array $methods)
+ protected function prepareMethods(array $methods): array
{
// My kingdom for a generator.
$ret = [];
@@ -112,10 +112,8 @@ class MethodEnumerator extends Enumerator
* Get a label for the particular kind of "class" represented.
*
* @param \ReflectionClass $reflector
- *
- * @return string
*/
- protected function getKindLabel(\ReflectionClass $reflector)
+ protected function getKindLabel(\ReflectionClass $reflector): string
{
if ($reflector->isInterface()) {
return 'Interface Methods';
@@ -130,10 +128,8 @@ class MethodEnumerator extends Enumerator
* Get output style for the given method's visibility.
*
* @param \ReflectionMethod $method
- *
- * @return string
*/
- private function getVisibilityStyle(\ReflectionMethod $method)
+ private function getVisibilityStyle(\ReflectionMethod $method): string
{
if ($method->isPublic()) {
return self::IS_PUBLIC;
diff --git a/vendor/psy/psysh/src/Command/ListCommand/PropertyEnumerator.php b/vendor/psy/psysh/src/Command/ListCommand/PropertyEnumerator.php
index a414726d6..dfde8eafd 100644
--- a/vendor/psy/psysh/src/Command/ListCommand/PropertyEnumerator.php
+++ b/vendor/psy/psysh/src/Command/ListCommand/PropertyEnumerator.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -21,7 +21,7 @@ class PropertyEnumerator extends Enumerator
/**
* {@inheritdoc}
*/
- protected function listItems(InputInterface $input, \Reflector $reflector = null, $target = null)
+ protected function listItems(InputInterface $input, \Reflector $reflector = null, $target = null): array
{
// only list properties when a Reflector is present.
@@ -56,13 +56,13 @@ class PropertyEnumerator extends Enumerator
/**
* Get defined properties for the given class or object Reflector.
*
- * @param bool $showAll Include private and protected properties
- * @param \Reflector $reflector
- * @param bool $noInherit Exclude inherited properties
+ * @param bool $showAll Include private and protected properties
+ * @param \ReflectionClass $reflector
+ * @param bool $noInherit Exclude inherited properties
*
* @return array
*/
- protected function getProperties($showAll, \Reflector $reflector, $noInherit = false)
+ protected function getProperties(bool $showAll, \ReflectionClass $reflector, bool $noInherit = false): array
{
$className = $reflector->getName();
@@ -89,7 +89,7 @@ class PropertyEnumerator extends Enumerator
*
* @return array
*/
- protected function prepareProperties(array $properties, $target = null)
+ protected function prepareProperties(array $properties, $target = null): array
{
// My kingdom for a generator.
$ret = [];
@@ -112,10 +112,8 @@ class PropertyEnumerator extends Enumerator
* Get a label for the particular kind of "class" represented.
*
* @param \ReflectionClass $reflector
- *
- * @return string
*/
- protected function getKindLabel(\ReflectionClass $reflector)
+ protected function getKindLabel(\ReflectionClass $reflector): string
{
if (\method_exists($reflector, 'isTrait') && $reflector->isTrait()) {
return 'Trait Properties';
@@ -128,10 +126,8 @@ class PropertyEnumerator extends Enumerator
* Get output style for the given property's visibility.
*
* @param \ReflectionProperty $property
- *
- * @return string
*/
- private function getVisibilityStyle(\ReflectionProperty $property)
+ private function getVisibilityStyle(\ReflectionProperty $property): string
{
if ($property->isPublic()) {
return self::IS_PUBLIC;
@@ -147,11 +143,13 @@ class PropertyEnumerator extends Enumerator
*
* @param \ReflectionProperty $property
* @param mixed $target
- *
- * @return string
*/
- protected function presentValue(\ReflectionProperty $property, $target)
+ protected function presentValue(\ReflectionProperty $property, $target): string
{
+ if (!$target) {
+ return '';
+ }
+
// If $target is a class or trait (try to) get the default
// value for the property.
if (!\is_object($target)) {
@@ -163,7 +161,7 @@ class PropertyEnumerator extends Enumerator
return $this->presentRef($props[$property->name]).$suffix;
}
- } catch (\Exception $e) {
+ } catch (\Throwable $e) {
// Well, we gave it a shot.
}
diff --git a/vendor/psy/psysh/src/Command/ListCommand/VariableEnumerator.php b/vendor/psy/psysh/src/Command/ListCommand/VariableEnumerator.php
index 2cd0345fe..38f3f6023 100644
--- a/vendor/psy/psysh/src/Command/ListCommand/VariableEnumerator.php
+++ b/vendor/psy/psysh/src/Command/ListCommand/VariableEnumerator.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -45,7 +45,7 @@ class VariableEnumerator extends Enumerator
/**
* {@inheritdoc}
*/
- protected function listItems(InputInterface $input, \Reflector $reflector = null, $target = null)
+ protected function listItems(InputInterface $input, \Reflector $reflector = null, $target = null): array
{
// only list variables when no Reflector is present.
if ($reflector !== null || $target !== null) {
@@ -76,7 +76,7 @@ class VariableEnumerator extends Enumerator
*
* @return array
*/
- protected function getVariables($showAll)
+ protected function getVariables(bool $showAll): array
{
$scopeVars = $this->context->getAll();
\uksort($scopeVars, function ($a, $b) {
@@ -117,7 +117,7 @@ class VariableEnumerator extends Enumerator
*
* @return array
*/
- protected function prepareVariables(array $variables)
+ protected function prepareVariables(array $variables): array
{
// My kingdom for a generator.
$ret = [];
diff --git a/vendor/psy/psysh/src/Command/ParseCommand.php b/vendor/psy/psysh/src/Command/ParseCommand.php
index 2df2b9aa6..21005f338 100644
--- a/vendor/psy/psysh/src/Command/ParseCommand.php
+++ b/vendor/psy/psysh/src/Command/ParseCommand.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -90,23 +90,17 @@ class ParseCommand extends Command implements ContextAware, PresenterAware
*/
protected function configure()
{
- $definition = [
- new CodeArgument('code', CodeArgument::REQUIRED, 'PHP code to parse.'),
- new InputOption('depth', '', InputOption::VALUE_REQUIRED, 'Depth to parse.', 10),
- ];
-
- if ($this->parserFactory->hasKindsSupport()) {
- $msg = 'One of PhpParser\\ParserFactory constants: '
- .\implode(', ', ParserFactory::getPossibleKinds())
- ." (default is based on current interpreter's version).";
- $defaultKind = $this->parserFactory->getDefaultKind();
-
- $definition[] = new InputOption('kind', '', InputOption::VALUE_REQUIRED, $msg, $defaultKind);
- }
+ $kindMsg = 'One of PhpParser\\ParserFactory constants: '
+ .\implode(', ', ParserFactory::getPossibleKinds())
+ ." (default is based on current interpreter's version).";
$this
->setName('parse')
- ->setDefinition($definition)
+ ->setDefinition([
+ new CodeArgument('code', CodeArgument::REQUIRED, 'PHP code to parse.'),
+ new InputOption('depth', '', InputOption::VALUE_REQUIRED, 'Depth to parse.', 10),
+ new InputOption('kind', '', InputOption::VALUE_REQUIRED, $kindMsg, $this->parserFactory->getDefaultKind()),
+ ])
->setDescription('Parse PHP code and show the abstract syntax tree.')
->setHelp(
<<<'HELP'
@@ -132,7 +126,7 @@ HELP
$code = 'parserFactory->hasKindsSupport() ? $input->getOption('kind') : null;
+ $parserKind = $input->getOption('kind');
$depth = $input->getOption('depth');
$nodes = $this->parse($this->getParser($parserKind), $code);
$output->page($this->presenter->present($nodes, $depth));
@@ -150,7 +144,7 @@ HELP
*
* @return array Statements
*/
- private function parse(Parser $parser, $code)
+ private function parse(Parser $parser, string $code): array
{
try {
return $parser->parse($code);
@@ -168,10 +162,8 @@ HELP
* Get (or create) the Parser instance.
*
* @param string|null $kind One of Psy\ParserFactory constants (only for PHP parser 2.0 and above)
- *
- * @return Parser
*/
- private function getParser($kind = null)
+ private function getParser(string $kind = null): Parser
{
if (!\array_key_exists($kind, $this->parsers)) {
$this->parsers[$kind] = $this->parserFactory->createParser($kind);
diff --git a/vendor/psy/psysh/src/Command/PsyVersionCommand.php b/vendor/psy/psysh/src/Command/PsyVersionCommand.php
index 1355841f1..44e75283f 100644
--- a/vendor/psy/psysh/src/Command/PsyVersionCommand.php
+++ b/vendor/psy/psysh/src/Command/PsyVersionCommand.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
diff --git a/vendor/psy/psysh/src/Command/ReflectingCommand.php b/vendor/psy/psysh/src/Command/ReflectingCommand.php
index 47b779e21..b85b2c401 100644
--- a/vendor/psy/psysh/src/Command/ReflectingCommand.php
+++ b/vendor/psy/psysh/src/Command/ReflectingCommand.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -57,7 +57,7 @@ abstract class ReflectingCommand extends Command implements ContextAware
*
* @return array (class or instance name, member name, kind)
*/
- protected function getTarget($valueName)
+ protected function getTarget(string $valueName): array
{
$valueName = \trim($valueName);
$matches = [];
@@ -92,10 +92,8 @@ abstract class ReflectingCommand extends Command implements ContextAware
*
* @param string $name
* @param bool $includeFunctions (default: false)
- *
- * @return string
*/
- protected function resolveName($name, $includeFunctions = false)
+ protected function resolveName(string $name, bool $includeFunctions = false): string
{
$shell = $this->getApplication();
@@ -140,10 +138,10 @@ abstract class ReflectingCommand extends Command implements ContextAware
/**
* Check whether a given name could be a class name.
*/
- protected function couldBeClassName($name)
+ protected function couldBeClassName(string $name): bool
{
// Regex based on https://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class
- return \preg_match('/^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*(\\\\[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)*$/', $name);
+ return \preg_match('/^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*(\\\\[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)*$/', $name) === 1;
}
/**
@@ -153,7 +151,7 @@ abstract class ReflectingCommand extends Command implements ContextAware
*
* @return array (value, Reflector)
*/
- protected function getTargetAndReflector($valueName)
+ protected function getTargetAndReflector(string $valueName): array
{
list($value, $member, $kind) = $this->getTarget($valueName);
@@ -169,11 +167,11 @@ abstract class ReflectingCommand extends Command implements ContextAware
*
* @return mixed Variable value
*/
- protected function resolveCode($code)
+ protected function resolveCode(string $code)
{
try {
$value = $this->getApplication()->execute($code, true);
- } catch (\Exception $e) {
+ } catch (\Throwable $e) {
// Swallow all exceptions?
}
@@ -193,7 +191,7 @@ abstract class ReflectingCommand extends Command implements ContextAware
*
* @return object Variable instance
*/
- private function resolveObject($code)
+ private function resolveObject(string $code)
{
$value = $this->resolveCode($code);
@@ -211,7 +209,7 @@ abstract class ReflectingCommand extends Command implements ContextAware
*
* @return mixed Variable instance
*/
- protected function resolveInstance($name)
+ protected function resolveInstance(string $name)
{
@\trigger_error('`resolveInstance` is deprecated; use `resolveCode` instead.', \E_USER_DEPRECATED);
@@ -225,7 +223,7 @@ abstract class ReflectingCommand extends Command implements ContextAware
*
* @return mixed
*/
- protected function getScopeVariable($name)
+ protected function getScopeVariable(string $name)
{
return $this->context->get($name);
}
@@ -235,7 +233,7 @@ abstract class ReflectingCommand extends Command implements ContextAware
*
* @return array
*/
- protected function getScopeVariables()
+ protected function getScopeVariables(): array
{
return $this->context->getAll();
}
diff --git a/vendor/psy/psysh/src/Command/ShowCommand.php b/vendor/psy/psysh/src/Command/ShowCommand.php
index 564b3f710..ecb427cfb 100644
--- a/vendor/psy/psysh/src/Command/ShowCommand.php
+++ b/vendor/psy/psysh/src/Command/ShowCommand.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -69,6 +69,8 @@ HELP
/**
* {@inheritdoc}
+ *
+ * @return int 0 if everything went fine, or an exit code
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
@@ -122,7 +124,9 @@ HELP
]);
}
- return $output->page(CodeFormatter::formatCode($code));
+ $output->page(CodeFormatter::formatCode($code));
+
+ return;
} else {
throw $e;
}
@@ -193,7 +197,7 @@ HELP
));
}
- private function replaceCwd($file)
+ private function replaceCwd(string $file): string
{
if ($cwd = \getcwd()) {
$cwd = \rtrim($cwd, \DIRECTORY_SEPARATOR).\DIRECTORY_SEPARATOR;
@@ -252,7 +256,7 @@ HELP
if ($namespace = $refl->getNamespaceName()) {
$vars['__namespace'] = $namespace;
}
- } catch (\Exception $e) {
+ } catch (\Throwable $e) {
// oh well
}
} elseif (isset($context['function'])) {
@@ -263,7 +267,7 @@ HELP
if ($namespace = $refl->getNamespaceName()) {
$vars['__namespace'] = $namespace;
}
- } catch (\Exception $e) {
+ } catch (\Throwable $e) {
// oh well
}
}
@@ -288,7 +292,7 @@ HELP
$this->context->setCommandScopeVariables($vars);
}
- private function extractEvalFileAndLine($file)
+ private function extractEvalFileAndLine(string $file)
{
if (\preg_match('/(.*)\\((\\d+)\\) : eval\\(\\)\'d code$/', $file, $matches)) {
return [$matches[1], $matches[2]];
diff --git a/vendor/psy/psysh/src/Command/SudoCommand.php b/vendor/psy/psysh/src/Command/SudoCommand.php
index c55f1e4b1..cd9facbab 100644
--- a/vendor/psy/psysh/src/Command/SudoCommand.php
+++ b/vendor/psy/psysh/src/Command/SudoCommand.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -95,6 +95,8 @@ HELP
/**
* {@inheritdoc}
+ *
+ * @return int 0 if everything went fine, or an exit code
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
@@ -129,7 +131,7 @@ HELP
*
* @return array Statements
*/
- private function parse($code)
+ private function parse(string $code): array
{
try {
return $this->parser->parse($code);
diff --git a/vendor/psy/psysh/src/Command/ThrowUpCommand.php b/vendor/psy/psysh/src/Command/ThrowUpCommand.php
index d2a12b91c..ccca8776a 100644
--- a/vendor/psy/psysh/src/Command/ThrowUpCommand.php
+++ b/vendor/psy/psysh/src/Command/ThrowUpCommand.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -13,7 +13,6 @@ namespace Psy\Command;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\New_;
-use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Name\FullyQualified as FullyQualifiedName;
use PhpParser\Node\Scalar\String_;
@@ -87,12 +86,14 @@ HELP
/**
* {@inheritdoc}
*
+ * @return int 0 if everything went fine, or an exit code
+ *
* @throws \InvalidArgumentException if there is no exception to throw
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$args = $this->prepareArgs($input->getArgument('exception'));
- $throwStmt = new Throw_(new StaticCall(new FullyQualifiedName(ThrowUpException::class), 'fromThrowable', $args));
+ $throwStmt = new Throw_(new New_(new FullyQualifiedName(ThrowUpException::class), $args));
$throwCode = $this->printer->prettyPrint([$throwStmt]);
$shell = $this->getApplication();
@@ -112,7 +113,7 @@ HELP
*
* @return Arg[]
*/
- private function prepareArgs($code = null)
+ private function prepareArgs(string $code = null): array
{
if (!$code) {
// Default to last exception if nothing else was supplied
@@ -150,7 +151,7 @@ HELP
*
* @return array Statements
*/
- private function parse($code)
+ private function parse(string $code): array
{
try {
return $this->parser->parse($code);
diff --git a/vendor/psy/psysh/src/Command/TimeitCommand.php b/vendor/psy/psysh/src/Command/TimeitCommand.php
index 3a3f29e7c..82b9e0e72 100644
--- a/vendor/psy/psysh/src/Command/TimeitCommand.php
+++ b/vendor/psy/psysh/src/Command/TimeitCommand.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -76,6 +76,8 @@ HELP
/**
* {@inheritdoc}
+ *
+ * @return int 0 if everything went fine, or an exit code
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
@@ -164,10 +166,8 @@ HELP
* accurate times are recorded for just the code being executed.
*
* @param string $code
- *
- * @return string
*/
- private function instrumentCode($code)
+ private function instrumentCode(string $code): string
{
return $this->printer->prettyPrint($this->traverser->traverse($this->parse($code)));
}
@@ -179,7 +179,7 @@ HELP
*
* @return array Statements
*/
- private function parse($code)
+ private function parse(string $code): array
{
$code = 'filter, $count, $includePsy);
}
diff --git a/vendor/psy/psysh/src/Command/WhereamiCommand.php b/vendor/psy/psysh/src/Command/WhereamiCommand.php
index 913a9ef2a..0c0a6e9c2 100644
--- a/vendor/psy/psysh/src/Command/WhereamiCommand.php
+++ b/vendor/psy/psysh/src/Command/WhereamiCommand.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -67,7 +67,7 @@ HELP
*
* @return array
*/
- protected function trace()
+ protected function trace(): array
{
foreach (\array_reverse($this->backtrace) as $stackFrame) {
if ($this->isDebugCall($stackFrame)) {
@@ -78,7 +78,7 @@ HELP
return \end($this->backtrace);
}
- private static function isDebugCall(array $stackFrame)
+ private static function isDebugCall(array $stackFrame): bool
{
$class = isset($stackFrame['class']) ? $stackFrame['class'] : null;
$function = isset($stackFrame['function']) ? $stackFrame['function'] : null;
@@ -92,7 +92,7 @@ HELP
*
* @return array
*/
- protected function fileInfo()
+ protected function fileInfo(): array
{
$stackFrame = $this->trace();
if (\preg_match('/eval\(/', $stackFrame['file'])) {
@@ -109,6 +109,8 @@ HELP
/**
* {@inheritdoc}
+ *
+ * @return int 0 if everything went fine, or an exit code
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
@@ -142,10 +144,8 @@ HELP
* Replace the given directory from the start of a filepath.
*
* @param string $file
- *
- * @return string
*/
- private function replaceCwd($file)
+ private function replaceCwd(string $file): string
{
$cwd = \getcwd();
if ($cwd === false) {
diff --git a/vendor/psy/psysh/src/Command/WtfCommand.php b/vendor/psy/psysh/src/Command/WtfCommand.php
index 77c174ec2..3d967fc52 100644
--- a/vendor/psy/psysh/src/Command/WtfCommand.php
+++ b/vendor/psy/psysh/src/Command/WtfCommand.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -81,6 +81,8 @@ HELP
/**
* {@inheritdoc}
+ *
+ * @return int 0 if everything went fine, or an exit code
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
diff --git a/vendor/psy/psysh/src/ConfigPaths.php b/vendor/psy/psysh/src/ConfigPaths.php
index 4b40879ea..67fab9865 100644
--- a/vendor/psy/psysh/src/ConfigPaths.php
+++ b/vendor/psy/psysh/src/ConfigPaths.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -31,7 +31,7 @@ class ConfigPaths
* @param string[] $overrides Directory overrides
* @param EnvInterface $env
*/
- public function __construct($overrides = [], $env = null)
+ public function __construct(array $overrides = [], EnvInterface $env = null)
{
$this->overrideDirs($overrides);
$this->env = $env ?: new SuperglobalsEnv();
@@ -45,7 +45,7 @@ class ConfigPaths
*
* @param string[] $overrides Directory overrides
*/
- public function overrideDirs($overrides)
+ public function overrideDirs(array $overrides)
{
if (\array_key_exists('configDir', $overrides)) {
$this->configDir = $overrides['configDir'] ?: null;
@@ -108,7 +108,7 @@ class ConfigPaths
*
* @return string[]
*/
- public function configDirs()
+ public function configDirs(): array
{
if ($this->configDir !== null) {
return [$this->configDir];
@@ -122,7 +122,7 @@ class ConfigPaths
/**
* @deprecated
*/
- public static function getConfigDirs()
+ public static function getConfigDirs(): array
{
return (new self())->configDirs();
}
@@ -139,7 +139,7 @@ class ConfigPaths
*
* @return string[]
*/
- public static function getHomeConfigDirs()
+ public static function getHomeConfigDirs(): array
{
// Not quite the same, but this is deprecated anyway /shrug
return self::getConfigDirs();
@@ -154,10 +154,8 @@ class ConfigPaths
* everywhere else).
*
* @see self::homeConfigDir
- *
- * @return string
*/
- public function currentConfigDir()
+ public function currentConfigDir(): string
{
if ($this->configDir !== null) {
return $this->configDir;
@@ -177,7 +175,7 @@ class ConfigPaths
/**
* @deprecated
*/
- public static function getCurrentConfigDir()
+ public static function getCurrentConfigDir(): string
{
return (new self())->currentConfigDir();
}
@@ -189,7 +187,7 @@ class ConfigPaths
*
* @return string[]
*/
- public function configFiles(array $names)
+ public function configFiles(array $names): array
{
return $this->allRealFiles($this->configDirs(), $names);
}
@@ -197,7 +195,7 @@ class ConfigPaths
/**
* @deprecated
*/
- public static function getConfigFiles(array $names, $configDir = null)
+ public static function getConfigFiles(array $names, $configDir = null): array
{
return (new self(['configDir' => $configDir]))->configFiles($names);
}
@@ -214,7 +212,7 @@ class ConfigPaths
*
* @return string[]
*/
- public function dataDirs()
+ public function dataDirs(): array
{
if ($this->dataDir !== null) {
return [$this->dataDir];
@@ -229,7 +227,7 @@ class ConfigPaths
/**
* @deprecated
*/
- public static function getDataDirs()
+ public static function getDataDirs(): array
{
return (new self())->dataDirs();
}
@@ -241,7 +239,7 @@ class ConfigPaths
*
* @return string[]
*/
- public function dataFiles(array $names)
+ public function dataFiles(array $names): array
{
return $this->allRealFiles($this->dataDirs(), $names);
}
@@ -249,7 +247,7 @@ class ConfigPaths
/**
* @deprecated
*/
- public static function getDataFiles(array $names, $dataDir = null)
+ public static function getDataFiles(array $names, $dataDir = null): array
{
return (new self(['dataDir' => $dataDir]))->dataFiles($names);
}
@@ -258,10 +256,8 @@ class ConfigPaths
* Get a runtime directory.
*
* Defaults to `/psysh` inside the system's temp dir.
- *
- * @return string
*/
- public function runtimeDir()
+ public function runtimeDir(): string
{
if ($this->runtimeDir !== null) {
return $this->runtimeDir;
@@ -276,11 +272,45 @@ class ConfigPaths
/**
* @deprecated
*/
- public static function getRuntimeDir()
+ public static function getRuntimeDir(): string
{
return (new self())->runtimeDir();
}
+ /**
+ * Get a list of directories in PATH.
+ *
+ * If $PATH is unset/empty it defaults to '/usr/sbin:/usr/bin:/sbin:/bin'.
+ *
+ * @return string[]
+ */
+ public function pathDirs(): array
+ {
+ return $this->getEnvArray('PATH') ?: ['/usr/sbin', '/usr/bin', '/sbin', '/bin'];
+ }
+
+ /**
+ * Locate a command (an executable) in $PATH.
+ *
+ * Behaves like 'command -v COMMAND' or 'which COMMAND'.
+ * If $PATH is unset/empty it defaults to '/usr/sbin:/usr/bin:/sbin:/bin'.
+ *
+ * @param string $command the executable to locate
+ *
+ * @return string
+ */
+ public function which($command)
+ {
+ foreach ($this->pathDirs() as $path) {
+ $fullpath = $path.\DIRECTORY_SEPARATOR.$command;
+ if (@\is_file($fullpath) && @\is_executable($fullpath)) {
+ return $fullpath;
+ }
+ }
+
+ return null;
+ }
+
/**
* Get all PsySH directory name candidates given a list of base directories.
*
@@ -292,7 +322,7 @@ class ConfigPaths
*
* @return string[]
*/
- private function allDirNames(array $baseDirs)
+ private function allDirNames(array $baseDirs): array
{
$dirs = \array_map(function ($dir) {
return \strtr($dir, '\\', '/').'/psysh';
@@ -327,7 +357,7 @@ class ConfigPaths
*
* @return string[]
*/
- private function allRealFiles(array $dirNames, array $fileNames)
+ private function allRealFiles(array $dirNames, array $fileNames): array
{
$files = [];
foreach ($dirNames as $dir) {
@@ -351,7 +381,7 @@ class ConfigPaths
*
* @return bool False if directory exists but is not writeable, or cannot be created
*/
- public static function ensureDir($dir)
+ public static function ensureDir(string $dir): bool
{
if (!\is_dir($dir)) {
// Just try making it and see if it works
@@ -376,7 +406,7 @@ class ConfigPaths
*
* @return string|false Full path to $file, or false if file is not writable
*/
- public static function touchFileWithMkdir($file)
+ public static function touchFileWithMkdir(string $file)
{
if (\file_exists($file)) {
if (\is_writable($file)) {
@@ -405,7 +435,7 @@ class ConfigPaths
private function getEnvArray($key)
{
if ($value = $this->getEnv($key)) {
- return \explode(':', $value);
+ return \explode(\PATH_SEPARATOR, $value);
}
return null;
diff --git a/vendor/psy/psysh/src/Configuration.php b/vendor/psy/psysh/src/Configuration.php
index fbd28e6a1..ddb35ea65 100644
--- a/vendor/psy/psysh/src/Configuration.php
+++ b/vendor/psy/psysh/src/Configuration.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -16,6 +16,7 @@ use Psy\Exception\RuntimeException;
use Psy\ExecutionLoop\ProcessForker;
use Psy\Output\OutputPager;
use Psy\Output\ShellOutput;
+use Psy\Output\Theme;
use Psy\TabCompletion\AutoCompleter;
use Psy\VarDumper\Presenter;
use Psy\VersionUpdater\Checker;
@@ -56,6 +57,7 @@ class Configuration
'errorLoggingLevel',
'forceArrayIndexes',
'formatterStyles',
+ 'historyFile',
'historySize',
'interactiveMode',
'manualDbFile',
@@ -65,6 +67,7 @@ class Configuration
'requireSemicolons',
'runtimeDir',
'startupMessage',
+ 'theme',
'updateCheck',
'useBracketedPaste',
'usePcntl',
@@ -106,12 +109,16 @@ class Configuration
private $updateCheck;
private $startupMessage;
private $forceArrayIndexes = false;
+ /** @deprecated */
private $formatterStyles = [];
private $verbosity = self::VERBOSITY_NORMAL;
private $yolo = false;
+ /** @var Theme */
+ private $theme;
// services
private $readline;
+ /** @var ShellOutput */
private $output;
private $shell;
private $cleaner;
@@ -170,10 +177,8 @@ class Configuration
* @throws \InvalidArgumentException
*
* @param InputInterface $input
- *
- * @return self
*/
- public static function fromInput(InputInterface $input)
+ public static function fromInput(InputInterface $input): self
{
$config = new self(['configFile' => self::getConfigFileFromInput($input)]);
@@ -196,6 +201,11 @@ class Configuration
$config->setInteractiveMode(self::INTERACTIVE_MODE_DISABLED);
}
+ // Handle --compact
+ if (self::getOptionFromInput($input, ['compact'])) {
+ $config->setTheme('compact');
+ }
+
// Handle --raw-output
// @todo support raw output with interactive input?
if (!$config->getInputInteractive()) {
@@ -236,7 +246,7 @@ class Configuration
*
* @return bool true if the option (or an alias) is present
*/
- private static function getOptionFromInput(InputInterface $input, array $names, array $otherParams = [])
+ private static function getOptionFromInput(InputInterface $input, array $names, array $otherParams = []): bool
{
// Best case, input is properly bound and validated.
foreach ($names as $name) {
@@ -331,7 +341,7 @@ class Configuration
*
* @return InputOption[]
*/
- public static function getInputOptions()
+ public static function getInputOptions(): array
{
return [
new InputOption('config', 'c', InputOption::VALUE_REQUIRED, 'Use an alternate PsySH config file location.'),
@@ -345,6 +355,7 @@ class Configuration
new InputOption('quiet', 'q', InputOption::VALUE_NONE, 'Shhhhhh.'),
new InputOption('verbose', 'v|vv|vvv', InputOption::VALUE_OPTIONAL, 'Increase the verbosity of messages.', '0'),
+ new InputOption('compact', null, InputOption::VALUE_NONE, 'Run PsySH with compact output.'),
new InputOption('interactive', 'i|a', InputOption::VALUE_NONE, 'Force PsySH to run in interactive mode.'),
new InputOption('no-interactive', 'n', InputOption::VALUE_NONE, 'Run PsySH without interactive input. Requires input from stdin.'),
// --interaction and --no-interaction aliases for compatibility with Symfony, Composer, etc
@@ -352,6 +363,8 @@ class Configuration
new InputOption('no-interaction', null, InputOption::VALUE_NONE, 'Run PsySH without interactive input. Requires input from stdin.'),
new InputOption('raw-output', 'r', InputOption::VALUE_NONE, 'Print var_export-style return values (for non-interactive input)'),
+ new InputOption('self-update', 'u', InputOption::VALUE_NONE, 'Update to the latest version'),
+
new InputOption('yolo', null, InputOption::VALUE_NONE, 'Run PsySH with minimal input validation. You probably don\'t want this.'),
];
}
@@ -399,7 +412,7 @@ class Configuration
*
* ~/.config/psysh/config.php
*
- * @return string
+ * @return string|null
*/
public function getConfigFile()
{
@@ -425,7 +438,7 @@ class Configuration
* Searches for a project specific config file `.psysh.php` in the current
* working directory.
*
- * @return string
+ * @return string|null
*/
public function getLocalConfigFile()
{
@@ -485,7 +498,7 @@ class Configuration
*
* @param string $file
*/
- public function loadConfigFile($file)
+ public function loadConfigFile(string $file)
{
if (!\is_file($file)) {
throw new \InvalidArgumentException(\sprintf('Invalid configuration file specified, %s does not exist', $file));
@@ -522,9 +535,9 @@ class Configuration
/**
* Get files to be included by default at the start of each shell session.
*
- * @return array
+ * @return string[]
*/
- public function getDefaultIncludes()
+ public function getDefaultIncludes(): array
{
return $this->defaultIncludes ?: [];
}
@@ -534,7 +547,7 @@ class Configuration
*
* @param string $dir
*/
- public function setConfigDir($dir)
+ public function setConfigDir(string $dir)
{
$this->configDir = (string) $dir;
@@ -548,7 +561,7 @@ class Configuration
/**
* Get the current configuration directory, if any is explicitly set.
*
- * @return string
+ * @return string|null
*/
public function getConfigDir()
{
@@ -560,7 +573,7 @@ class Configuration
*
* @param string $dir
*/
- public function setDataDir($dir)
+ public function setDataDir(string $dir)
{
$this->dataDir = (string) $dir;
@@ -574,7 +587,7 @@ class Configuration
/**
* Get the current data directory, if any is explicitly set.
*
- * @return string
+ * @return string|null
*/
public function getDataDir()
{
@@ -586,7 +599,7 @@ class Configuration
*
* @param string $dir
*/
- public function setRuntimeDir($dir)
+ public function setRuntimeDir(string $dir)
{
$this->runtimeDir = (string) $dir;
@@ -603,9 +616,9 @@ class Configuration
* Defaults to `/psysh` inside the system's temp dir unless explicitly
* overridden.
*
- * @return string
+ * @throws RuntimeException if no temporary directory is set and it is not possible to create one
*/
- public function getRuntimeDir()
+ public function getRuntimeDir(): string
{
$runtimeDir = $this->configPaths->runtimeDir();
@@ -623,7 +636,7 @@ class Configuration
*
* @param string $file
*/
- public function setHistoryFile($file)
+ public function setHistoryFile(string $file)
{
$this->historyFile = ConfigPaths::touchFileWithMkdir($file);
}
@@ -633,10 +646,8 @@ class Configuration
*
* Defaults to `/history` inside the shell's base config dir unless
* explicitly overridden.
- *
- * @return string
*/
- public function getHistoryFile()
+ public function getHistoryFile(): string
{
if (isset($this->historyFile)) {
return $this->historyFile;
@@ -664,7 +675,7 @@ class Configuration
*
* @param int $value
*/
- public function setHistorySize($value)
+ public function setHistorySize(int $value)
{
$this->historySize = (int) $value;
}
@@ -684,7 +695,7 @@ class Configuration
*
* @param bool $value
*/
- public function setEraseDuplicates($value)
+ public function setEraseDuplicates(bool $value)
{
$this->eraseDuplicates = (bool) $value;
}
@@ -692,7 +703,7 @@ class Configuration
/**
* Get whether readline erases old duplicate history entries.
*
- * @return bool
+ * @return bool|null
*/
public function getEraseDuplicates()
{
@@ -711,7 +722,7 @@ class Configuration
*
* @return string Temporary file name
*/
- public function getTempFile($type, $pid)
+ public function getTempFile(string $type, int $pid): string
{
return \tempnam($this->getRuntimeDir(), $type.'_'.$pid.'_');
}
@@ -726,7 +737,7 @@ class Configuration
*
* @return string Pipe name
*/
- public function getPipe($type, $pid)
+ public function getPipe(string $type, int $pid): string
{
return \sprintf('%s/%s_%s', $this->getRuntimeDir(), $type, $pid);
}
@@ -736,7 +747,7 @@ class Configuration
*
* @return bool True if Readline is available
*/
- public function hasReadline()
+ public function hasReadline(): bool
{
return $this->hasReadline;
}
@@ -746,7 +757,7 @@ class Configuration
*
* @param bool $useReadline
*/
- public function setUseReadline($useReadline)
+ public function setUseReadline(bool $useReadline)
{
$this->useReadline = (bool) $useReadline;
}
@@ -759,7 +770,7 @@ class Configuration
*
* @return bool True if the current Shell should use Readline
*/
- public function useReadline()
+ public function useReadline(): bool
{
return isset($this->useReadline) ? ($this->hasReadline && $this->useReadline) : $this->hasReadline;
}
@@ -785,7 +796,7 @@ class Configuration
*
* @return Readline\Readline
*/
- public function getReadline()
+ public function getReadline(): Readline\Readline
{
if (!isset($this->readline)) {
$className = $this->getReadlineClass();
@@ -803,21 +814,21 @@ class Configuration
* Get the appropriate Readline implementation class name.
*
* @see self::getReadline
- *
- * @return string
*/
- private function getReadlineClass()
+ private function getReadlineClass(): string
{
if ($this->useReadline()) {
if (Readline\GNUReadline::isSupported()) {
return Readline\GNUReadline::class;
} elseif (Readline\Libedit::isSupported()) {
return Readline\Libedit::class;
- } elseif (Readline\HoaConsole::isSupported()) {
- return Readline\HoaConsole::class;
}
}
+ if (Readline\Userland::isSupported()) {
+ return Readline\Userland::class;
+ }
+
return Readline\Transient::class;
}
@@ -828,7 +839,7 @@ class Configuration
*
* @param bool $useBracketedPaste
*/
- public function setUseBracketedPaste($useBracketedPaste)
+ public function setUseBracketedPaste(bool $useBracketedPaste)
{
$this->useBracketedPaste = (bool) $useBracketedPaste;
}
@@ -848,15 +859,14 @@ class Configuration
*
* @return bool True if the shell should use bracketed paste
*/
- public function useBracketedPaste()
+ public function useBracketedPaste(): bool
{
- // For now, only the GNU readline implementation supports bracketed paste.
- $supported = ($this->getReadlineClass() === Readline\GNUReadline::class) && Readline\GNUReadline::supportsBracketedPaste();
+ $readlineClass = $this->getReadlineClass();
- return $supported && $this->useBracketedPaste;
+ return $this->useBracketedPaste && $readlineClass::supportsBracketedPaste();
// @todo mebbe turn this on by default some day?
- // return isset($this->useBracketedPaste) ? ($supported && $this->useBracketedPaste) : $supported;
+ // return $readlineClass::supportsBracketedPaste() && $this->useBracketedPaste !== false;
}
/**
@@ -864,7 +874,7 @@ class Configuration
*
* @return bool True if Pcntl is available
*/
- public function hasPcntl()
+ public function hasPcntl(): bool
{
return $this->hasPcntl;
}
@@ -874,7 +884,7 @@ class Configuration
*
* @param bool $usePcntl
*/
- public function setUsePcntl($usePcntl)
+ public function setUsePcntl(bool $usePcntl)
{
$this->usePcntl = (bool) $usePcntl;
}
@@ -887,9 +897,19 @@ class Configuration
*
* @return bool True if the current Shell should use Pcntl
*/
- public function usePcntl()
+ public function usePcntl(): bool
{
- return isset($this->usePcntl) ? ($this->hasPcntl && $this->usePcntl) : $this->hasPcntl;
+ if (!isset($this->usePcntl)) {
+ // Unless pcntl is explicitly *enabled*, don't use it while XDebug is debugging.
+ // See https://github.com/bobthecow/psysh/issues/742
+ if (\function_exists('xdebug_is_debugger_active') && \xdebug_is_debugger_active()) {
+ return false;
+ }
+
+ return $this->hasPcntl;
+ }
+
+ return $this->hasPcntl && $this->usePcntl;
}
/**
@@ -900,7 +920,7 @@ class Configuration
*
* @return bool true if raw output is enabled
*/
- public function rawOutput()
+ public function rawOutput(): bool
{
return $this->rawOutput;
}
@@ -910,7 +930,7 @@ class Configuration
*
* @param bool $rawOutput
*/
- public function setRawOutput($rawOutput)
+ public function setRawOutput(bool $rawOutput)
{
$this->rawOutput = (bool) $rawOutput;
}
@@ -922,7 +942,7 @@ class Configuration
*
* @param bool $requireSemicolons
*/
- public function setRequireSemicolons($requireSemicolons)
+ public function setRequireSemicolons(bool $requireSemicolons)
{
$this->requireSemicolons = (bool) $requireSemicolons;
}
@@ -933,10 +953,8 @@ class Configuration
* By default, PsySH will automatically insert semicolons at the end of
* statements if they're missing. To strictly require semicolons, set
* `requireSemicolons` to true.
- *
- * @return bool
*/
- public function requireSemicolons()
+ public function requireSemicolons(): bool
{
return $this->requireSemicolons;
}
@@ -949,7 +967,7 @@ class Configuration
*
* @param bool $useUnicode
*/
- public function setUseUnicode($useUnicode)
+ public function setUseUnicode(bool $useUnicode)
{
$this->useUnicode = (bool) $useUnicode;
}
@@ -959,10 +977,8 @@ class Configuration
*
* Note that this does not disable Unicode output in general, it just makes
* it so PsySH won't output any itself.
- *
- * @return bool
*/
- public function useUnicode()
+ public function useUnicode(): bool
{
if (isset($this->useUnicode)) {
return $this->useUnicode;
@@ -977,7 +993,7 @@ class Configuration
*
* @see self::errorLoggingLevel
*
- * @param bool $errorLoggingLevel
+ * @param int $errorLoggingLevel
*/
public function setErrorLoggingLevel($errorLoggingLevel)
{
@@ -995,10 +1011,8 @@ class Configuration
* level.
*
* http://php.net/manual/en/function.error-reporting.php
- *
- * @return int
*/
- public function errorLoggingLevel()
+ public function errorLoggingLevel(): int
{
return $this->errorLoggingLevel;
}
@@ -1017,10 +1031,8 @@ class Configuration
* Get a CodeCleaner service instance.
*
* If none has been explicitly defined, this will create a new instance.
- *
- * @return CodeCleaner
*/
- public function getCodeCleaner()
+ public function getCodeCleaner(): CodeCleaner
{
if (!isset($this->cleaner)) {
$this->cleaner = new CodeCleaner(null, null, null, $this->yolo());
@@ -1042,7 +1054,7 @@ class Configuration
/**
* Check whether to disable input validation.
*/
- public function yolo()
+ public function yolo(): bool
{
return $this->yolo;
}
@@ -1052,7 +1064,7 @@ class Configuration
*
* @param bool $useTabCompletion
*/
- public function setUseTabCompletion($useTabCompletion)
+ public function setUseTabCompletion(bool $useTabCompletion)
{
$this->useTabCompletion = (bool) $useTabCompletion;
}
@@ -1062,7 +1074,7 @@ class Configuration
*
* @param bool $useTabCompletion
*/
- public function setTabCompletion($useTabCompletion)
+ public function setTabCompletion(bool $useTabCompletion)
{
$this->setUseTabCompletion($useTabCompletion);
}
@@ -1075,17 +1087,15 @@ class Configuration
*
* @return bool True if the current Shell should use tab completion
*/
- public function useTabCompletion()
+ public function useTabCompletion(): bool
{
return isset($this->useTabCompletion) ? ($this->hasReadline && $this->useTabCompletion) : $this->hasReadline;
}
/**
* @deprecated Call `useTabCompletion` instead
- *
- * @return bool
*/
- public function getTabCompletion()
+ public function getTabCompletion(): bool
{
return $this->useTabCompletion();
}
@@ -1099,6 +1109,11 @@ class Configuration
{
$this->output = $output;
$this->pipedOutput = null; // Reset cached pipe info
+
+ if (isset($this->theme)) {
+ $output->setTheme($this->theme);
+ }
+
$this->applyFormatterStyles();
}
@@ -1110,17 +1125,16 @@ class Configuration
*
* @see self::verbosity
* @see self::getPager
- *
- * @return ShellOutput
*/
- public function getOutput()
+ public function getOutput(): ShellOutput
{
if (!isset($this->output)) {
$this->setOutput(new ShellOutput(
$this->getOutputVerbosity(),
null,
null,
- $this->getPager()
+ $this->getPager() ?: null,
+ $this->theme()
));
// This is racy because `getOutputDecorated` needs access to the
@@ -1143,29 +1157,29 @@ class Configuration
public function getOutputDecorated()
{
switch ($this->colorMode()) {
- case self::COLOR_MODE_AUTO:
- return $this->outputIsPiped() ? false : null;
case self::COLOR_MODE_FORCED:
return true;
case self::COLOR_MODE_DISABLED:
return false;
+ case self::COLOR_MODE_AUTO:
+ default:
+ return $this->outputIsPiped() ? false : null;
}
}
/**
* Get the interactive setting for shell input.
- *
- * @return bool
*/
- public function getInputInteractive()
+ public function getInputInteractive(): bool
{
switch ($this->interactiveMode()) {
- case self::INTERACTIVE_MODE_AUTO:
- return !$this->inputIsPiped();
case self::INTERACTIVE_MODE_FORCED:
return true;
case self::INTERACTIVE_MODE_DISABLED:
return false;
+ case self::INTERACTIVE_MODE_AUTO:
+ default:
+ return !$this->inputIsPiped();
}
}
@@ -1175,13 +1189,19 @@ class Configuration
* If a string is supplied, a ProcOutputPager will be used which shells out
* to the specified command.
*
+ * `cat` is special-cased to use the PassthruPager directly.
+ *
* @throws \InvalidArgumentException if $pager is not a string or OutputPager instance
*
- * @param string|OutputPager $pager
+ * @param string|OutputPager|false $pager
*/
public function setPager($pager)
{
- if ($pager && !\is_string($pager) && !$pager instanceof OutputPager) {
+ if ($pager === null || $pager === false || $pager === 'cat') {
+ $pager = false;
+ }
+
+ if ($pager !== false && !\is_string($pager) && !$pager instanceof OutputPager) {
throw new \InvalidArgumentException('Unexpected pager instance');
}
@@ -1194,17 +1214,21 @@ class Configuration
* If no Pager has been explicitly provided, and Pcntl is available, this
* will default to `cli.pager` ini value, falling back to `which less`.
*
- * @return string|OutputPager
+ * @return string|OutputPager|false
*/
public function getPager()
{
if (!isset($this->pager) && $this->usePcntl()) {
+ if (\getenv('TERM') === 'dumb') {
+ return false;
+ }
+
if ($pager = \ini_get('cli.pager')) {
// use the default pager
$this->pager = $pager;
- } elseif ($less = \exec('which less 2>/dev/null')) {
+ } elseif ($less = $this->configPaths->which('less')) {
// check for the presence of less...
- $this->pager = $less.' -R -S -F -X';
+ $this->pager = $less.' -R -F -X';
}
}
@@ -1223,10 +1247,8 @@ class Configuration
/**
* Get an AutoCompleter service instance.
- *
- * @return AutoCompleter
*/
- public function getAutoCompleter()
+ public function getAutoCompleter(): AutoCompleter
{
if (!isset($this->autoCompleter)) {
$this->autoCompleter = new AutoCompleter();
@@ -1237,10 +1259,8 @@ class Configuration
/**
* @deprecated Nothing should be using this anymore
- *
- * @return array
*/
- public function getTabCompletionMatchers()
+ public function getTabCompletionMatchers(): array
{
return [];
}
@@ -1335,7 +1355,7 @@ class Configuration
*
* @param string $filename
*/
- public function setManualDbFile($filename)
+ public function setManualDbFile(string $filename)
{
$this->manualDbFile = (string) $filename;
}
@@ -1343,7 +1363,7 @@ class Configuration
/**
* Get the current PHP manual database file.
*
- * @return string Default: '~/.local/share/psysh/php_manual.sqlite'
+ * @return string|null Default: '~/.local/share/psysh/php_manual.sqlite'
*/
public function getManualDbFile()
{
@@ -1365,13 +1385,13 @@ class Configuration
/**
* Get a PHP manual database connection.
*
- * @return \PDO
+ * @return \PDO|null
*/
public function getManualDb()
{
if (!isset($this->manualDb)) {
$dbFile = $this->getManualDbFile();
- if (\is_file($dbFile)) {
+ if ($dbFile !== null && \is_file($dbFile)) {
try {
$this->manualDb = new \PDO('sqlite:'.$dbFile);
} catch (\PDOException $e) {
@@ -1399,10 +1419,8 @@ class Configuration
/**
* Get the Presenter service.
- *
- * @return Presenter
*/
- public function getPresenter()
+ public function getPresenter(): Presenter
{
if (!isset($this->presenter)) {
$this->presenter = new Presenter($this->getOutput()->getFormatter(), $this->forceArrayIndexes());
@@ -1418,7 +1436,7 @@ class Configuration
*
* @param bool $warnOnMultipleConfigs
*/
- public function setWarnOnMultipleConfigs($warnOnMultipleConfigs)
+ public function setWarnOnMultipleConfigs(bool $warnOnMultipleConfigs)
{
$this->warnOnMultipleConfigs = (bool) $warnOnMultipleConfigs;
}
@@ -1432,10 +1450,8 @@ class Configuration
* are found.
*
* This will default to true in a future release, but is false for now.
- *
- * @return bool
*/
- public function warnOnMultipleConfigs()
+ public function warnOnMultipleConfigs(): bool
{
return $this->warnOnMultipleConfigs;
}
@@ -1443,9 +1459,11 @@ class Configuration
/**
* Set the current color mode.
*
+ * @throws \InvalidArgumentException if the color mode isn't auto, forced or disabled
+ *
* @param string $colorMode
*/
- public function setColorMode($colorMode)
+ public function setColorMode(string $colorMode)
{
$validColorModes = [
self::COLOR_MODE_AUTO,
@@ -1454,8 +1472,7 @@ class Configuration
];
if (!\in_array($colorMode, $validColorModes)) {
- // @todo Fix capitalization for 0.11.0
- throw new \InvalidArgumentException('invalid color mode: '.$colorMode);
+ throw new \InvalidArgumentException('Invalid color mode: '.$colorMode);
}
$this->colorMode = $colorMode;
@@ -1463,10 +1480,8 @@ class Configuration
/**
* Get the current color mode.
- *
- * @return string
*/
- public function colorMode()
+ public function colorMode(): string
{
return $this->colorMode;
}
@@ -1474,9 +1489,11 @@ class Configuration
/**
* Set the shell's interactive mode.
*
+ * @throws \InvalidArgumentException if interactive mode isn't disabled, forced, or auto
+ *
* @param string $interactiveMode
*/
- public function setInteractiveMode($interactiveMode)
+ public function setInteractiveMode(string $interactiveMode)
{
$validInteractiveModes = [
self::INTERACTIVE_MODE_AUTO,
@@ -1493,10 +1510,8 @@ class Configuration
/**
* Get the current interactive mode.
- *
- * @return string
*/
- public function interactiveMode()
+ public function interactiveMode(): string
{
return $this->interactiveMode;
}
@@ -1515,10 +1530,8 @@ class Configuration
* Get an update checker service instance.
*
* If none has been explicitly defined, this will create a new instance.
- *
- * @return Checker
*/
- public function getChecker()
+ public function getChecker(): Checker
{
if (!isset($this->checker)) {
$interval = $this->getUpdateCheck();
@@ -1552,10 +1565,8 @@ class Configuration
*
* One of 'always', 'daily', 'weekly', 'monthly' or 'never'. If none is
* explicitly set, default to 'weekly'.
- *
- * @return string
*/
- public function getUpdateCheck()
+ public function getUpdateCheck(): string
{
return isset($this->updateCheck) ? $this->updateCheck : Checker::WEEKLY;
}
@@ -1567,7 +1578,7 @@ class Configuration
*
* @param string $interval
*/
- public function setUpdateCheck($interval)
+ public function setUpdateCheck(string $interval)
{
$validIntervals = [
Checker::ALWAYS,
@@ -1578,8 +1589,7 @@ class Configuration
];
if (!\in_array($interval, $validIntervals)) {
- // @todo Fix capitalization for 0.11.0
- throw new \InvalidArgumentException('invalid update check interval: '.$interval);
+ throw new \InvalidArgumentException('Invalid update check interval: '.$interval);
}
$this->updateCheck = $interval;
@@ -1600,7 +1610,7 @@ class Configuration
*
* @param string $message
*/
- public function setStartupMessage($message)
+ public function setStartupMessage(string $message)
{
$this->startupMessage = $message;
}
@@ -1620,7 +1630,7 @@ class Configuration
*
* @param string $prompt
*/
- public function setPrompt($prompt)
+ public function setPrompt(string $prompt)
{
$this->prompt = $prompt;
}
@@ -1628,7 +1638,7 @@ class Configuration
/**
* Get the prompt.
*
- * @return string
+ * @return string|null
*/
public function getPrompt()
{
@@ -1637,10 +1647,8 @@ class Configuration
/**
* Get the force array indexes.
- *
- * @return bool
*/
- public function forceArrayIndexes()
+ public function forceArrayIndexes(): bool
{
return $this->forceArrayIndexes;
}
@@ -1650,11 +1658,42 @@ class Configuration
*
* @param bool $forceArrayIndexes
*/
- public function setForceArrayIndexes($forceArrayIndexes)
+ public function setForceArrayIndexes(bool $forceArrayIndexes)
{
$this->forceArrayIndexes = $forceArrayIndexes;
}
+ /**
+ * Set the current output Theme.
+ *
+ * @param Theme|string|array $theme Theme (or Theme config)
+ */
+ public function setTheme($theme)
+ {
+ if (!$theme instanceof Theme) {
+ $theme = new Theme($theme);
+ }
+
+ $this->theme = $theme;
+
+ if (isset($this->output)) {
+ $this->output->setTheme($theme);
+ $this->applyFormatterStyles();
+ }
+ }
+
+ /**
+ * Get the current output Theme.
+ */
+ public function theme(): Theme
+ {
+ if (!isset($this->theme)) {
+ $this->theme = new Theme();
+ }
+
+ return $this->theme;
+ }
+
/**
* Set the shell output formatter styles.
*
@@ -1667,15 +1706,14 @@ class Configuration
*
* Foreground, background or options can be null, or even omitted entirely.
*
- * @see ShellOutput::initFormatters
- *
- * @param array $formatterStyles
+ * @deprecated The `formatterStyles` configuration has been replaced by Themes and support will
+ * eventually be removed. In the meantime, styles are applied first by the Theme, then
+ * overridden by any explicitly defined formatter styles.
*/
public function setFormatterStyles(array $formatterStyles)
{
foreach ($formatterStyles as $name => $style) {
- list($fg, $bg, $opts) = \array_pad($style, 3, null);
- $this->formatterStyles[$name] = new OutputFormatterStyle($fg ?: null, $bg ?: null, $opts ?: []);
+ $this->formatterStyles[$name] = new OutputFormatterStyle(...$style);
}
if (isset($this->output)) {
@@ -1688,6 +1726,10 @@ class Configuration
*
* This is called on initialization of the shell output, and again if the
* formatter styles config is updated.
+ *
+ * @deprecated The `formatterStyles` configuration has been replaced by Themes and support will
+ * eventually be removed. In the meantime, styles are applied first by the Theme, then
+ * overridden by any explicitly defined formatter styles.
*/
private function applyFormatterStyles()
{
@@ -1695,14 +1737,19 @@ class Configuration
foreach ($this->formatterStyles as $name => $style) {
$formatter->setStyle($name, $style);
}
+
+ $errorFormatter = $this->output->getErrorOutput()->getFormatter();
+ foreach (Theme::ERROR_STYLES as $name) {
+ if (isset($this->formatterStyles[$name])) {
+ $errorFormatter->setStyle($name, $this->formatterStyles[$name]);
+ }
+ }
}
/**
* Get the configured output verbosity.
- *
- * @return string
*/
- public function verbosity()
+ public function verbosity(): string
{
return $this->verbosity;
}
@@ -1712,9 +1759,11 @@ class Configuration
*
* Accepts OutputInterface verbosity constants.
*
+ * @throws \InvalidArgumentException if verbosity level is invalid
+ *
* @param string $verbosity
*/
- public function setVerbosity($verbosity)
+ public function setVerbosity(string $verbosity)
{
$validVerbosityLevels = [
self::VERBOSITY_QUIET,
@@ -1740,7 +1789,7 @@ class Configuration
*
* @return int OutputInterface verbosity level
*/
- public function getOutputVerbosity()
+ public function getOutputVerbosity(): int
{
switch ($this->verbosity()) {
case self::VERBOSITY_QUIET:
@@ -1761,13 +1810,11 @@ class Configuration
* Guess whether stdin is piped.
*
* This is mostly useful for deciding whether to use non-interactive mode.
- *
- * @return bool
*/
- public function inputIsPiped()
+ public function inputIsPiped(): bool
{
if ($this->pipedInput === null) {
- $this->pipedInput = \defined('STDIN') && static::looksLikeAPipe(\STDIN);
+ $this->pipedInput = \defined('STDIN') && self::looksLikeAPipe(\STDIN);
}
return $this->pipedInput;
@@ -1777,13 +1824,11 @@ class Configuration
* Guess whether shell output is piped.
*
* This is mostly useful for deciding whether to use non-decorated output.
- *
- * @return bool
*/
- public function outputIsPiped()
+ public function outputIsPiped(): bool
{
if ($this->pipedOutput === null) {
- $this->pipedOutput = static::looksLikeAPipe($this->getOutput()->getStream());
+ $this->pipedOutput = self::looksLikeAPipe($this->getOutput()->getStream());
}
return $this->pipedOutput;
@@ -1793,10 +1838,8 @@ class Configuration
* Guess whether an input or output stream is piped.
*
* @param resource|int $stream
- *
- * @return bool
*/
- private static function looksLikeAPipe($stream)
+ private static function looksLikeAPipe($stream): bool
{
if (\function_exists('posix_isatty')) {
return !\posix_isatty($stream);
diff --git a/vendor/psy/psysh/src/ConsoleColorFactory.php b/vendor/psy/psysh/src/ConsoleColorFactory.php
deleted file mode 100644
index 9cfbf40e3..000000000
--- a/vendor/psy/psysh/src/ConsoleColorFactory.php
+++ /dev/null
@@ -1,39 +0,0 @@
-scopeVariables, $this->getSpecialVariables());
}
/**
* Get all defined magic variables: $_, $_e, $__out, $__class, $__file, etc.
- *
- * @return array
*/
- public function getSpecialVariables()
+ public function getSpecialVariables(): array
{
$vars = [
'_' => $this->returnValue,
@@ -168,21 +164,21 @@ class Context
}
/**
- * Set the most recent Exception.
+ * Set the most recent Exception or Error.
*
- * @param \Exception $e
+ * @param \Throwable $e
*/
- public function setLastException(\Exception $e)
+ public function setLastException(\Throwable $e)
{
$this->lastException = $e;
}
/**
- * Get the most recent Exception.
+ * Get the most recent Exception or Error.
*
* @throws \InvalidArgumentException If no Exception has been caught
*
- * @return \Exception|null
+ * @return \Throwable|null
*/
public function getLastException()
{
@@ -198,7 +194,7 @@ class Context
*
* @param string $lastStdout
*/
- public function setLastStdout($lastStdout)
+ public function setLastStdout(string $lastStdout)
{
$this->lastStdout = $lastStdout;
}
@@ -285,10 +281,8 @@ class Context
/**
* Get command-scope magic variables: $__class, $__file, etc.
- *
- * @return array
*/
- public function getCommandScopeVariables()
+ public function getCommandScopeVariables(): array
{
return $this->commandScopeVariables;
}
@@ -301,7 +295,7 @@ class Context
*
* @return array Array of unused variable names
*/
- public function getUnusedCommandScopeVariableNames()
+ public function getUnusedCommandScopeVariableNames(): array
{
return \array_diff(self::$commandScopeNames, \array_keys($this->commandScopeVariables));
}
@@ -310,10 +304,8 @@ class Context
* Check whether a variable name is a magic variable.
*
* @param string $name
- *
- * @return bool
*/
- public static function isSpecialVariableName($name)
+ public static function isSpecialVariableName(string $name): bool
{
return \in_array($name, self::$specialNames) || \in_array($name, self::$commandScopeNames);
}
diff --git a/vendor/psy/psysh/src/ContextAware.php b/vendor/psy/psysh/src/ContextAware.php
index 121d4db18..83979ae85 100644
--- a/vendor/psy/psysh/src/ContextAware.php
+++ b/vendor/psy/psysh/src/ContextAware.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
diff --git a/vendor/psy/psysh/src/EnvInterface.php b/vendor/psy/psysh/src/EnvInterface.php
index 1f7b9fae8..31a738fc4 100644
--- a/vendor/psy/psysh/src/EnvInterface.php
+++ b/vendor/psy/psysh/src/EnvInterface.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -21,5 +21,5 @@ interface EnvInterface
*
* @return string|null
*/
- public function get($key);
+ public function get(string $key);
}
diff --git a/vendor/psy/psysh/src/Exception/BreakException.php b/vendor/psy/psysh/src/Exception/BreakException.php
index 6efc7acb7..4061442a8 100644
--- a/vendor/psy/psysh/src/Exception/BreakException.php
+++ b/vendor/psy/psysh/src/Exception/BreakException.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -21,7 +21,7 @@ class BreakException extends \Exception implements Exception
/**
* {@inheritdoc}
*/
- public function __construct($message = '', $code = 0, \Exception $previous = null)
+ public function __construct($message = '', $code = 0, \Throwable $previous = null)
{
$this->rawMessage = $message;
parent::__construct(\sprintf('Exit: %s', $message), $code, $previous);
@@ -29,10 +29,8 @@ class BreakException extends \Exception implements Exception
/**
* Return a raw (unformatted) version of the error message.
- *
- * @return string
*/
- public function getRawMessage()
+ public function getRawMessage(): string
{
return $this->rawMessage;
}
diff --git a/vendor/psy/psysh/src/Exception/DeprecatedException.php b/vendor/psy/psysh/src/Exception/DeprecatedException.php
index d06608ebb..f326b53bd 100644
--- a/vendor/psy/psysh/src/Exception/DeprecatedException.php
+++ b/vendor/psy/psysh/src/Exception/DeprecatedException.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
diff --git a/vendor/psy/psysh/src/Exception/ErrorException.php b/vendor/psy/psysh/src/Exception/ErrorException.php
index 78ac9c569..54abcfd70 100644
--- a/vendor/psy/psysh/src/Exception/ErrorException.php
+++ b/vendor/psy/psysh/src/Exception/ErrorException.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -21,14 +21,14 @@ class ErrorException extends \ErrorException implements Exception
/**
* Construct a Psy ErrorException.
*
- * @param string $message (default: "")
- * @param int $code (default: 0)
- * @param int $severity (default: 1)
- * @param string|null $filename (default: null)
- * @param int|null $lineno (default: null)
- * @param Exception|null $previous (default: null)
+ * @param string $message (default: "")
+ * @param int $code (default: 0)
+ * @param int $severity (default: 1)
+ * @param string|null $filename (default: null)
+ * @param int|null $lineno (default: null)
+ * @param \Throwable|null $previous (default: null)
*/
- public function __construct($message = '', $code = 0, $severity = 1, $filename = null, $lineno = null, $previous = null)
+ public function __construct($message = '', $code = 0, $severity = 1, $filename = null, $lineno = null, \Throwable $previous = null)
{
$this->rawMessage = $message;
@@ -73,10 +73,8 @@ class ErrorException extends \ErrorException implements Exception
/**
* Get the raw (unformatted) message for this error.
- *
- * @return string
*/
- public function getRawMessage()
+ public function getRawMessage(): string
{
return $this->rawMessage;
}
@@ -88,7 +86,7 @@ class ErrorException extends \ErrorException implements Exception
*
* set_error_handler([ErrorException::class, 'throwException']);
*
- * @throws ErrorException
+ * @throws self
*
* @param int $errno Error type
* @param string $errstr Message
@@ -103,11 +101,11 @@ class ErrorException extends \ErrorException implements Exception
/**
* Create an ErrorException from an Error.
*
- * @param \Error $e
+ * @deprecated psySH no longer wraps Errors
*
- * @return ErrorException
+ * @param \Error $e
*/
- public static function fromError(\Error $e)
+ public static function fromError(\Error $e): self
{
return new self($e->getMessage(), $e->getCode(), 1, $e->getFile(), $e->getLine(), $e);
}
diff --git a/vendor/psy/psysh/src/Exception/Exception.php b/vendor/psy/psysh/src/Exception/Exception.php
index 4b02d1326..db7906211 100644
--- a/vendor/psy/psysh/src/Exception/Exception.php
+++ b/vendor/psy/psysh/src/Exception/Exception.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
diff --git a/vendor/psy/psysh/src/Exception/FatalErrorException.php b/vendor/psy/psysh/src/Exception/FatalErrorException.php
index 6642264e2..21b223488 100644
--- a/vendor/psy/psysh/src/Exception/FatalErrorException.php
+++ b/vendor/psy/psysh/src/Exception/FatalErrorException.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -26,9 +26,9 @@ class FatalErrorException extends \ErrorException implements Exception
* @param int $severity (default: 1)
* @param string|null $filename (default: null)
* @param int|null $lineno (default: null)
- * @param \Exception|null $previous (default: null)
+ * @param \Throwable|null $previous (default: null)
*/
- public function __construct($message = '', $code = 0, $severity = 1, $filename = null, $lineno = null, $previous = null)
+ public function __construct($message = '', $code = 0, $severity = 1, $filename = null, $lineno = null, \Throwable $previous = null)
{
// Since these are basically always PHP Parser Node line numbers, treat -1 as null.
if ($lineno === -1) {
@@ -42,10 +42,8 @@ class FatalErrorException extends \ErrorException implements Exception
/**
* Return a raw (unformatted) version of the error message.
- *
- * @return string
*/
- public function getRawMessage()
+ public function getRawMessage(): string
{
return $this->rawMessage;
}
diff --git a/vendor/psy/psysh/src/Exception/ParseErrorException.php b/vendor/psy/psysh/src/Exception/ParseErrorException.php
index cfc5f70ca..8abfd12f8 100644
--- a/vendor/psy/psysh/src/Exception/ParseErrorException.php
+++ b/vendor/psy/psysh/src/Exception/ParseErrorException.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -22,7 +22,7 @@ class ParseErrorException extends \PhpParser\Error implements Exception
* @param string $message (default: "")
* @param int $line (default: -1)
*/
- public function __construct($message = '', $line = -1)
+ public function __construct(string $message = '', int $line = -1)
{
$message = \sprintf('PHP Parse error: %s', $message);
parent::__construct($message, $line);
@@ -32,10 +32,8 @@ class ParseErrorException extends \PhpParser\Error implements Exception
* Create a ParseErrorException from a PhpParser Error.
*
* @param \PhpParser\Error $e
- *
- * @return ParseErrorException
*/
- public static function fromParseError(\PhpParser\Error $e)
+ public static function fromParseError(\PhpParser\Error $e): self
{
return new self($e->getRawMessage(), $e->getStartLine());
}
diff --git a/vendor/psy/psysh/src/Exception/RuntimeException.php b/vendor/psy/psysh/src/Exception/RuntimeException.php
index 31890517e..6228813b0 100644
--- a/vendor/psy/psysh/src/Exception/RuntimeException.php
+++ b/vendor/psy/psysh/src/Exception/RuntimeException.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -23,9 +23,9 @@ class RuntimeException extends \RuntimeException implements Exception
*
* @param string $message (default: "")
* @param int $code (default: 0)
- * @param \Exception|null $previous (default: null)
+ * @param \Throwable|null $previous (default: null)
*/
- public function __construct($message = '', $code = 0, \Exception $previous = null)
+ public function __construct(string $message = '', int $code = 0, \Throwable $previous = null)
{
$this->rawMessage = $message;
parent::__construct($message, $code, $previous);
@@ -33,10 +33,8 @@ class RuntimeException extends \RuntimeException implements Exception
/**
* Return a raw (unformatted) version of the error message.
- *
- * @return string
*/
- public function getRawMessage()
+ public function getRawMessage(): string
{
return $this->rawMessage;
}
diff --git a/vendor/psy/psysh/src/Exception/ThrowUpException.php b/vendor/psy/psysh/src/Exception/ThrowUpException.php
index 692c4a3c6..a01c39d25 100644
--- a/vendor/psy/psysh/src/Exception/ThrowUpException.php
+++ b/vendor/psy/psysh/src/Exception/ThrowUpException.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -19,18 +19,16 @@ class ThrowUpException extends \Exception implements Exception
/**
* {@inheritdoc}
*/
- public function __construct(\Exception $exception)
+ public function __construct(\Throwable $throwable)
{
- $message = \sprintf("Throwing %s with message '%s'", \get_class($exception), $exception->getMessage());
- parent::__construct($message, $exception->getCode(), $exception);
+ $message = \sprintf("Throwing %s with message '%s'", \get_class($throwable), $throwable->getMessage());
+ parent::__construct($message, $throwable->getCode(), $throwable);
}
/**
* Return a raw (unformatted) version of the error message.
- *
- * @return string
*/
- public function getRawMessage()
+ public function getRawMessage(): string
{
return $this->getPrevious()->getMessage();
}
@@ -38,11 +36,11 @@ class ThrowUpException extends \Exception implements Exception
/**
* Create a ThrowUpException from a Throwable.
*
- * @param \Throwable $throwable
+ * @deprecated psySH no longer wraps Throwables
*
- * @return ThrowUpException
+ * @param \Throwable $throwable
*/
- public static function fromThrowable($throwable)
+ public static function fromThrowable($throwable): self
{
if ($throwable instanceof \Error) {
$throwable = ErrorException::fromError($throwable);
diff --git a/vendor/psy/psysh/src/Exception/TypeErrorException.php b/vendor/psy/psysh/src/Exception/TypeErrorException.php
index 40dccf47e..d7151ead7 100644
--- a/vendor/psy/psysh/src/Exception/TypeErrorException.php
+++ b/vendor/psy/psysh/src/Exception/TypeErrorException.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -21,22 +21,23 @@ class TypeErrorException extends \Exception implements Exception
/**
* Constructor!
*
- * @param string $message (default: "")
- * @param int $code (default: 0)
+ * @deprecated psySH no longer wraps TypeErrors
+ *
+ * @param string $message (default: "")
+ * @param int $code (default: 0)
+ * @param \Throwable|null $previous (default: null)
*/
- public function __construct($message = '', $code = 0)
+ public function __construct(string $message = '', int $code = 0, \Throwable $previous = null)
{
$this->rawMessage = $message;
$message = \preg_replace('/, called in .*?: eval\\(\\)\'d code/', '', $message);
- parent::__construct(\sprintf('TypeError: %s', $message), $code);
+ parent::__construct(\sprintf('TypeError: %s', $message), $code, $previous);
}
/**
* Get the raw (unformatted) message for this error.
- *
- * @return string
*/
- public function getRawMessage()
+ public function getRawMessage(): string
{
return $this->rawMessage;
}
@@ -44,12 +45,12 @@ class TypeErrorException extends \Exception implements Exception
/**
* Create a TypeErrorException from a TypeError.
*
- * @param \TypeError $e
+ * @deprecated psySH no longer wraps TypeErrors
*
- * @return TypeErrorException
+ * @param \TypeError $e
*/
- public static function fromTypeError(\TypeError $e)
+ public static function fromTypeError(\TypeError $e): self
{
- return new self($e->getMessage(), $e->getCode());
+ return new self($e->getMessage(), $e->getCode(), $e);
}
}
diff --git a/vendor/psy/psysh/src/Exception/UnexpectedTargetException.php b/vendor/psy/psysh/src/Exception/UnexpectedTargetException.php
index fd2330508..9d2b70d11 100644
--- a/vendor/psy/psysh/src/Exception/UnexpectedTargetException.php
+++ b/vendor/psy/psysh/src/Exception/UnexpectedTargetException.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -19,9 +19,9 @@ class UnexpectedTargetException extends RuntimeException
* @param mixed $target
* @param string $message (default: "")
* @param int $code (default: 0)
- * @param \Exception|null $previous (default: null)
+ * @param \Throwable|null $previous (default: null)
*/
- public function __construct($target, $message = '', $code = 0, \Exception $previous = null)
+ public function __construct($target, string $message = '', int $code = 0, \Throwable $previous = null)
{
$this->target = $target;
parent::__construct($message, $code, $previous);
diff --git a/vendor/psy/psysh/src/ExecutionClosure.php b/vendor/psy/psysh/src/ExecutionClosure.php
index bebec1349..837e931be 100644
--- a/vendor/psy/psysh/src/ExecutionClosure.php
+++ b/vendor/psy/psysh/src/ExecutionClosure.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -44,13 +44,6 @@ class ExecutionClosure
\ob_end_clean();
}
- throw $_e;
- } catch (\Exception $_e) {
- // Clean up on our way out.
- if (\ob_get_level() > 0) {
- \ob_end_clean();
- }
-
throw $_e;
} finally {
// Won't be needing this anymore
diff --git a/vendor/psy/psysh/src/ExecutionLoop/AbstractListener.php b/vendor/psy/psysh/src/ExecutionLoop/AbstractListener.php
index 0bfa3fdf5..8230c5508 100644
--- a/vendor/psy/psysh/src/ExecutionLoop/AbstractListener.php
+++ b/vendor/psy/psysh/src/ExecutionLoop/AbstractListener.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -35,14 +35,14 @@ abstract class AbstractListener implements Listener
/**
* {@inheritdoc}
*/
- public function onInput(Shell $shell, $input)
+ public function onInput(Shell $shell, string $input)
{
}
/**
* {@inheritdoc}
*/
- public function onExecute(Shell $shell, $code)
+ public function onExecute(Shell $shell, string $code)
{
}
diff --git a/vendor/psy/psysh/src/ExecutionLoop/Listener.php b/vendor/psy/psysh/src/ExecutionLoop/Listener.php
index 5bc03c196..9f207f5b7 100644
--- a/vendor/psy/psysh/src/ExecutionLoop/Listener.php
+++ b/vendor/psy/psysh/src/ExecutionLoop/Listener.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -20,10 +20,8 @@ interface Listener
{
/**
* Determines whether this listener should be active.
- *
- * @return bool
*/
- public static function isSupported();
+ public static function isSupported(): bool;
/**
* Called once before the REPL session starts.
@@ -49,7 +47,7 @@ interface Listener
*
* @return string|null User input override
*/
- public function onInput(Shell $shell, $input);
+ public function onInput(Shell $shell, string $input);
/**
* Called before executing user code.
@@ -65,7 +63,7 @@ interface Listener
*
* @return string|null User code override
*/
- public function onExecute(Shell $shell, $code);
+ public function onExecute(Shell $shell, string $code);
/**
* Called at the end of each loop.
diff --git a/vendor/psy/psysh/src/ExecutionLoop/ProcessForker.php b/vendor/psy/psysh/src/ExecutionLoop/ProcessForker.php
index 0bad66e0e..3d61693c4 100644
--- a/vendor/psy/psysh/src/ExecutionLoop/ProcessForker.php
+++ b/vendor/psy/psysh/src/ExecutionLoop/ProcessForker.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -41,10 +41,8 @@ class ProcessForker extends AbstractListener
/**
* Process forker is supported if pcntl and posix extensions are available.
- *
- * @return bool
*/
- public static function isSupported()
+ public static function isSupported(): bool
{
return self::isPcntlSupported() && !self::disabledPcntlFunctions() && self::isPosixSupported() && !self::disabledPosixFunctions();
}
@@ -52,7 +50,7 @@ class ProcessForker extends AbstractListener
/**
* Verify that all required pcntl functions are, in fact, available.
*/
- public static function isPcntlSupported()
+ public static function isPcntlSupported(): bool
{
foreach (self::$pcntlFunctions as $func) {
if (!\function_exists($func)) {
@@ -74,7 +72,7 @@ class ProcessForker extends AbstractListener
/**
* Verify that all required posix functions are, in fact, available.
*/
- public static function isPosixSupported()
+ public static function isPosixSupported(): bool
{
foreach (self::$posixFunctions as $func) {
if (!\function_exists($func)) {
@@ -93,13 +91,13 @@ class ProcessForker extends AbstractListener
return self::checkDisabledFunctions(self::$posixFunctions);
}
- private static function checkDisabledFunctions(array $functions)
+ private static function checkDisabledFunctions(array $functions): array
{
return \array_values(\array_intersect($functions, \array_map('strtolower', \array_map('trim', \explode(',', \ini_get('disable_functions'))))));
}
/**
- * Forks into a master and a loop process.
+ * Forks into a main and a loop process.
*
* The loop process will handle the evaluation of all instructions, then
* return its state via a socket upon completion.
@@ -250,10 +248,8 @@ class ProcessForker extends AbstractListener
* we can.
*
* @param array $return
- *
- * @return string
*/
- private function serializeReturn(array $return)
+ private function serializeReturn(array $return): string
{
$serializable = [];
@@ -268,14 +264,19 @@ class ProcessForker extends AbstractListener
continue;
}
+ if (\version_compare(\PHP_VERSION, '8.1', '>=') && $value instanceof \UnitEnum) {
+ // Enums defined in the REPL session can't be unserialized.
+ $ref = new \ReflectionObject($value);
+ if (\strpos($ref->getFileName(), ": eval()'d code") !== false) {
+ continue;
+ }
+ }
+
try {
@\serialize($value);
$serializable[$key] = $value;
} catch (\Throwable $e) {
// we'll just ignore this one...
- } catch (\Exception $e) {
- // and this one too...
- // @todo remove this once we don't support PHP 5.x anymore :)
}
}
diff --git a/vendor/psy/psysh/src/ExecutionLoop/RunkitReloader.php b/vendor/psy/psysh/src/ExecutionLoop/RunkitReloader.php
index e0375a2d8..74046a2e2 100644
--- a/vendor/psy/psysh/src/ExecutionLoop/RunkitReloader.php
+++ b/vendor/psy/psysh/src/ExecutionLoop/RunkitReloader.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -25,10 +25,8 @@ class RunkitReloader extends AbstractListener
/**
* Only enabled if Runkit is installed.
- *
- * @return bool
*/
- public static function isSupported()
+ public static function isSupported(): bool
{
// runkit_import was removed in runkit7-4.0.0a1
return \extension_loaded('runkit') || \extension_loaded('runkit7') && \function_exists('runkit_import');
@@ -51,7 +49,7 @@ class RunkitReloader extends AbstractListener
* @param Shell $shell
* @param string $input
*/
- public function onInput(Shell $shell, $input)
+ public function onInput(Shell $shell, string $input)
{
$this->reload($shell);
}
@@ -127,15 +125,13 @@ class RunkitReloader extends AbstractListener
* Use PHP-Parser to ensure that the file is valid PHP.
*
* @param string $file
- *
- * @return bool
*/
- private function lintFile($file)
+ private function lintFile(string $file): bool
{
// first try to parse it
try {
$this->parser->parse(\file_get_contents($file));
- } catch (\Exception $e) {
+ } catch (\Throwable $e) {
return false;
}
diff --git a/vendor/psy/psysh/src/ExecutionLoopClosure.php b/vendor/psy/psysh/src/ExecutionLoopClosure.php
index aadef7337..78f7e5ea1 100644
--- a/vendor/psy/psysh/src/ExecutionLoopClosure.php
+++ b/vendor/psy/psysh/src/ExecutionLoopClosure.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -12,9 +12,7 @@
namespace Psy;
use Psy\Exception\BreakException;
-use Psy\Exception\ErrorException;
use Psy\Exception\ThrowUpException;
-use Psy\Exception\TypeErrorException;
/**
* The Psy Shell's execution loop scope.
@@ -59,13 +57,6 @@ class ExecutionLoopClosure extends ExecutionClosure
\ob_end_clean();
}
- throw $_e;
- } catch (\Exception $_e) {
- // Clean up on our way out.
- if (\ob_get_level() > 0) {
- \ob_end_clean();
- }
-
throw $_e;
} finally {
// Won't be needing this anymore
@@ -87,11 +78,7 @@ class ExecutionLoopClosure extends ExecutionClosure
$__psysh__->writeException($_e);
throw $_e;
- } catch (\TypeError $_e) {
- $__psysh__->writeException(TypeErrorException::fromTypeError($_e));
- } catch (\Error $_e) {
- $__psysh__->writeException(ErrorException::fromError($_e));
- } catch (\Exception $_e) {
+ } catch (\Throwable $_e) {
$__psysh__->writeException($_e);
}
diff --git a/vendor/psy/psysh/src/Formatter/CodeFormatter.php b/vendor/psy/psysh/src/Formatter/CodeFormatter.php
index 0dabc0642..43bb7fc08 100644
--- a/vendor/psy/psysh/src/Formatter/CodeFormatter.php
+++ b/vendor/psy/psysh/src/Formatter/CodeFormatter.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -81,7 +81,7 @@ class CodeFormatter implements ReflectorFormatter
*
* @return string formatted code
*/
- public static function format(\Reflector $reflector, $colorMode = null)
+ public static function format(\Reflector $reflector, string $colorMode = null): string
{
if (self::isReflectable($reflector)) {
if ($code = @\file_get_contents($reflector->getFileName())) {
@@ -104,7 +104,7 @@ class CodeFormatter implements ReflectorFormatter
*
* @return string formatted code
*/
- public static function formatCode($code, $startLine = 1, $endLine = null, $markLine = null)
+ public static function formatCode(string $code, int $startLine = 1, int $endLine = null, int $markLine = null): string
{
$spans = self::tokenizeSpans($code);
$lines = self::splitLines($spans, $startLine, $endLine);
@@ -122,10 +122,8 @@ class CodeFormatter implements ReflectorFormatter
* This is typehinted as \Reflector but we've narrowed the input via self::isReflectable already.
*
* @param \ReflectionClass|\ReflectionFunctionAbstract $reflector
- *
- * @return int
*/
- private static function getStartLine(\Reflector $reflector)
+ private static function getStartLine(\Reflector $reflector): int
{
$startLine = $reflector->getStartLine();
@@ -148,7 +146,7 @@ class CodeFormatter implements ReflectorFormatter
*
* @return \Generator [$spanType, $spanText] highlight spans
*/
- private static function tokenizeSpans($code)
+ private static function tokenizeSpans(string $code): \Generator
{
$spanType = null;
$buffer = '';
@@ -209,7 +207,7 @@ class CodeFormatter implements ReflectorFormatter
*
* @return \Generator lines, each an array of [$spanType, $spanText] pairs
*/
- private static function splitLines(\Generator $spans, $startLine = 1, $endLine = null)
+ private static function splitLines(\Generator $spans, int $startLine = 1, int $endLine = null): \Generator
{
$lineNum = 1;
$buffer = [];
@@ -247,7 +245,7 @@ class CodeFormatter implements ReflectorFormatter
*
* @return \Generator Formatted lines
*/
- private static function formatLines(\Generator $spanLines)
+ private static function formatLines(\Generator $spanLines): \Generator
{
foreach ($spanLines as $lineNum => $spanLine) {
$line = '';
@@ -276,7 +274,7 @@ class CodeFormatter implements ReflectorFormatter
*
* @return \Generator Numbered, formatted lines
*/
- private static function numberLines(\Generator $lines, $markLine = null)
+ private static function numberLines(\Generator $lines, int $markLine = null): \Generator
{
$lines = \iterator_to_array($lines);
@@ -302,18 +300,18 @@ class CodeFormatter implements ReflectorFormatter
$mark = ($markLine === $lineNum) ? self::LINE_MARKER : self::NO_LINE_MARKER;
}
- yield \sprintf("%s: %s", $mark, $lineNum, $line);
+ yield \sprintf("%s: %s", $mark, $lineNum, $line);
}
}
/**
* Check whether a Reflector instance is reflectable by this formatter.
*
- * @param \Reflector $reflector
+ * @phpstan-assert-if-true \ReflectionClass|\ReflectionFunctionAbstract $reflector
*
- * @return bool
+ * @param \Reflector $reflector
*/
- private static function isReflectable(\Reflector $reflector)
+ private static function isReflectable(\Reflector $reflector): bool
{
return ($reflector instanceof \ReflectionClass || $reflector instanceof \ReflectionFunctionAbstract) && \is_file($reflector->getFileName());
}
diff --git a/vendor/psy/psysh/src/Formatter/DocblockFormatter.php b/vendor/psy/psysh/src/Formatter/DocblockFormatter.php
index 3056967d2..282f463e2 100644
--- a/vendor/psy/psysh/src/Formatter/DocblockFormatter.php
+++ b/vendor/psy/psysh/src/Formatter/DocblockFormatter.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -31,7 +31,7 @@ class DocblockFormatter implements ReflectorFormatter
*
* @return string Formatted docblock
*/
- public static function format(\Reflector $reflector)
+ public static function format(\Reflector $reflector): string
{
$docblock = new Docblock($reflector);
$chunks = [];
@@ -68,10 +68,8 @@ class DocblockFormatter implements ReflectorFormatter
*
* @param array $vector
* @param array $lines
- *
- * @return string
*/
- private static function formatVector(array $vector, array $lines)
+ private static function formatVector(array $vector, array $lines): string
{
$template = [' '];
foreach ($vector as $type) {
@@ -109,7 +107,7 @@ class DocblockFormatter implements ReflectorFormatter
*
* @return string formatted tags
*/
- private static function formatTags(array $skip, array $tags)
+ private static function formatTags(array $skip, array $tags): string
{
$chunks = [];
@@ -133,10 +131,8 @@ class DocblockFormatter implements ReflectorFormatter
*
* @param string $type Vector type
* @param int $max Pad width
- *
- * @return string
*/
- private static function getVectorParamTemplate($type, $max)
+ private static function getVectorParamTemplate(string $type, int $max): string
{
if (!isset(self::$vectorParamTemplates[$type])) {
return \sprintf('%%-%ds', $max);
@@ -150,10 +146,8 @@ class DocblockFormatter implements ReflectorFormatter
*
* @param string $text String to indent
* @param string $indent (default: ' ')
- *
- * @return string
*/
- private static function indent($text, $indent = ' ')
+ private static function indent(string $text, string $indent = ' '): string
{
return $indent.\str_replace("\n", "\n".$indent, $text);
}
@@ -162,10 +156,8 @@ class DocblockFormatter implements ReflectorFormatter
* Convert underscored or whitespace separated words into sentence case.
*
* @param string $text
- *
- * @return string
*/
- private static function inflect($text)
+ private static function inflect(string $text): string
{
$words = \trim(\preg_replace('/[\s_-]+/', ' ', \preg_replace('/([a-z])([A-Z])/', '$1 $2', $text)));
diff --git a/vendor/psy/psysh/src/Formatter/Formatter.php b/vendor/psy/psysh/src/Formatter/Formatter.php
index 8800c1866..0f972a3f9 100644
--- a/vendor/psy/psysh/src/Formatter/Formatter.php
+++ b/vendor/psy/psysh/src/Formatter/Formatter.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
diff --git a/vendor/psy/psysh/src/Formatter/ReflectorFormatter.php b/vendor/psy/psysh/src/Formatter/ReflectorFormatter.php
index cf2f25340..02f426cdd 100644
--- a/vendor/psy/psysh/src/Formatter/ReflectorFormatter.php
+++ b/vendor/psy/psysh/src/Formatter/ReflectorFormatter.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -18,8 +18,6 @@ interface ReflectorFormatter
{
/**
* @param \Reflector $reflector
- *
- * @return string
*/
- public static function format(\Reflector $reflector);
+ public static function format(\Reflector $reflector): string;
}
diff --git a/vendor/psy/psysh/src/Formatter/SignatureFormatter.php b/vendor/psy/psysh/src/Formatter/SignatureFormatter.php
index c706ec1e0..3c9c2625d 100644
--- a/vendor/psy/psysh/src/Formatter/SignatureFormatter.php
+++ b/vendor/psy/psysh/src/Formatter/SignatureFormatter.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -31,7 +31,7 @@ class SignatureFormatter implements ReflectorFormatter
*
* @return string Formatted signature
*/
- public static function format(\Reflector $reflector)
+ public static function format(\Reflector $reflector): string
{
switch (true) {
case $reflector instanceof \ReflectionFunction:
@@ -63,11 +63,11 @@ class SignatureFormatter implements ReflectorFormatter
/**
* Print the signature name.
*
- * @param \Reflector $reflector
+ * @param \ReflectionClass|ReflectionClassConstant|\ReflectionClassConstant|\ReflectionFunctionAbstract $reflector
*
* @return string Formatted name
*/
- public static function formatName(\Reflector $reflector)
+ public static function formatName(\Reflector $reflector): string
{
return $reflector->getName();
}
@@ -75,20 +75,12 @@ class SignatureFormatter implements ReflectorFormatter
/**
* Print the method, property or class modifiers.
*
- * @param \Reflector $reflector
+ * @param \ReflectionMethod|\ReflectionProperty|\ReflectionClass $reflector
*
* @return string Formatted modifiers
*/
- private static function formatModifiers(\Reflector $reflector)
+ private static function formatModifiers(\Reflector $reflector): string
{
- if ($reflector instanceof \ReflectionClass && $reflector->isTrait()) {
- // For some reason, PHP 5.x returns `abstract public` modifiers for
- // traits. Let's just ignore that business entirely.
- if (\version_compare(\PHP_VERSION, '7.0.0', '<')) {
- return '';
- }
- }
-
return \implode(' ', \array_map(function ($modifier) {
return \sprintf('%s ', $modifier);
}, \Reflection::getModifierNames($reflector->getModifiers())));
@@ -101,7 +93,7 @@ class SignatureFormatter implements ReflectorFormatter
*
* @return string Formatted signature
*/
- private static function formatClass(\ReflectionClass $reflector)
+ private static function formatClass(\ReflectionClass $reflector): string
{
$chunks = [];
@@ -142,7 +134,7 @@ class SignatureFormatter implements ReflectorFormatter
*
* @return string Formatted signature
*/
- private static function formatClassConstant($reflector)
+ private static function formatClassConstant($reflector): string
{
$value = $reflector->getValue();
$style = self::getTypeStyle($value);
@@ -163,7 +155,7 @@ class SignatureFormatter implements ReflectorFormatter
*
* @return string Formatted signature
*/
- private static function formatConstant($reflector)
+ private static function formatConstant(ReflectionConstant_ $reflector): string
{
$value = $reflector->getValue();
$style = self::getTypeStyle($value);
@@ -181,10 +173,8 @@ class SignatureFormatter implements ReflectorFormatter
* Helper for getting output style for a given value's type.
*
* @param mixed $value
- *
- * @return string
*/
- private static function getTypeStyle($value)
+ private static function getTypeStyle($value): string
{
if (\is_int($value) || \is_float($value)) {
return 'number';
@@ -204,7 +194,7 @@ class SignatureFormatter implements ReflectorFormatter
*
* @return string Formatted signature
*/
- private static function formatProperty(\ReflectionProperty $reflector)
+ private static function formatProperty(\ReflectionProperty $reflector): string
{
return \sprintf(
'%s $%s ',
@@ -220,7 +210,7 @@ class SignatureFormatter implements ReflectorFormatter
*
* @return string Formatted signature
*/
- private static function formatFunction(\ReflectionFunctionAbstract $reflector)
+ private static function formatFunction(\ReflectionFunctionAbstract $reflector): string
{
return \sprintf(
'function %s%s (%s)%s',
@@ -238,7 +228,7 @@ class SignatureFormatter implements ReflectorFormatter
*
* @return string Formatted return type
*/
- private static function formatFunctionReturnType(\ReflectionFunctionAbstract $reflector)
+ private static function formatFunctionReturnType(\ReflectionFunctionAbstract $reflector): string
{
if (!\method_exists($reflector, 'hasReturnType') || !$reflector->hasReturnType()) {
return '';
@@ -254,7 +244,7 @@ class SignatureFormatter implements ReflectorFormatter
*
* @return string Formatted signature
*/
- private static function formatMethod(\ReflectionMethod $reflector)
+ private static function formatMethod(\ReflectionMethod $reflector): string
{
return \sprintf(
'%s %s',
@@ -270,7 +260,7 @@ class SignatureFormatter implements ReflectorFormatter
*
* @return array
*/
- private static function formatFunctionParams(\ReflectionFunctionAbstract $reflector)
+ private static function formatFunctionParams(\ReflectionFunctionAbstract $reflector): array
{
$params = [];
foreach ($reflector->getParameters() as $param) {
@@ -285,7 +275,7 @@ class SignatureFormatter implements ReflectorFormatter
$hint = \sprintf('%s ', $class->getName());
}
}
- } catch (\Exception $e) {
+ } catch (\Throwable $e) {
// sometimes we just don't know...
// bad class names, or autoloaded classes that haven't been loaded yet, or whathaveyou.
// come to think of it, the only time I've seen this is with the intl extension.
@@ -332,10 +322,8 @@ class SignatureFormatter implements ReflectorFormatter
* Print function param or return type(s).
*
* @param \ReflectionType $type
- *
- * @return string
*/
- private static function formatReflectionType(\ReflectionType $type = null)
+ private static function formatReflectionType(\ReflectionType $type = null): string
{
if ($type === null) {
return '';
diff --git a/vendor/psy/psysh/src/Formatter/TraceFormatter.php b/vendor/psy/psysh/src/Formatter/TraceFormatter.php
index 7a638a519..f9859225b 100644
--- a/vendor/psy/psysh/src/Formatter/TraceFormatter.php
+++ b/vendor/psy/psysh/src/Formatter/TraceFormatter.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -22,10 +22,6 @@ class TraceFormatter
/**
* Format the trace of the given exception.
*
- * @throws \InvalidArgumentException if passed a non-Throwable value
- *
- * @todo type hint $throwable when we drop support for PHP 5.x
- *
* @param \Throwable $throwable The error or exception with a backtrace
* @param FilterOptions $filter (default: null)
* @param int $count (default: PHP_INT_MAX)
@@ -33,12 +29,8 @@ class TraceFormatter
*
* @return string[] Formatted stacktrace lines
*/
- public static function formatTrace($throwable, FilterOptions $filter = null, $count = null, $includePsy = true)
+ public static function formatTrace(\Throwable $throwable, FilterOptions $filter = null, int $count = null, bool $includePsy = true): array
{
- if (!($throwable instanceof \Throwable || $throwable instanceof \Exception)) {
- throw new \InvalidArgumentException('Unable to format non-throwable value');
- }
-
if ($cwd = \getcwd()) {
$cwd = \rtrim($cwd, \DIRECTORY_SEPARATOR).\DIRECTORY_SEPARATOR;
}
diff --git a/vendor/psy/psysh/src/Input/CodeArgument.php b/vendor/psy/psysh/src/Input/CodeArgument.php
index a2189af7f..c41534782 100644
--- a/vendor/psy/psysh/src/Input/CodeArgument.php
+++ b/vendor/psy/psysh/src/Input/CodeArgument.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -39,7 +39,7 @@ class CodeArgument extends InputArgument
*
* @throws \InvalidArgumentException When argument mode is not valid
*/
- public function __construct($name, $mode = null, $description = '', $default = null)
+ public function __construct(string $name, int $mode = null, string $description = '', $default = null)
{
if ($mode & InputArgument::IS_ARRAY) {
throw new \InvalidArgumentException('Argument mode IS_ARRAY is not valid');
diff --git a/vendor/psy/psysh/src/Input/FilterOptions.php b/vendor/psy/psysh/src/Input/FilterOptions.php
index f2c1c629f..64eee3f80 100644
--- a/vendor/psy/psysh/src/Input/FilterOptions.php
+++ b/vendor/psy/psysh/src/Input/FilterOptions.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -31,7 +31,7 @@ class FilterOptions
*
* @return InputOption[]
*/
- public static function getOptions()
+ public static function getOptions(): array
{
return [
new InputOption('grep', 'G', InputOption::VALUE_REQUIRED, 'Limit to items matching the given pattern (string or regex).'),
@@ -73,10 +73,8 @@ class FilterOptions
/**
* Check whether the bound input has filter options.
- *
- * @return bool
*/
- public function hasFilter()
+ public function hasFilter(): bool
{
return $this->filter;
}
@@ -86,10 +84,8 @@ class FilterOptions
*
* @param string $string
* @param array $matches
- *
- * @return bool
*/
- public function match($string, array &$matches = null)
+ public function match(string $string, array &$matches = null): bool
{
return $this->filter === false || (\preg_match($this->pattern, $string, $matches) xor $this->invert);
}
@@ -116,10 +112,8 @@ class FilterOptions
* Check whether a string appears to be a regular expression.
*
* @param string $string
- *
- * @return bool
*/
- private function stringIsRegex($string)
+ private function stringIsRegex(string $string): bool
{
return \substr($string, 0, 1) === '/' && \substr($string, -1) === '/' && \strlen($string) >= 3;
}
@@ -131,7 +125,7 @@ class FilterOptions
*
* @param string $pattern
*/
- private function validateRegex($pattern)
+ private function validateRegex(string $pattern)
{
\set_error_handler([ErrorException::class, 'throwException']);
try {
diff --git a/vendor/psy/psysh/src/Input/ShellInput.php b/vendor/psy/psysh/src/Input/ShellInput.php
index 741e0a544..10ca2b5b0 100644
--- a/vendor/psy/psysh/src/Input/ShellInput.php
+++ b/vendor/psy/psysh/src/Input/ShellInput.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -33,7 +33,7 @@ class ShellInput extends StringInput
*
* @param string $input An array of parameters from the CLI (in the argv format)
*/
- public function __construct($input)
+ public function __construct(string $input)
{
parent::__construct($input);
@@ -81,7 +81,7 @@ class ShellInput extends StringInput
*
* @throws \InvalidArgumentException When unable to parse input (should never happen)
*/
- private function tokenize($input)
+ private function tokenize(string $input): array
{
$tokens = [];
$length = \strlen($input);
@@ -150,7 +150,7 @@ class ShellInput extends StringInput
*
* @throws \RuntimeException When too many arguments are given
*/
- private function parseShellArgument($token, $rest)
+ private function parseShellArgument(string $token, string $rest)
{
$c = \count($this->arguments);
@@ -200,7 +200,7 @@ class ShellInput extends StringInput
*
* @param string $token The current token
*/
- private function parseShortOption($token)
+ private function parseShortOption(string $token)
{
$name = \substr($token, 1);
@@ -223,7 +223,7 @@ class ShellInput extends StringInput
*
* @throws \RuntimeException When option given doesn't exist
*/
- private function parseShortOptionSet($name)
+ private function parseShortOptionSet(string $name)
{
$len = \strlen($name);
for ($i = 0; $i < $len; $i++) {
@@ -247,17 +247,12 @@ class ShellInput extends StringInput
*
* @param string $token The current token
*/
- private function parseLongOption($token)
+ private function parseLongOption(string $token)
{
$name = \substr($token, 2);
if (false !== $pos = \strpos($name, '=')) {
- if ('' === ($value = \substr($name, $pos + 1))) {
- // if no value after "=" then substr() returns "" since php7 only, false before
- // see http://php.net/manual/fr/migration70.incompatible.php#119151
- if (\PHP_VERSION_ID < 70000 && false === $value) {
- $value = '';
- }
+ if (($value = \substr($name, $pos + 1)) === '') {
\array_unshift($this->parsed, [$value, null]);
}
$this->addLongOption(\substr($name, 0, $pos), $value);
@@ -274,7 +269,7 @@ class ShellInput extends StringInput
*
* @throws \RuntimeException When option given doesn't exist
*/
- private function addShortOption($shortcut, $value)
+ private function addShortOption(string $shortcut, $value)
{
if (!$this->definition->hasShortcut($shortcut)) {
throw new \RuntimeException(\sprintf('The "-%s" option does not exist.', $shortcut));
@@ -291,7 +286,7 @@ class ShellInput extends StringInput
*
* @throws \RuntimeException When option given doesn't exist
*/
- private function addLongOption($name, $value)
+ private function addLongOption(string $name, $value)
{
if (!$this->definition->hasOption($name)) {
throw new \RuntimeException(\sprintf('The "--%s" option does not exist.', $name));
diff --git a/vendor/psy/psysh/src/Input/SilentInput.php b/vendor/psy/psysh/src/Input/SilentInput.php
index b4804c611..0c963f544 100644
--- a/vendor/psy/psysh/src/Input/SilentInput.php
+++ b/vendor/psy/psysh/src/Input/SilentInput.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -27,17 +27,15 @@ class SilentInput
*
* @param string $inputString
*/
- public function __construct($inputString)
+ public function __construct(string $inputString)
{
$this->inputString = $inputString;
}
/**
* To. String.
- *
- * @return string
*/
- public function __toString()
+ public function __toString(): string
{
return $this->inputString;
}
diff --git a/vendor/psy/psysh/src/Output/OutputPager.php b/vendor/psy/psysh/src/Output/OutputPager.php
index b9dcdf82d..0652b70bf 100644
--- a/vendor/psy/psysh/src/Output/OutputPager.php
+++ b/vendor/psy/psysh/src/Output/OutputPager.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
diff --git a/vendor/psy/psysh/src/Output/PassthruPager.php b/vendor/psy/psysh/src/Output/PassthruPager.php
index 3eaa9cf78..6ad17b5b9 100644
--- a/vendor/psy/psysh/src/Output/PassthruPager.php
+++ b/vendor/psy/psysh/src/Output/PassthruPager.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
diff --git a/vendor/psy/psysh/src/Output/ProcOutputPager.php b/vendor/psy/psysh/src/Output/ProcOutputPager.php
index d31471ca0..aeaff3685 100644
--- a/vendor/psy/psysh/src/Output/ProcOutputPager.php
+++ b/vendor/psy/psysh/src/Output/ProcOutputPager.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -32,9 +32,9 @@ class ProcOutputPager extends StreamOutput implements OutputPager
* Constructor.
*
* @param StreamOutput $output
- * @param string $cmd Pager process command (default: 'less -R -S -F -X')
+ * @param string $cmd Pager process command (default: 'less -R -F -X')
*/
- public function __construct(StreamOutput $output, $cmd = 'less -R -S -F -X')
+ public function __construct(StreamOutput $output, string $cmd = 'less -R -F -X')
{
$this->stream = $output->getStream();
$this->cmd = $cmd;
@@ -54,6 +54,7 @@ class ProcOutputPager extends StreamOutput implements OutputPager
if (false === @\fwrite($pipe, $message.($newline ? \PHP_EOL : ''))) {
// @codeCoverageIgnoreStart
// should never happen
+ $this->close();
throw new \RuntimeException('Unable to write output');
// @codeCoverageIgnoreEnd
}
diff --git a/vendor/psy/psysh/src/Output/ShellOutput.php b/vendor/psy/psysh/src/Output/ShellOutput.php
index e23666029..543baccb2 100644
--- a/vendor/psy/psysh/src/Output/ShellOutput.php
+++ b/vendor/psy/psysh/src/Output/ShellOutput.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -13,7 +13,6 @@ namespace Psy\Output;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Formatter\OutputFormatterInterface;
-use Symfony\Component\Console\Formatter\OutputFormatterStyle;
use Symfony\Component\Console\Output\ConsoleOutput;
/**
@@ -24,8 +23,13 @@ class ShellOutput extends ConsoleOutput
const NUMBER_LINES = 128;
private $paging = 0;
+
+ /** @var OutputPager */
private $pager;
+ /** @var Theme */
+ private $theme;
+
/**
* Construct a ShellOutput instance.
*
@@ -34,10 +38,11 @@ class ShellOutput extends ConsoleOutput
* @param OutputFormatterInterface|null $formatter (default: null)
* @param string|OutputPager|null $pager (default: null)
*/
- public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null, $pager = null)
+ public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null, $pager = null, $theme = null)
{
parent::__construct($verbosity, $decorated, $formatter);
+ $this->theme = $theme ?? new Theme('modern');
$this->initFormatters();
if ($pager === null) {
@@ -64,7 +69,7 @@ class ShellOutput extends ConsoleOutput
* @param string|array|\Closure $messages A string, array of strings or a callback
* @param int $type (default: 0)
*/
- public function page($messages, $type = 0)
+ public function page($messages, int $type = 0)
{
if (\is_string($messages)) {
$messages = (array) $messages;
@@ -158,6 +163,15 @@ class ShellOutput extends ConsoleOutput
}
}
+ /**
+ * Set the output Theme.
+ */
+ public function setTheme(Theme $theme)
+ {
+ $this->theme = $theme;
+ $this->initFormatters();
+ }
+
/**
* Flush and close the output pager.
*/
@@ -173,38 +187,22 @@ class ShellOutput extends ConsoleOutput
*/
private function initFormatters()
{
- $formatter = $this->getFormatter();
+ $useGrayFallback = !$this->grayExists();
+ $this->theme->applyStyles($this->getFormatter(), $useGrayFallback);
+ $this->theme->applyErrorStyles($this->getErrorOutput()->getFormatter(), $useGrayFallback);
+ }
- $formatter->setStyle('warning', new OutputFormatterStyle('black', 'yellow'));
- $formatter->setStyle('error', new OutputFormatterStyle('white', 'red', ['bold']));
- $formatter->setStyle('aside', new OutputFormatterStyle('blue'));
- $formatter->setStyle('strong', new OutputFormatterStyle(null, null, ['bold']));
- $formatter->setStyle('return', new OutputFormatterStyle('cyan'));
- $formatter->setStyle('urgent', new OutputFormatterStyle('red'));
- $formatter->setStyle('hidden', new OutputFormatterStyle('black'));
+ /**
+ * Checks if the "gray" color exists on the output.
+ */
+ private function grayExists(): bool
+ {
+ try {
+ $this->write('>');
+ } catch (\InvalidArgumentException $e) {
+ return false;
+ }
- // Visibility
- $formatter->setStyle('public', new OutputFormatterStyle(null, null, ['bold']));
- $formatter->setStyle('protected', new OutputFormatterStyle('yellow'));
- $formatter->setStyle('private', new OutputFormatterStyle('red'));
- $formatter->setStyle('global', new OutputFormatterStyle('cyan', null, ['bold']));
- $formatter->setStyle('const', new OutputFormatterStyle('cyan'));
- $formatter->setStyle('class', new OutputFormatterStyle('blue', null, ['underscore']));
- $formatter->setStyle('function', new OutputFormatterStyle(null));
- $formatter->setStyle('default', new OutputFormatterStyle(null));
-
- // Types
- $formatter->setStyle('number', new OutputFormatterStyle('magenta'));
- $formatter->setStyle('integer', new OutputFormatterStyle('magenta'));
- $formatter->setStyle('float', new OutputFormatterStyle('yellow'));
- $formatter->setStyle('string', new OutputFormatterStyle('green'));
- $formatter->setStyle('bool', new OutputFormatterStyle('cyan'));
- $formatter->setStyle('keyword', new OutputFormatterStyle('yellow'));
- $formatter->setStyle('comment', new OutputFormatterStyle('blue'));
- $formatter->setStyle('object', new OutputFormatterStyle('blue'));
- $formatter->setStyle('resource', new OutputFormatterStyle('yellow'));
-
- // Code-specific formatting
- $formatter->setStyle('inline_html', new OutputFormatterStyle('cyan'));
+ return true;
}
}
diff --git a/vendor/psy/psysh/src/Output/Theme.php b/vendor/psy/psysh/src/Output/Theme.php
new file mode 100644
index 000000000..98a73e912
--- /dev/null
+++ b/vendor/psy/psysh/src/Output/Theme.php
@@ -0,0 +1,285 @@
+ true,
+ ];
+
+ const CLASSIC_THEME = [
+ 'compact' => true,
+
+ 'prompt' => '>>> ',
+ 'bufferPrompt' => '... ',
+ 'replayPrompt' => '--> ',
+ 'returnValue' => '=> ',
+ ];
+
+ const DEFAULT_STYLES = [
+ 'info' => ['white', 'blue', ['bold']],
+ 'warning' => ['black', 'yellow'],
+ 'error' => ['white', 'red', ['bold']],
+ 'whisper' => ['gray'],
+
+ 'aside' => ['blue'],
+ 'strong' => [null, null, ['bold']],
+ 'return' => ['cyan'],
+ 'urgent' => ['red'],
+ 'hidden' => ['black'],
+
+ // Visibility
+ 'public' => [null, null, ['bold']],
+ 'protected' => ['yellow'],
+ 'private' => ['red'],
+ 'global' => ['cyan', null, ['bold']],
+ 'const' => ['cyan'],
+ 'class' => ['blue', null, ['underscore']],
+ 'function' => [null],
+ 'default' => [null],
+
+ // Types
+ 'number' => ['magenta'],
+ 'integer' => ['magenta'],
+ 'float' => ['yellow'],
+ 'string' => ['green'],
+ 'bool' => ['cyan'],
+ 'keyword' => ['yellow'],
+ 'comment' => ['blue'],
+ 'object' => ['blue'],
+ 'resource' => ['yellow'],
+
+ // Code-specific formatting
+ 'inline_html' => ['cyan'],
+ ];
+
+ const ERROR_STYLES = ['info', 'warning', 'error', 'whisper'];
+
+ private $compact = false;
+
+ private $prompt = '> ';
+ private $bufferPrompt = '. ';
+ private $replayPrompt = '- ';
+ private $returnValue = '= ';
+
+ private $grayFallback = 'blue';
+
+ private $styles = [];
+
+ /**
+ * @param string|array $config theme name or config options
+ */
+ public function __construct($config = 'modern')
+ {
+ if (\is_string($config)) {
+ switch ($config) {
+ case 'modern':
+ $config = static::MODERN_THEME;
+ break;
+
+ case 'compact':
+ $config = static::COMPACT_THEME;
+ break;
+
+ case 'classic':
+ $config = static::CLASSIC_THEME;
+ break;
+
+ default:
+ \trigger_error(\sprintf('Unknown theme: %s', $config), \E_USER_NOTICE);
+ $config = static::MODERN_THEME;
+ break;
+ }
+ }
+
+ if (!\is_array($config)) {
+ throw new \InvalidArgumentException('Invalid theme config');
+ }
+
+ foreach ($config as $name => $value) {
+ switch ($name) {
+ case 'compact':
+ $this->setCompact($value);
+ break;
+
+ case 'prompt':
+ $this->setPrompt($value);
+ break;
+
+ case 'bufferPrompt':
+ $this->setBufferPrompt($value);
+ break;
+
+ case 'replayPrompt':
+ $this->setReplayPrompt($value);
+ break;
+
+ case 'returnValue':
+ $this->setReturnValue($value);
+ break;
+
+ case 'grayFallback':
+ $this->setGrayFallback($value);
+ break;
+
+ case 'compact':
+ $this->setCompact($value);
+ break;
+ }
+ }
+
+ $this->setStyles($config['styles'] ?? []);
+ }
+
+ /**
+ * Enable or disable compact output.
+ */
+ public function setCompact(bool $compact)
+ {
+ $this->compact = $compact;
+ }
+
+ /**
+ * Get whether to use compact output.
+ */
+ public function compact(): bool
+ {
+ return $this->compact;
+ }
+
+ /**
+ * Set the prompt string.
+ */
+ public function setPrompt(string $prompt)
+ {
+ $this->prompt = $prompt;
+ }
+
+ /**
+ * Get the prompt string.
+ */
+ public function prompt(): string
+ {
+ return $this->prompt;
+ }
+
+ /**
+ * Set the buffer prompt string (used for multi-line input continuation).
+ */
+ public function setBufferPrompt(string $bufferPrompt)
+ {
+ $this->bufferPrompt = $bufferPrompt;
+ }
+
+ /**
+ * Get the buffer prompt string (used for multi-line input continuation).
+ */
+ public function bufferPrompt(): string
+ {
+ return $this->bufferPrompt;
+ }
+
+ /**
+ * Set the prompt string used when replaying history.
+ */
+ public function setReplayPrompt(string $replayPrompt)
+ {
+ $this->replayPrompt = $replayPrompt;
+ }
+
+ /**
+ * Get the prompt string used when replaying history.
+ */
+ public function replayPrompt(): string
+ {
+ return $this->replayPrompt;
+ }
+
+ /**
+ * Set the return value marker.
+ */
+ public function setReturnValue(string $returnValue)
+ {
+ $this->returnValue = $returnValue;
+ }
+
+ /**
+ * Get the return value marker.
+ */
+ public function returnValue(): string
+ {
+ return $this->returnValue;
+ }
+
+ /**
+ * Set the fallback color when "gray" is unavailable.
+ */
+ public function setGrayFallback(string $grayFallback)
+ {
+ $this->grayFallback = $grayFallback;
+ }
+
+ /**
+ * Set the shell output formatter styles.
+ *
+ * Accepts a map from style name to [fg, bg, options], for example:
+ *
+ * [
+ * 'error' => ['white', 'red', ['bold']],
+ * 'warning' => ['black', 'yellow'],
+ * ]
+ *
+ * Foreground, background or options can be null, or even omitted entirely.
+ */
+ public function setStyles(array $styles)
+ {
+ foreach (\array_keys(static::DEFAULT_STYLES) as $name) {
+ $this->styles[$name] = $styles[$name] ?? static::DEFAULT_STYLES[$name];
+ }
+ }
+
+ /**
+ * Apply the current output formatter styles.
+ */
+ public function applyStyles(OutputFormatterInterface $formatter, bool $useGrayFallback)
+ {
+ foreach (\array_keys(static::DEFAULT_STYLES) as $name) {
+ $formatter->setStyle($name, new OutputFormatterStyle(...$this->getStyle($name, $useGrayFallback)));
+ }
+ }
+
+ /**
+ * Apply the current output formatter error styles.
+ */
+ public function applyErrorStyles(OutputFormatterInterface $errorFormatter, bool $useGrayFallback)
+ {
+ foreach (static::ERROR_STYLES as $name) {
+ $errorFormatter->setStyle($name, new OutputFormatterStyle(...$this->getStyle($name, $useGrayFallback)));
+ }
+ }
+
+ private function getStyle(string $name, bool $useGrayFallback): array
+ {
+ return \array_map(function ($style) use ($useGrayFallback) {
+ return ($useGrayFallback && $style === 'gray') ? $this->grayFallback : $style;
+ }, $this->styles[$name]);
+ }
+}
diff --git a/vendor/psy/psysh/src/ParserFactory.php b/vendor/psy/psysh/src/ParserFactory.php
index 90c75bc28..e7c15c5db 100644
--- a/vendor/psy/psysh/src/ParserFactory.php
+++ b/vendor/psy/psysh/src/ParserFactory.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -11,7 +11,6 @@
namespace Psy;
-use PhpParser\Lexer;
use PhpParser\Parser;
use PhpParser\ParserFactory as OriginalParserFactory;
@@ -28,25 +27,13 @@ class ParserFactory
/**
* Possible kinds of parsers for the factory, from PHP parser library.
*
- * @return array
+ * @return string[]
*/
- public static function getPossibleKinds()
+ public static function getPossibleKinds(): array
{
return ['ONLY_PHP5', 'ONLY_PHP7', 'PREFER_PHP5', 'PREFER_PHP7'];
}
- /**
- * Is this parser factory supports kinds?
- *
- * PHP parser < 2.0 doesn't support kinds, >= 2.0 — does.
- *
- * @return bool
- */
- public function hasKindsSupport()
- {
- return \class_exists(OriginalParserFactory::class);
- }
-
/**
* Default kind (if supported, based on current interpreter's version).
*
@@ -54,38 +41,26 @@ class ParserFactory
*/
public function getDefaultKind()
{
- if ($this->hasKindsSupport()) {
- return \version_compare(\PHP_VERSION, '7.0', '>=') ? static::ONLY_PHP7 : static::ONLY_PHP5;
- }
+ return static::ONLY_PHP7;
}
/**
* New parser instance with given kind.
*
* @param string|null $kind One of class constants (only for PHP parser 2.0 and above)
- *
- * @return Parser
*/
- public function createParser($kind = null)
+ public function createParser($kind = null): Parser
{
- if ($this->hasKindsSupport()) {
- $originalFactory = new OriginalParserFactory();
+ $originalFactory = new OriginalParserFactory();
- $kind = $kind ?: $this->getDefaultKind();
+ $kind = $kind ?: $this->getDefaultKind();
- if (!\in_array($kind, static::getPossibleKinds())) {
- throw new \InvalidArgumentException('Unknown parser kind');
- }
-
- $parser = $originalFactory->create(\constant(OriginalParserFactory::class.'::'.$kind));
- } else {
- if ($kind !== null) {
- throw new \InvalidArgumentException('Install PHP Parser v2.x to specify parser kind');
- }
-
- $parser = new Parser(new Lexer());
+ if (!\in_array($kind, static::getPossibleKinds())) {
+ throw new \InvalidArgumentException('Unknown parser kind');
}
+ $parser = $originalFactory->create(\constant(OriginalParserFactory::class.'::'.$kind));
+
return $parser;
}
}
diff --git a/vendor/psy/psysh/src/Readline/GNUReadline.php b/vendor/psy/psysh/src/Readline/GNUReadline.php
index 179cd29ae..877e1a309 100644
--- a/vendor/psy/psysh/src/Readline/GNUReadline.php
+++ b/vendor/psy/psysh/src/Readline/GNUReadline.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -34,10 +34,8 @@ class GNUReadline implements Readline
*
* NOTE: As of PHP 7.4, PHP sometimes has history support in the Libedit
* wrapper, so that will use the GNUReadline implementation as well!
- *
- * @return bool
*/
- public static function isSupported()
+ public static function isSupported(): bool
{
return \function_exists('readline') && \function_exists('readline_list_history');
}
@@ -47,34 +45,24 @@ class GNUReadline implements Readline
*
* Currently, the GNU readline implementation does, but the libedit wrapper does not.
*/
- public static function supportsBracketedPaste()
+ public static function supportsBracketedPaste(): bool
{
- return self::isSupported() && \stripos(\readline_info('library_version'), 'editline') === false;
+ return self::isSupported() && \stripos(\readline_info('library_version') ?: '', 'editline') === false;
}
- /**
- * GNU Readline constructor.
- *
- * @param string|false $historyFile
- * @param int $historySize
- * @param bool $eraseDups
- */
public function __construct($historyFile = null, $historySize = 0, $eraseDups = false)
{
$this->historyFile = ($historyFile !== null) ? $historyFile : false;
$this->historySize = $historySize;
$this->eraseDups = $eraseDups;
- // HHVM errors on this, so HHVM doesn't get a readline_name.
- if (!\defined('HHVM_VERSION')) {
- \readline_info('readline_name', 'psysh');
- }
+ \readline_info('readline_name', 'psysh');
}
/**
* {@inheritdoc}
*/
- public function addHistory($line)
+ public function addHistory(string $line): bool
{
if ($res = \readline_add_history($line)) {
$this->writeHistory();
@@ -86,7 +74,7 @@ class GNUReadline implements Readline
/**
* {@inheritdoc}
*/
- public function clearHistory()
+ public function clearHistory(): bool
{
if ($res = \readline_clear_history()) {
$this->writeHistory();
@@ -98,7 +86,7 @@ class GNUReadline implements Readline
/**
* {@inheritdoc}
*/
- public function listHistory()
+ public function listHistory(): array
{
return \readline_list_history();
}
@@ -106,17 +94,9 @@ class GNUReadline implements Readline
/**
* {@inheritdoc}
*/
- public function readHistory()
+ public function readHistory(): bool
{
- // Workaround PHP bug #69054
- //
- // If open_basedir is set, readline_read_history() segfaults. This was fixed in 5.6.7:
- //
- // https://github.com/php/php-src/blob/423a057023ef3c00d2ffc16a6b43ba01d0f71796/NEWS#L19-L21
- //
- if (\version_compare(\PHP_VERSION, '5.6.7', '>=') || !\ini_get('open_basedir')) {
- \readline_read_history();
- }
+ \readline_read_history();
\readline_clear_history();
return \readline_read_history($this->historyFile);
@@ -125,7 +105,7 @@ class GNUReadline implements Readline
/**
* {@inheritdoc}
*/
- public function readline($prompt = null)
+ public function readline(string $prompt = null)
{
return \readline($prompt);
}
@@ -141,7 +121,7 @@ class GNUReadline implements Readline
/**
* {@inheritdoc}
*/
- public function writeHistory()
+ public function writeHistory(): bool
{
// We have to write history first, since it is used
// by Libedit to list history
diff --git a/vendor/psy/psysh/src/Readline/Hoa/Autocompleter.php b/vendor/psy/psysh/src/Readline/Hoa/Autocompleter.php
new file mode 100644
index 000000000..6955de622
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/Autocompleter.php
@@ -0,0 +1,57 @@
+setAutocompleters($autocompleters);
+
+ return;
+ }
+
+ /**
+ * Complete a word.
+ * Returns null for no word, a full-word or an array of full-words.
+ */
+ public function complete(&$prefix)
+ {
+ foreach ($this->getAutocompleters() as $autocompleter) {
+ $preg = \preg_match(
+ '#('.$autocompleter->getWordDefinition().')$#u',
+ $prefix,
+ $match
+ );
+
+ if (0 === $preg) {
+ continue;
+ }
+
+ $_prefix = $match[0];
+
+ if (null === $out = $autocompleter->complete($_prefix)) {
+ continue;
+ }
+
+ $prefix = $_prefix;
+
+ return $out;
+ }
+
+ return null;
+ }
+
+ /**
+ * Set/initialize list of autocompleters.
+ */
+ protected function setAutocompleters(array $autocompleters)
+ {
+ $old = $this->_autocompleters;
+ $this->_autocompleters = new \ArrayObject($autocompleters);
+
+ return $old;
+ }
+
+ /**
+ * Get list of autocompleters.
+ */
+ public function getAutocompleters()
+ {
+ return $this->_autocompleters;
+ }
+
+ /**
+ * Get definition of a word.
+ */
+ public function getWordDefinition(): string
+ {
+ return '.*';
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/AutocompleterPath.php b/vendor/psy/psysh/src/Readline/Hoa/AutocompleterPath.php
new file mode 100644
index 000000000..a922b7898
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/AutocompleterPath.php
@@ -0,0 +1,194 @@
+setRoot($root);
+ }
+
+ if (null !== $iteratorFactory) {
+ $this->setIteratorFactory($iteratorFactory);
+ }
+ }
+
+ /**
+ * Complete a word.
+ * Returns null for no word, a full-word or an array of full-words.
+ */
+ public function complete(&$prefix)
+ {
+ $root = $this->getRoot();
+
+ if (static::PWD === $root) {
+ $root = \getcwd();
+ }
+
+ $path = $root.\DIRECTORY_SEPARATOR.$prefix;
+
+ if (!\is_dir($path)) {
+ $path = \dirname($path).\DIRECTORY_SEPARATOR;
+ $prefix = \basename($prefix);
+ } else {
+ $prefix = null;
+ }
+
+ $iteratorFactory = $this->getIteratorFactory() ?:
+ static::getDefaultIteratorFactory();
+
+ try {
+ $iterator = $iteratorFactory($path);
+ $out = [];
+ $length = \mb_strlen($prefix);
+
+ foreach ($iterator as $fileinfo) {
+ $filename = $fileinfo->getFilename();
+
+ if (null === $prefix ||
+ (\mb_substr($filename, 0, $length) === $prefix)) {
+ if ($fileinfo->isDir()) {
+ $out[] = $filename.'/';
+ } else {
+ $out[] = $filename;
+ }
+ }
+ }
+ } catch (\Exception $e) {
+ return null;
+ }
+
+ $count = \count($out);
+
+ if (1 === $count) {
+ return $out[0];
+ }
+
+ if (0 === $count) {
+ return null;
+ }
+
+ return $out;
+ }
+
+ /**
+ * Get definition of a word.
+ */
+ public function getWordDefinition(): string
+ {
+ return '/?[\w\d\\_\-\.]+(/[\w\d\\_\-\.]*)*';
+ }
+
+ /**
+ * Set root.
+ */
+ public function setRoot(string $root)
+ {
+ $old = $this->_root;
+ $this->_root = $root;
+
+ return $old;
+ }
+
+ /**
+ * Get root.
+ */
+ public function getRoot()
+ {
+ return $this->_root;
+ }
+
+ /**
+ * Set iterator factory (a finder).
+ */
+ public function setIteratorFactory(\Closure $iteratorFactory)
+ {
+ $old = $this->_iteratorFactory;
+ $this->_iteratorFactory = $iteratorFactory;
+
+ return $old;
+ }
+
+ /**
+ * Get iterator factory.
+ */
+ public function getIteratorFactory()
+ {
+ return $this->_iteratorFactory;
+ }
+
+ /**
+ * Get default iterator factory (based on \DirectoryIterator).
+ */
+ public static function getDefaultIteratorFactory()
+ {
+ return function ($path) {
+ return new \DirectoryIterator($path);
+ };
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/AutocompleterWord.php b/vendor/psy/psysh/src/Readline/Hoa/AutocompleterWord.php
new file mode 100644
index 000000000..c60823eac
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/AutocompleterWord.php
@@ -0,0 +1,119 @@
+setWords($words);
+ }
+
+ /**
+ * Complete a word.
+ * Returns null for no word, a full-word or an array of full-words.
+ *
+ * @param string &$prefix Prefix to autocomplete
+ *
+ * @return mixed
+ */
+ public function complete(&$prefix)
+ {
+ $out = [];
+ $length = \mb_strlen($prefix);
+
+ foreach ($this->getWords() as $word) {
+ if (\mb_substr($word, 0, $length) === $prefix) {
+ $out[] = $word;
+ }
+ }
+
+ if (empty($out)) {
+ return null;
+ }
+
+ if (1 === \count($out)) {
+ return $out[0];
+ }
+
+ return $out;
+ }
+
+ /**
+ * Get definition of a word.
+ */
+ public function getWordDefinition(): string
+ {
+ return '\b\w+';
+ }
+
+ /**
+ * Set list of words.
+ *
+ * @param array $words words
+ *
+ * @return array
+ */
+ public function setWords(array $words)
+ {
+ $old = $this->_words;
+ $this->_words = $words;
+
+ return $old;
+ }
+
+ /**
+ * Get list of words.
+ */
+ public function getWords(): array
+ {
+ return $this->_words;
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/Console.php b/vendor/psy/psysh/src/Readline/Hoa/Console.php
new file mode 100644
index 000000000..17b1fecc6
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/Console.php
@@ -0,0 +1,347 @@
+ $repeat) {
+ return;
+ } elseif (1 === $repeat) {
+ $handle = \explode(' ', $steps);
+ } else {
+ $handle = \explode(' ', $steps, 1);
+ }
+
+ $tput = Console::getTput();
+ $output = Console::getOutput();
+
+ foreach ($handle as $step) {
+ switch ($step) {
+ case 'u':
+ case 'up':
+ case '↑':
+ $output->writeAll(
+ \str_replace(
+ '%p1%d',
+ $repeat,
+ $tput->get('parm_up_cursor')
+ )
+ );
+
+ break;
+
+ case 'U':
+ case 'UP':
+ static::moveTo(null, 1);
+
+ break;
+
+ case 'r':
+ case 'right':
+ case '→':
+ $output->writeAll(
+ \str_replace(
+ '%p1%d',
+ $repeat,
+ $tput->get('parm_right_cursor')
+ )
+ );
+
+ break;
+
+ case 'R':
+ case 'RIGHT':
+ static::moveTo(9999);
+
+ break;
+
+ case 'd':
+ case 'down':
+ case '↓':
+ $output->writeAll(
+ \str_replace(
+ '%p1%d',
+ $repeat,
+ $tput->get('parm_down_cursor')
+ )
+ );
+
+ break;
+
+ case 'D':
+ case 'DOWN':
+ static::moveTo(null, 9999);
+
+ break;
+
+ case 'l':
+ case 'left':
+ case '←':
+ $output->writeAll(
+ \str_replace(
+ '%p1%d',
+ $repeat,
+ $tput->get('parm_left_cursor')
+ )
+ );
+
+ break;
+
+ case 'L':
+ case 'LEFT':
+ static::moveTo(1);
+
+ break;
+ }
+ }
+ }
+
+ /**
+ * Move to the line X and the column Y.
+ * If null, use the current coordinate.
+ */
+ public static function moveTo(int $x = null, int $y = null)
+ {
+ if (null === $x || null === $y) {
+ $position = static::getPosition();
+
+ if (null === $x) {
+ $x = $position['x'];
+ }
+
+ if (null === $y) {
+ $y = $position['y'];
+ }
+ }
+
+ Console::getOutput()->writeAll(
+ \str_replace(
+ ['%i%p1%d', '%p2%d'],
+ [$y, $x],
+ Console::getTput()->get('cursor_address')
+ )
+ );
+ }
+
+ /**
+ * Get current position (x and y) of the cursor.
+ */
+ public static function getPosition(): array
+ {
+ $tput = Console::getTput();
+ $user7 = $tput->get('user7');
+
+ if (null === $user7) {
+ return [
+ 'x' => 0,
+ 'y' => 0,
+ ];
+ }
+
+ Console::getOutput()->writeAll($user7);
+
+ $input = Console::getInput();
+
+ // Read $tput->get('user6').
+ $input->read(2); // skip \033 and [.
+
+ $x = null;
+ $y = null;
+ $handle = &$y;
+
+ while (true) {
+ $char = $input->readCharacter();
+
+ switch ($char) {
+ case ';':
+ $handle = &$x;
+
+ break;
+
+ case 'R':
+ break 2;
+
+ default:
+ $handle .= $char;
+ }
+ }
+
+ return [
+ 'x' => (int) $x,
+ 'y' => (int) $y,
+ ];
+ }
+
+ /**
+ * Save current position.
+ */
+ public static function save()
+ {
+ Console::getOutput()->writeAll(
+ Console::getTput()->get('save_cursor')
+ );
+ }
+
+ /**
+ * Restore cursor to the last saved position.
+ */
+ public static function restore()
+ {
+ Console::getOutput()->writeAll(
+ Console::getTput()->get('restore_cursor')
+ );
+ }
+
+ /**
+ * Clear the screen.
+ * Part can be:
+ * • a, all, ↕ : clear entire screen and static::move(1, 1);
+ * • u, up, ↑ : clear from cursor to beginning of the screen;
+ * • r, right, → : clear from cursor to the end of the line;
+ * • d, down, ↓ : clear from cursor to end of the screen;
+ * • l, left, ← : clear from cursor to beginning of the screen;
+ * • line, ↔ : clear all the line and static::move(1).
+ * Parts can be concatenated by a single space.
+ */
+ public static function clear(string $parts = 'all')
+ {
+ $tput = Console::getTput();
+ $output = Console::getOutput();
+
+ foreach (\explode(' ', $parts) as $part) {
+ switch ($part) {
+ case 'a':
+ case 'all':
+ case '↕':
+ $output->writeAll($tput->get('clear_screen'));
+ static::moveTo(1, 1);
+
+ break;
+
+ case 'u':
+ case 'up':
+ case '↑':
+ $output->writeAll("\033[1J");
+
+ break;
+
+ case 'r':
+ case 'right':
+ case '→':
+ $output->writeAll($tput->get('clr_eol'));
+
+ break;
+
+ case 'd':
+ case 'down':
+ case '↓':
+ $output->writeAll($tput->get('clr_eos'));
+
+ break;
+
+ case 'l':
+ case 'left':
+ case '←':
+ $output->writeAll($tput->get('clr_bol'));
+
+ break;
+
+ case 'line':
+ case '↔':
+ $output->writeAll("\r".$tput->get('clr_eol'));
+
+ break;
+ }
+ }
+ }
+
+ /**
+ * Hide the cursor.
+ */
+ public static function hide()
+ {
+ Console::getOutput()->writeAll(
+ Console::getTput()->get('cursor_invisible')
+ );
+ }
+
+ /**
+ * Show the cursor.
+ */
+ public static function show()
+ {
+ Console::getOutput()->writeAll(
+ Console::getTput()->get('cursor_visible')
+ );
+ }
+
+ /**
+ * Colorize cursor.
+ * Attributes can be:
+ * • n, normal : normal;
+ * • b, bold : bold;
+ * • u, underlined : underlined;
+ * • bl, blink : blink;
+ * • i, inverse : inverse;
+ * • !b, !bold : normal weight;
+ * • !u, !underlined : not underlined;
+ * • !bl, !blink : steady;
+ * • !i, !inverse : positive;
+ * • fg(color), foreground(color) : set foreground to “color”;
+ * • bg(color), background(color) : set background to “color”.
+ * “color” can be:
+ * • default;
+ * • black;
+ * • red;
+ * • green;
+ * • yellow;
+ * • blue;
+ * • magenta;
+ * • cyan;
+ * • white;
+ * • 0-256 (classic palette);
+ * • #hexa.
+ * Attributes can be concatenated by a single space.
+ */
+ public static function colorize(string $attributes)
+ {
+ static $_rgbTo256 = null;
+
+ if (null === $_rgbTo256) {
+ $_rgbTo256 = [
+ '000000', '800000', '008000', '808000', '000080', '800080',
+ '008080', 'c0c0c0', '808080', 'ff0000', '00ff00', 'ffff00',
+ '0000ff', 'ff00ff', '00ffff', 'ffffff', '000000', '00005f',
+ '000087', '0000af', '0000d7', '0000ff', '005f00', '005f5f',
+ '005f87', '005faf', '005fd7', '005fff', '008700', '00875f',
+ '008787', '0087af', '0087d7', '0087ff', '00af00', '00af5f',
+ '00af87', '00afaf', '00afd7', '00afff', '00d700', '00d75f',
+ '00d787', '00d7af', '00d7d7', '00d7ff', '00ff00', '00ff5f',
+ '00ff87', '00ffaf', '00ffd7', '00ffff', '5f0000', '5f005f',
+ '5f0087', '5f00af', '5f00d7', '5f00ff', '5f5f00', '5f5f5f',
+ '5f5f87', '5f5faf', '5f5fd7', '5f5fff', '5f8700', '5f875f',
+ '5f8787', '5f87af', '5f87d7', '5f87ff', '5faf00', '5faf5f',
+ '5faf87', '5fafaf', '5fafd7', '5fafff', '5fd700', '5fd75f',
+ '5fd787', '5fd7af', '5fd7d7', '5fd7ff', '5fff00', '5fff5f',
+ '5fff87', '5fffaf', '5fffd7', '5fffff', '870000', '87005f',
+ '870087', '8700af', '8700d7', '8700ff', '875f00', '875f5f',
+ '875f87', '875faf', '875fd7', '875fff', '878700', '87875f',
+ '878787', '8787af', '8787d7', '8787ff', '87af00', '87af5f',
+ '87af87', '87afaf', '87afd7', '87afff', '87d700', '87d75f',
+ '87d787', '87d7af', '87d7d7', '87d7ff', '87ff00', '87ff5f',
+ '87ff87', '87ffaf', '87ffd7', '87ffff', 'af0000', 'af005f',
+ 'af0087', 'af00af', 'af00d7', 'af00ff', 'af5f00', 'af5f5f',
+ 'af5f87', 'af5faf', 'af5fd7', 'af5fff', 'af8700', 'af875f',
+ 'af8787', 'af87af', 'af87d7', 'af87ff', 'afaf00', 'afaf5f',
+ 'afaf87', 'afafaf', 'afafd7', 'afafff', 'afd700', 'afd75f',
+ 'afd787', 'afd7af', 'afd7d7', 'afd7ff', 'afff00', 'afff5f',
+ 'afff87', 'afffaf', 'afffd7', 'afffff', 'd70000', 'd7005f',
+ 'd70087', 'd700af', 'd700d7', 'd700ff', 'd75f00', 'd75f5f',
+ 'd75f87', 'd75faf', 'd75fd7', 'd75fff', 'd78700', 'd7875f',
+ 'd78787', 'd787af', 'd787d7', 'd787ff', 'd7af00', 'd7af5f',
+ 'd7af87', 'd7afaf', 'd7afd7', 'd7afff', 'd7d700', 'd7d75f',
+ 'd7d787', 'd7d7af', 'd7d7d7', 'd7d7ff', 'd7ff00', 'd7ff5f',
+ 'd7ff87', 'd7ffaf', 'd7ffd7', 'd7ffff', 'ff0000', 'ff005f',
+ 'ff0087', 'ff00af', 'ff00d7', 'ff00ff', 'ff5f00', 'ff5f5f',
+ 'ff5f87', 'ff5faf', 'ff5fd7', 'ff5fff', 'ff8700', 'ff875f',
+ 'ff8787', 'ff87af', 'ff87d7', 'ff87ff', 'ffaf00', 'ffaf5f',
+ 'ffaf87', 'ffafaf', 'ffafd7', 'ffafff', 'ffd700', 'ffd75f',
+ 'ffd787', 'ffd7af', 'ffd7d7', 'ffd7ff', 'ffff00', 'ffff5f',
+ 'ffff87', 'ffffaf', 'ffffd7', 'ffffff', '080808', '121212',
+ '1c1c1c', '262626', '303030', '3a3a3a', '444444', '4e4e4e',
+ '585858', '606060', '666666', '767676', '808080', '8a8a8a',
+ '949494', '9e9e9e', 'a8a8a8', 'b2b2b2', 'bcbcbc', 'c6c6c6',
+ 'd0d0d0', 'dadada', 'e4e4e4', 'eeeeee',
+ ];
+ }
+
+ $tput = Console::getTput();
+
+ if (1 >= $tput->count('max_colors')) {
+ return;
+ }
+
+ $handle = [];
+
+ foreach (\explode(' ', $attributes) as $attribute) {
+ switch ($attribute) {
+ case 'n':
+ case 'normal':
+ $handle[] = 0;
+
+ break;
+
+ case 'b':
+ case 'bold':
+ $handle[] = 1;
+
+ break;
+
+ case 'u':
+ case 'underlined':
+ $handle[] = 4;
+
+ break;
+
+ case 'bl':
+ case 'blink':
+ $handle[] = 5;
+
+ break;
+
+ case 'i':
+ case 'inverse':
+ $handle[] = 7;
+
+ break;
+
+ case '!b':
+ case '!bold':
+ $handle[] = 22;
+
+ break;
+
+ case '!u':
+ case '!underlined':
+ $handle[] = 24;
+
+ break;
+
+ case '!bl':
+ case '!blink':
+ $handle[] = 25;
+
+ break;
+
+ case '!i':
+ case '!inverse':
+ $handle[] = 27;
+
+ break;
+
+ default:
+ if (0 === \preg_match('#^([^\(]+)\(([^\)]+)\)$#', $attribute, $m)) {
+ break;
+ }
+
+ $shift = 0;
+
+ switch ($m[1]) {
+ case 'fg':
+ case 'foreground':
+ $shift = 0;
+
+ break;
+
+ case 'bg':
+ case 'background':
+ $shift = 10;
+
+ break;
+
+ default:
+ break 2;
+ }
+
+ $_handle = 0;
+ $_keyword = true;
+
+ switch ($m[2]) {
+ case 'black':
+ $_handle = 30;
+
+ break;
+
+ case 'red':
+ $_handle = 31;
+
+ break;
+
+ case 'green':
+ $_handle = 32;
+
+ break;
+
+ case 'yellow':
+ $_handle = 33;
+
+ break;
+
+ case 'blue':
+ $_handle = 34;
+
+ break;
+
+ case 'magenta':
+ $_handle = 35;
+
+ break;
+
+ case 'cyan':
+ $_handle = 36;
+
+ break;
+
+ case 'white':
+ $_handle = 37;
+
+ break;
+
+ case 'default':
+ $_handle = 39;
+
+ break;
+
+ default:
+ $_keyword = false;
+
+ if (256 <= $tput->count('max_colors') &&
+ '#' === $m[2][0]) {
+ $rgb = \hexdec(\substr($m[2], 1));
+ $r = ($rgb >> 16) & 255;
+ $g = ($rgb >> 8) & 255;
+ $b = $rgb & 255;
+ $distance = null;
+
+ foreach ($_rgbTo256 as $i => $_rgb) {
+ $_rgb = \hexdec($_rgb);
+ $_r = ($_rgb >> 16) & 255;
+ $_g = ($_rgb >> 8) & 255;
+ $_b = $_rgb & 255;
+
+ $d = \sqrt(
+ ($_r - $r) ** 2
+ + ($_g - $g) ** 2
+ + ($_b - $b) ** 2
+ );
+
+ if (null === $distance ||
+ $d <= $distance) {
+ $distance = $d;
+ $_handle = $i;
+ }
+ }
+ } else {
+ $_handle = (int) ($m[2]);
+ }
+ }
+
+ if (true === $_keyword) {
+ $handle[] = $_handle + $shift;
+ } else {
+ $handle[] = (38 + $shift).';5;'.$_handle;
+ }
+ }
+ }
+
+ Console::getOutput()->writeAll("\033[".\implode(';', $handle).'m');
+
+ return;
+ }
+
+ /**
+ * Change color number to a specific RGB color.
+ */
+ public static function changeColor(int $fromCode, int $toColor)
+ {
+ $tput = Console::getTput();
+
+ if (true !== $tput->has('can_change')) {
+ return;
+ }
+
+ $r = ($toColor >> 16) & 255;
+ $g = ($toColor >> 8) & 255;
+ $b = $toColor & 255;
+
+ Console::getOutput()->writeAll(
+ \str_replace(
+ [
+ '%p1%d',
+ 'rgb:',
+ '%p2%{255}%*%{1000}%/%2.2X/',
+ '%p3%{255}%*%{1000}%/%2.2X/',
+ '%p4%{255}%*%{1000}%/%2.2X',
+ ],
+ [
+ $fromCode,
+ '',
+ \sprintf('%02x', $r),
+ \sprintf('%02x', $g),
+ \sprintf('%02x', $b),
+ ],
+ $tput->get('initialize_color')
+ )
+ );
+
+ return;
+ }
+
+ /**
+ * Set cursor style.
+ * Style can be:
+ * • b, block, ▋: block;
+ * • u, underline, _: underline;
+ * • v, vertical, |: vertical.
+ */
+ public static function setStyle(string $style, bool $blink = true)
+ {
+ if (\defined('PHP_WINDOWS_VERSION_PLATFORM')) {
+ return;
+ }
+
+ switch ($style) {
+ case 'u':
+ case 'underline':
+ case '_':
+ $_style = 2;
+
+ break;
+
+ case 'v':
+ case 'vertical':
+ case '|':
+ $_style = 5;
+
+ break;
+
+ case 'b':
+ case 'block':
+ case '▋':
+ default:
+ $_style = 1;
+
+ break;
+ }
+
+ if (false === $blink) {
+ ++$_style;
+ }
+
+ // Not sure what tput entry we can use here…
+ Console::getOutput()->writeAll("\033[".$_style.' q');
+
+ return;
+ }
+
+ /**
+ * Make a stupid “bip”.
+ */
+ public static function bip()
+ {
+ Console::getOutput()->writeAll(
+ Console::getTput()->get('bell')
+ );
+ }
+}
+
+/*
+ * Advanced interaction.
+ */
+Console::advancedInteraction();
diff --git a/vendor/psy/psysh/src/Readline/Hoa/ConsoleException.php b/vendor/psy/psysh/src/Readline/Hoa/ConsoleException.php
new file mode 100644
index 000000000..17e6f607b
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/ConsoleException.php
@@ -0,0 +1,46 @@
+_input = $input;
+
+ return;
+ }
+
+ /**
+ * Get underlying stream.
+ */
+ public function getStream(): StreamIn
+ {
+ return $this->_input;
+ }
+
+ /**
+ * Test for end-of-file.
+ */
+ public function eof(): bool
+ {
+ return $this->_input->eof();
+ }
+
+ /**
+ * Read n characters.
+ */
+ public function read(int $length)
+ {
+ return $this->_input->read($length);
+ }
+
+ /**
+ * Alias of $this->read().
+ */
+ public function readString(int $length)
+ {
+ return $this->_input->readString($length);
+ }
+
+ /**
+ * Read a character.
+ */
+ public function readCharacter()
+ {
+ return $this->_input->readCharacter();
+ }
+
+ /**
+ * Read a boolean.
+ */
+ public function readBoolean()
+ {
+ return $this->_input->readBoolean();
+ }
+
+ /**
+ * Read an integer.
+ */
+ public function readInteger(int $length = 1)
+ {
+ return $this->_input->readInteger($length);
+ }
+
+ /**
+ * Read a float.
+ */
+ public function readFloat(int $length = 1)
+ {
+ return $this->_input->readFloat($length);
+ }
+
+ /**
+ * Read an array.
+ * Alias of the $this->scanf() method.
+ */
+ public function readArray($argument = null)
+ {
+ return $this->_input->readArray($argument);
+ }
+
+ /**
+ * Read a line.
+ */
+ public function readLine()
+ {
+ return $this->_input->readLine();
+ }
+
+ /**
+ * Read all, i.e. read as much as possible.
+ */
+ public function readAll(int $offset = 0)
+ {
+ return $this->_input->readAll($offset);
+ }
+
+ /**
+ * Parse input from a stream according to a format.
+ */
+ public function scanf(string $format): array
+ {
+ return $this->_input->scanf($format);
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/ConsoleOutput.php b/vendor/psy/psysh/src/Readline/Hoa/ConsoleOutput.php
new file mode 100644
index 000000000..fbba894c9
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/ConsoleOutput.php
@@ -0,0 +1,208 @@
+_output = $output;
+
+ return;
+ }
+
+ /**
+ * Get the real output stream.
+ */
+ public function getStream(): StreamOut
+ {
+ return $this->_output;
+ }
+
+ /**
+ * Write n characters.
+ */
+ public function write(string $string, int $length)
+ {
+ if (0 > $length) {
+ throw new ConsoleException('Length must be greater than 0, given %d.', 0, $length);
+ }
+
+ $out = \substr($string, 0, $length);
+
+ if (true === $this->isMultiplexerConsidered()) {
+ if (true === Console::isTmuxRunning()) {
+ $out =
+ "\033Ptmux;".
+ \str_replace("\033", "\033\033", $out).
+ "\033\\";
+ }
+
+ $length = \strlen($out);
+ }
+
+ if (null === $this->_output) {
+ echo $out;
+ } else {
+ $this->_output->write($out, $length);
+ }
+ }
+
+ /**
+ * Write a string.
+ */
+ public function writeString(string $string)
+ {
+ $string = (string) $string;
+
+ return $this->write($string, \strlen($string));
+ }
+
+ /**
+ * Write a character.
+ */
+ public function writeCharacter(string $character)
+ {
+ return $this->write((string) $character[0], 1);
+ }
+
+ /**
+ * Write a boolean.
+ */
+ public function writeBoolean(bool $boolean)
+ {
+ return $this->write(((bool) $boolean) ? '1' : '0', 1);
+ }
+
+ /**
+ * Write an integer.
+ */
+ public function writeInteger(int $integer)
+ {
+ $integer = (string) (int) $integer;
+
+ return $this->write($integer, \strlen($integer));
+ }
+
+ /**
+ * Write a float.
+ */
+ public function writeFloat(float $float)
+ {
+ $float = (string) (float) $float;
+
+ return $this->write($float, \strlen($float));
+ }
+
+ /**
+ * Write an array.
+ */
+ public function writeArray(array $array)
+ {
+ $array = \var_export($array, true);
+
+ return $this->write($array, \strlen($array));
+ }
+
+ /**
+ * Write a line.
+ */
+ public function writeLine(string $line)
+ {
+ if (false === $n = \strpos($line, "\n")) {
+ return $this->write($line."\n", \strlen($line) + 1);
+ }
+
+ ++$n;
+
+ return $this->write(\substr($line, 0, $n), $n);
+ }
+
+ /**
+ * Write all, i.e. as much as possible.
+ */
+ public function writeAll(string $string)
+ {
+ return $this->write($string ?? '', \strlen($string ?? ''));
+ }
+
+ /**
+ * Truncate a stream to a given length.
+ */
+ public function truncate(int $size): bool
+ {
+ return false;
+ }
+
+ /**
+ * Consider the multiplexer (if running) while writing on the output.
+ */
+ public function considerMultiplexer(bool $consider): bool
+ {
+ $old = $this->_considerMultiplexer;
+ $this->_considerMultiplexer = $consider;
+
+ return $old;
+ }
+
+ /**
+ * Check whether the multiplexer must be considered or not.
+ */
+ public function isMultiplexerConsidered(): bool
+ {
+ return $this->_considerMultiplexer;
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/ConsoleProcessus.php b/vendor/psy/psysh/src/Readline/Hoa/ConsoleProcessus.php
new file mode 100644
index 000000000..69bf1ddb1
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/ConsoleProcessus.php
@@ -0,0 +1,892 @@
+ value, or input).
+ */
+ protected $_options = [];
+
+ /**
+ * Current working directory.
+ */
+ protected $_cwd = null;
+
+ /**
+ * Environment.
+ */
+ protected $_environment = null;
+
+ /**
+ * Timeout.
+ */
+ protected $_timeout = 30;
+
+ /**
+ * Descriptor.
+ */
+ protected $_descriptors = [
+ 0 => ['pipe', 'r'],
+ 1 => ['pipe', 'w'],
+ 2 => ['pipe', 'w'],
+ ];
+
+ /**
+ * Pipe descriptors of the processus.
+ */
+ protected $_pipes = null;
+
+ /**
+ * Seekability of pipes.
+ */
+ protected $_seekable = [];
+
+ /**
+ * Start a processus.
+ */
+ public function __construct(
+ string $command,
+ array $options = null,
+ array $descriptors = null,
+ string $cwd = null,
+ array $environment = null,
+ int $timeout = 30
+ ) {
+ $this->setCommand($command);
+
+ if (null !== $options) {
+ $this->setOptions($options);
+ }
+
+ if (null !== $descriptors) {
+ $this->_descriptors = [];
+
+ foreach ($descriptors as $descriptor => $nature) {
+ if (isset($this->_descriptors[$descriptor])) {
+ throw new ConsoleException('Pipe descriptor %d already exists, cannot '.'redefine it.', 0, $descriptor);
+ }
+
+ $this->_descriptors[$descriptor] = $nature;
+ }
+ }
+
+ $this->setCwd($cwd ?: \getcwd());
+
+ if (null !== $environment) {
+ $this->setEnvironment($environment);
+ }
+
+ $this->setTimeout($timeout);
+ parent::__construct($this->getCommandLine(), null, true);
+ $this->getListener()->addIds(['input', 'output', 'timeout', 'start', 'stop']);
+
+ return;
+ }
+
+ /**
+ * Open the stream and return the associated resource.
+ */
+ protected function &_open(string $streamName, StreamContext $context = null)
+ {
+ $out = @\proc_open(
+ $streamName,
+ $this->_descriptors,
+ $this->_pipes,
+ $this->getCwd(),
+ $this->getEnvironment()
+ );
+
+ if (false === $out) {
+ throw new ConsoleException('Something wrong happen when running %s.', 1, $streamName);
+ }
+
+ return $out;
+ }
+
+ /**
+ * Close the current stream.
+ */
+ protected function _close(): bool
+ {
+ foreach ($this->_pipes as $pipe) {
+ @\fclose($pipe);
+ }
+
+ return (bool) @\proc_close($this->getStream());
+ }
+
+ /**
+ * Run the process and fire events (amongst start, stop, input, output and
+ * timeout).
+ * If an event returns false, it will close the current pipe.
+ * For a simple run without firing events, use the $this->open() method.
+ */
+ public function run()
+ {
+ if (false === $this->isOpened()) {
+ $this->open();
+ } else {
+ $this->_close();
+ $this->_setStream($this->_open(
+ $this->getStreamName(),
+ $this->getStreamContext()
+ ));
+ }
+
+ $this->getListener()->fire('start', new EventBucket());
+
+ $_read = [];
+ $_write = [];
+ $_except = [];
+
+ foreach ($this->_pipes as $p => $pipe) {
+ switch ($this->_descriptors[$p][1]) {
+ case 'r':
+ \stream_set_blocking($pipe, false);
+ $_write[] = $pipe;
+
+ break;
+
+ case 'w':
+ case 'a':
+ \stream_set_blocking($pipe, true);
+ $_read[] = $pipe;
+
+ break;
+ }
+ }
+
+ while (true) {
+ foreach ($_read as $i => $r) {
+ if (false === \is_resource($r)) {
+ unset($_read[$i]);
+ }
+ }
+
+ foreach ($_write as $i => $w) {
+ if (false === \is_resource($w)) {
+ unset($_write[$i]);
+ }
+ }
+
+ foreach ($_except as $i => $e) {
+ if (false === \is_resource($e)) {
+ unset($_except[$i]);
+ }
+ }
+
+ if (empty($_read) && empty($_write) && empty($_except)) {
+ break;
+ }
+
+ $read = $_read;
+ $write = $_write;
+ $except = $_except;
+ $select = \stream_select($read, $write, $except, $this->getTimeout());
+
+ if (0 === $select) {
+ $this->getListener()->fire('timeout', new EventBucket());
+
+ break;
+ }
+
+ foreach ($read as $i => $_r) {
+ $pipe = \array_search($_r, $this->_pipes);
+ $line = $this->readLine($pipe);
+
+ if (false === $line) {
+ $result = [false];
+ } else {
+ $result = $this->getListener()->fire(
+ 'output',
+ new EventBucket([
+ 'pipe' => $pipe,
+ 'line' => $line,
+ ])
+ );
+ }
+
+ if (true === \feof($_r) || \in_array(false, $result, true)) {
+ \fclose($_r);
+ unset($_read[$i]);
+
+ break;
+ }
+ }
+
+ foreach ($write as $j => $_w) {
+ $result = $this->getListener()->fire(
+ 'input',
+ new EventBucket([
+ 'pipe' => \array_search($_w, $this->_pipes),
+ ])
+ );
+
+ if (true === \feof($_w) || \in_array(false, $result, true)) {
+ \fclose($_w);
+ unset($_write[$j]);
+ }
+ }
+
+ if (empty($_read)) {
+ break;
+ }
+ }
+
+ $this->getListener()->fire('stop', new EventBucket());
+
+ return;
+ }
+
+ /**
+ * Get pipe resource.
+ */
+ protected function getPipe(int $pipe)
+ {
+ if (!isset($this->_pipes[$pipe])) {
+ throw new ConsoleException('Pipe descriptor %d does not exist, cannot read from it.', 2, $pipe);
+ }
+
+ return $this->_pipes[$pipe];
+ }
+
+ /**
+ * Check if a pipe is seekable or not.
+ */
+ protected function isPipeSeekable(int $pipe): bool
+ {
+ if (!isset($this->_seekable[$pipe])) {
+ $_pipe = $this->getPipe($pipe);
+ $data = \stream_get_meta_data($_pipe);
+ $this->_seekable[$pipe] = $data['seekable'];
+ }
+
+ return $this->_seekable[$pipe];
+ }
+
+ /**
+ * Test for end-of-file.
+ */
+ public function eof(int $pipe = 1): bool
+ {
+ return \feof($this->getPipe($pipe));
+ }
+
+ /**
+ * Read n characters.
+ */
+ public function read(int $length, int $pipe = 1)
+ {
+ if (0 > $length) {
+ throw new ConsoleException('Length must be greater than 0, given %d.', 3, $length);
+ }
+
+ return \fread($this->getPipe($pipe), $length);
+ }
+
+ /**
+ * Alias of $this->read().
+ */
+ public function readString(int $length, int $pipe = 1)
+ {
+ return $this->read($length, $pipe);
+ }
+
+ /**
+ * Read a character.
+ */
+ public function readCharacter(int $pipe = 1)
+ {
+ return \fgetc($this->getPipe($pipe));
+ }
+
+ /**
+ * Read a boolean.
+ */
+ public function readBoolean(int $pipe = 1)
+ {
+ return (bool) $this->read(1, $pipe);
+ }
+
+ /**
+ * Read an integer.
+ */
+ public function readInteger(int $length = 1, int $pipe = 1)
+ {
+ return (int) $this->read($length, $pipe);
+ }
+
+ /**
+ * Read a float.
+ */
+ public function readFloat(int $length = 1, int $pipe = 1)
+ {
+ return (float) $this->read($length, $pipe);
+ }
+
+ /**
+ * Read an array.
+ * Alias of the $this->scanf() method.
+ */
+ public function readArray(string $format = null, int $pipe = 1)
+ {
+ return $this->scanf($format, $pipe);
+ }
+
+ /**
+ * Read a line.
+ */
+ public function readLine(int $pipe = 1)
+ {
+ return \stream_get_line($this->getPipe($pipe), 1 << 15, "\n");
+ }
+
+ /**
+ * Read all, i.e. read as much as possible.
+ */
+ public function readAll(int $offset = -1, int $pipe = 1)
+ {
+ $_pipe = $this->getPipe($pipe);
+
+ if (true === $this->isPipeSeekable($pipe)) {
+ $offset += \ftell($_pipe);
+ } else {
+ $offset = -1;
+ }
+
+ return \stream_get_contents($_pipe, -1, $offset);
+ }
+
+ /**
+ * Parse input from a stream according to a format.
+ */
+ public function scanf(string $format, int $pipe = 1): array
+ {
+ return \fscanf($this->getPipe($pipe), $format);
+ }
+
+ /**
+ * Write n characters.
+ */
+ public function write(string $string, int $length, int $pipe = 0)
+ {
+ if (0 > $length) {
+ throw new ConsoleException('Length must be greater than 0, given %d.', 4, $length);
+ }
+
+ return \fwrite($this->getPipe($pipe), $string, $length);
+ }
+
+ /**
+ * Write a string.
+ */
+ public function writeString(string $string, int $pipe = 0)
+ {
+ $string = (string) $string;
+
+ return $this->write($string, \strlen($string), $pipe);
+ }
+
+ /**
+ * Write a character.
+ */
+ public function writeCharacter(string $char, int $pipe = 0)
+ {
+ return $this->write((string) $char[0], 1, $pipe);
+ }
+
+ /**
+ * Write a boolean.
+ */
+ public function writeBoolean(bool $boolean, int $pipe = 0)
+ {
+ return $this->write((string) (bool) $boolean, 1, $pipe);
+ }
+
+ /**
+ * Write an integer.
+ */
+ public function writeInteger(int $integer, int $pipe = 0)
+ {
+ $integer = (string) (int) $integer;
+
+ return $this->write($integer, \strlen($integer), $pipe);
+ }
+
+ /**
+ * Write a float.
+ */
+ public function writeFloat(float $float, int $pipe = 0)
+ {
+ $float = (string) (float) $float;
+
+ return $this->write($float, \strlen($float), $pipe);
+ }
+
+ /**
+ * Write an array.
+ */
+ public function writeArray(array $array, int $pipe = 0)
+ {
+ $array = \var_export($array, true);
+
+ return $this->write($array, \strlen($array), $pipe);
+ }
+
+ /**
+ * Write a line.
+ */
+ public function writeLine(string $line, int $pipe = 0)
+ {
+ if (false === $n = \strpos($line, "\n")) {
+ return $this->write($line."\n", \strlen($line) + 1, $pipe);
+ }
+
+ ++$n;
+
+ return $this->write(\substr($line, 0, $n), $n, $pipe);
+ }
+
+ /**
+ * Write all, i.e. as much as possible.
+ */
+ public function writeAll(string $string, int $pipe = 0)
+ {
+ return $this->write($string, \strlen($string), $pipe);
+ }
+
+ /**
+ * Truncate a file to a given length.
+ */
+ public function truncate(int $size, int $pipe = 0): bool
+ {
+ return \ftruncate($this->getPipe($pipe), $size);
+ }
+
+ /**
+ * Get filename component of path.
+ */
+ public function getBasename(): string
+ {
+ return \basename($this->getCommand());
+ }
+
+ /**
+ * Get directory name component of path.
+ */
+ public function getDirname(): string
+ {
+ return \dirname($this->getCommand());
+ }
+
+ /**
+ * Get status.
+ */
+ public function getStatus(): array
+ {
+ return \proc_get_status($this->getStream());
+ }
+
+ /**
+ * Get exit code (alias of $this->getStatus()['exitcode']);.
+ */
+ public function getExitCode(): int
+ {
+ $handle = $this->getStatus();
+
+ return $handle['exitcode'];
+ }
+
+ /**
+ * Whether the processus have ended successfully.
+ *
+ * @return bool
+ */
+ public function isSuccessful(): bool
+ {
+ return 0 === $this->getExitCode();
+ }
+
+ /**
+ * Terminate the process.
+ *
+ * Valid signals are self::SIGHUP, SIGINT, SIGQUIT, SIGABRT, SIGKILL,
+ * SIGALRM and SIGTERM.
+ */
+ public function terminate(int $signal = self::SIGTERM): bool
+ {
+ return \proc_terminate($this->getStream(), $signal);
+ }
+
+ /**
+ * Set command name.
+ */
+ protected function setCommand(string $command)
+ {
+ $old = $this->_command;
+ $this->_command = \escapeshellcmd($command);
+
+ return $old;
+ }
+
+ /**
+ * Get command name.
+ */
+ public function getCommand()
+ {
+ return $this->_command;
+ }
+
+ /**
+ * Set command options.
+ */
+ protected function setOptions(array $options): array
+ {
+ foreach ($options as &$option) {
+ $option = \escapeshellarg($option);
+ }
+
+ $old = $this->_options;
+ $this->_options = $options;
+
+ return $old;
+ }
+
+ /**
+ * Get options.
+ */
+ public function getOptions(): array
+ {
+ return $this->_options;
+ }
+
+ /**
+ * Get command-line.
+ */
+ public function getCommandLine(): string
+ {
+ $out = $this->getCommand();
+
+ foreach ($this->getOptions() as $key => $value) {
+ if (!\is_int($key)) {
+ $out .= ' '.$key.'='.$value;
+ } else {
+ $out .= ' '.$value;
+ }
+ }
+
+ return $out;
+ }
+
+ /**
+ * Set current working directory of the process.
+ */
+ protected function setCwd(string $cwd)
+ {
+ $old = $this->_cwd;
+ $this->_cwd = $cwd;
+
+ return $old;
+ }
+
+ /**
+ * Get current working directory of the process.
+ */
+ public function getCwd(): string
+ {
+ return $this->_cwd;
+ }
+
+ /**
+ * Set environment of the process.
+ */
+ protected function setEnvironment(array $environment)
+ {
+ $old = $this->_environment;
+ $this->_environment = $environment;
+
+ return $old;
+ }
+
+ /**
+ * Get environment of the process.
+ */
+ public function getEnvironment()
+ {
+ return $this->_environment;
+ }
+
+ /**
+ * Set timeout of the process.
+ */
+ public function setTimeout(int $timeout)
+ {
+ $old = $this->_timeout;
+ $this->_timeout = $timeout;
+
+ return $old;
+ }
+
+ /**
+ * Get timeout of the process.
+ */
+ public function getTimeout(): int
+ {
+ return $this->_timeout;
+ }
+
+ /**
+ * Set process title.
+ */
+ public static function setTitle(string $title)
+ {
+ \cli_set_process_title($title);
+ }
+
+ /**
+ * Get process title.
+ */
+ public static function getTitle()
+ {
+ return \cli_get_process_title();
+ }
+
+ /**
+ * Found the place of a binary.
+ */
+ public static function locate(string $binary)
+ {
+ if (isset($_ENV['PATH'])) {
+ $separator = ':';
+ $path = &$_ENV['PATH'];
+ } elseif (isset($_SERVER['PATH'])) {
+ $separator = ':';
+ $path = &$_SERVER['PATH'];
+ } elseif (isset($_SERVER['Path'])) {
+ $separator = ';';
+ $path = &$_SERVER['Path'];
+ } else {
+ return null;
+ }
+
+ foreach (\explode($separator, $path) as $directory) {
+ if (true === \file_exists($out = $directory.\DIRECTORY_SEPARATOR.$binary)) {
+ return $out;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Quick process execution.
+ * Returns only the STDOUT.
+ */
+ public static function execute(string $commandLine, bool $escape = true): string
+ {
+ if (true === $escape) {
+ $commandLine = \escapeshellcmd($commandLine);
+ }
+
+ return \rtrim(\shell_exec($commandLine) ?? '');
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/ConsoleTput.php b/vendor/psy/psysh/src/Readline/Hoa/ConsoleTput.php
new file mode 100644
index 000000000..ba627e379
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/ConsoleTput.php
@@ -0,0 +1,841 @@
+parse($terminfo);
+
+ return;
+ }
+
+ /**
+ * Parse.
+ */
+ protected function parse(string $terminfo): array
+ {
+ if (!\file_exists($terminfo)) {
+ throw new ConsoleException('Terminfo file %s does not exist.', 0, $terminfo);
+ }
+
+ $data = \file_get_contents($terminfo);
+ $length = \strlen($data);
+ $out = ['file' => $terminfo];
+
+ $headers = [
+ 'data_size' => $length,
+ 'header_size' => 12,
+ 'magic_number' => (\ord($data[1]) << 8) | \ord($data[0]),
+ 'names_size' => (\ord($data[3]) << 8) | \ord($data[2]),
+ 'bool_count' => (\ord($data[5]) << 8) | \ord($data[4]),
+ 'number_count' => (\ord($data[7]) << 8) | \ord($data[6]),
+ 'string_count' => (\ord($data[9]) << 8) | \ord($data[8]),
+ 'string_table_size' => (\ord($data[11]) << 8) | \ord($data[10]),
+ ];
+ $out['headers'] = $headers;
+
+ // Names.
+ $i = $headers['header_size'];
+ $nameAndDescription = \explode('|', \substr($data, $i, $headers['names_size'] - 1));
+ $out['name'] = $nameAndDescription[0];
+ $out['description'] = $nameAndDescription[1];
+
+ // Booleans.
+ $i += $headers['names_size'];
+ $booleans = [];
+ $booleanNames = &static::$_booleans;
+
+ for (
+ $e = 0, $max = $i + $headers['bool_count'];
+ $i < $max;
+ ++$e, ++$i
+ ) {
+ $booleans[$booleanNames[$e]] = 1 === \ord($data[$i]);
+ }
+
+ $out['booleans'] = $booleans;
+
+ // Numbers.
+ if (1 === ($i % 2)) {
+ ++$i;
+ }
+
+ $numbers = [];
+ $numberNames = &static::$_numbers;
+
+ for (
+ $e = 0, $max = $i + $headers['number_count'] * 2;
+ $i < $max;
+ ++$e, $i += 2
+ ) {
+ $name = $numberNames[$e];
+ $data_i0 = \ord($data[$i]);
+ $data_i1 = \ord($data[$i + 1]);
+
+ if ($data_i1 === 255 && $data_i0 === 255) {
+ $numbers[$name] = -1;
+ } else {
+ $numbers[$name] = ($data_i1 << 8) | $data_i0;
+ }
+ }
+
+ $out['numbers'] = $numbers;
+
+ // Strings.
+ $strings = [];
+ $stringNames = &static::$_strings;
+ $ii = $i + $headers['string_count'] * 2;
+
+ for (
+ $e = 0, $max = $ii;
+ $i < $max;
+ ++$e, $i += 2
+ ) {
+ $name = $stringNames[$e];
+ $data_i0 = \ord($data[$i]);
+ $data_i1 = \ord($data[$i + 1]);
+
+ if ($data_i1 === 255 && $data_i0 === 255) {
+ continue;
+ }
+
+ $a = ($data_i1 << 8) | $data_i0;
+ $strings[$name] = $a;
+
+ if (65534 === $a) {
+ continue;
+ }
+
+ $b = $ii + $a;
+ $c = $b;
+
+ while ($c < $length && \ord($data[$c])) {
+ $c++;
+ }
+
+ $value = \substr($data, $b, $c - $b);
+ $strings[$name] = false !== $value ? $value : null;
+ }
+
+ $out['strings'] = $strings;
+
+ return $this->_informations = $out;
+ }
+
+ /**
+ * Get all informations.
+ */
+ public function getInformations(): array
+ {
+ return $this->_informations;
+ }
+
+ /**
+ * Get a boolean value.
+ */
+ public function has(string $boolean): bool
+ {
+ if (!isset($this->_informations['booleans'][$boolean])) {
+ return false;
+ }
+
+ return $this->_informations['booleans'][$boolean];
+ }
+
+ /**
+ * Get a number value.
+ */
+ public function count(string $number): int
+ {
+ if (!isset($this->_informations['numbers'][$number])) {
+ return 0;
+ }
+
+ return $this->_informations['numbers'][$number];
+ }
+
+ /**
+ * Get a string value.
+ */
+ public function get(string $string)
+ {
+ if (!isset($this->_informations['strings'][$string])) {
+ return null;
+ }
+
+ return $this->_informations['strings'][$string];
+ }
+
+ /**
+ * Get current term profile.
+ */
+ public static function getTerm(): string
+ {
+ return
+ isset($_SERVER['TERM']) && !empty($_SERVER['TERM'])
+ ? $_SERVER['TERM']
+ : (\defined('PHP_WINDOWS_VERSION_PLATFORM') ? 'windows-ansi' : 'xterm');
+ }
+
+ /**
+ * Get pathname to the current terminfo.
+ */
+ public static function getTerminfo($term = null): string
+ {
+ $paths = [];
+
+ if (isset($_SERVER['TERMINFO'])) {
+ $paths[] = $_SERVER['TERMINFO'];
+ }
+
+ if (isset($_SERVER['HOME'])) {
+ $paths[] = $_SERVER['HOME'].\DIRECTORY_SEPARATOR.'.terminfo';
+ }
+
+ if (isset($_SERVER['TERMINFO_DIRS'])) {
+ foreach (\explode(':', $_SERVER['TERMINFO_DIRS']) as $path) {
+ $paths[] = $path;
+ }
+ }
+
+ $paths[] = '/usr/share/terminfo';
+ $paths[] = '/usr/share/lib/terminfo';
+ $paths[] = '/lib/terminfo';
+ $paths[] = '/usr/lib/terminfo';
+ $paths[] = '/usr/local/share/terminfo';
+ $paths[] = '/usr/local/share/lib/terminfo';
+ $paths[] = '/usr/local/lib/terminfo';
+ $paths[] = '/usr/local/ncurses/lib/terminfo';
+ $paths[] = 'hoa://Library/Terminfo';
+
+ $term = $term ?: static::getTerm();
+ $fileHexa = \dechex(\ord($term[0])).\DIRECTORY_SEPARATOR.$term;
+ $fileAlpha = $term[0].\DIRECTORY_SEPARATOR.$term;
+ $pathname = null;
+
+ foreach ($paths as $path) {
+ if (\file_exists($_ = $path.\DIRECTORY_SEPARATOR.$fileHexa) ||
+ \file_exists($_ = $path.\DIRECTORY_SEPARATOR.$fileAlpha)) {
+ $pathname = $_;
+
+ break;
+ }
+ }
+
+ if (null === $pathname && 'xterm' !== $term) {
+ return static::getTerminfo('xterm');
+ }
+
+ return $pathname ?? '';
+ }
+
+ /**
+ * Check whether all required terminfo capabilities are defined.
+ */
+ public static function isSupported(): bool
+ {
+ if (static::getTerminfo() === '') {
+ return false;
+ }
+
+ $requiredVars = [
+ 'clear_screen',
+ 'clr_bol',
+ 'clr_eol',
+ 'clr_eos',
+ 'initialize_color',
+ 'parm_down_cursor',
+ 'parm_index',
+ 'parm_left_cursor',
+ 'parm_right_cursor',
+ 'parm_rindex',
+ 'parm_up_cursor',
+ 'user6',
+ 'user7',
+ ];
+
+ $tput = new self();
+
+ foreach ($requiredVars as $var) {
+ if ($tput->get($var) === null) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/ConsoleWindow.php b/vendor/psy/psysh/src/Readline/Hoa/ConsoleWindow.php
new file mode 100644
index 000000000..fe77e05de
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/ConsoleWindow.php
@@ -0,0 +1,529 @@
+writeAll("\033[8;".$y.';'.$x.'t');
+
+ return;
+ }
+
+ /**
+ * Get current size (x and y) of the window.
+ */
+ public static function getSize(): array
+ {
+ if (\defined('PHP_WINDOWS_VERSION_PLATFORM')) {
+ $modecon = \explode("\n", \ltrim(ConsoleProcessus::execute('mode con')));
+
+ $_y = \trim($modecon[2]);
+ \preg_match('#[^:]+:\s*([0-9]+)#', $_y, $matches);
+ $y = (int) $matches[1];
+
+ $_x = \trim($modecon[3]);
+ \preg_match('#[^:]+:\s*([0-9]+)#', $_x, $matches);
+ $x = (int) $matches[1];
+
+ return [
+ 'x' => $x,
+ 'y' => $y,
+ ];
+ }
+
+ $term = '';
+
+ if (isset($_SERVER['TERM'])) {
+ $term = 'TERM="'.$_SERVER['TERM'].'" ';
+ }
+
+ $command = $term.'tput cols && '.$term.'tput lines';
+ $tput = ConsoleProcessus::execute($command, false);
+
+ if (!empty($tput)) {
+ list($x, $y) = \explode("\n", $tput);
+
+ return [
+ 'x' => (int) $x,
+ 'y' => (int) $y,
+ ];
+ }
+
+ // DECSLPP.
+ Console::getOutput()->writeAll("\033[18t");
+
+ $input = Console::getInput();
+
+ // Read \033[8;y;xt.
+ $input->read(4); // skip \033, [, 8 and ;.
+
+ $x = null;
+ $y = null;
+ $handle = &$y;
+
+ while (true) {
+ $char = $input->readCharacter();
+
+ switch ($char) {
+ case ';':
+ $handle = &$x;
+
+ break;
+
+ case 't':
+ break 2;
+
+ default:
+ if (false === \ctype_digit($char)) {
+ break 2;
+ }
+
+ $handle .= $char;
+ }
+ }
+
+ if (null === $x || null === $y) {
+ return [
+ 'x' => 0,
+ 'y' => 0,
+ ];
+ }
+
+ return [
+ 'x' => (int) $x,
+ 'y' => (int) $y,
+ ];
+ }
+
+ /**
+ * Move to X and Y (in pixels).
+ */
+ public static function moveTo(int $x, int $y)
+ {
+ if (\defined('PHP_WINDOWS_VERSION_PLATFORM')) {
+ return;
+ }
+
+ // DECSLPP.
+ Console::getOutput()->writeAll("\033[3;".$x.';'.$y.'t');
+
+ return;
+ }
+
+ /**
+ * Get current position (x and y) of the window (in pixels).
+ */
+ public static function getPosition(): array
+ {
+ if (\defined('PHP_WINDOWS_VERSION_PLATFORM')) {
+ return ['x' => 0, 'y' => 0];
+ }
+
+ // DECSLPP.
+ Console::getOutput()->writeAll("\033[13t");
+
+ $input = Console::getInput();
+
+ // Read \033[3;x;yt.
+ $input->read(4); // skip \033, [, 3 and ;.
+
+ $x = null;
+ $y = null;
+ $handle = &$x;
+
+ while (true) {
+ $char = $input->readCharacter();
+
+ switch ($char) {
+ case ';':
+ $handle = &$y;
+
+ break;
+
+ case 't':
+ break 2;
+
+ default:
+ $handle .= $char;
+ }
+ }
+
+ return [
+ 'x' => (int) $x,
+ 'y' => (int) $y,
+ ];
+ }
+
+ /**
+ * Scroll whole page.
+ * Directions can be:
+ * • u, up, ↑ : scroll whole page up;
+ * • d, down, ↓ : scroll whole page down.
+ * Directions can be concatenated by a single space.
+ */
+ public static function scroll(string $directions, int $repeat = 1)
+ {
+ if (\defined('PHP_WINDOWS_VERSION_PLATFORM')) {
+ return;
+ }
+
+ if (1 > $repeat) {
+ return;
+ } elseif (1 === $repeat) {
+ $handle = \explode(' ', $directions);
+ } else {
+ $handle = \explode(' ', $directions, 1);
+ }
+
+ $tput = Console::getTput();
+ $count = ['up' => 0, 'down' => 0];
+
+ foreach ($handle as $direction) {
+ switch ($direction) {
+ case 'u':
+ case 'up':
+ case '↑':
+ ++$count['up'];
+
+ break;
+
+ case 'd':
+ case 'down':
+ case '↓':
+ ++$count['down'];
+
+ break;
+ }
+ }
+
+ $output = Console::getOutput();
+
+ if (0 < $count['up']) {
+ $output->writeAll(
+ \str_replace(
+ '%p1%d',
+ $count['up'] * $repeat,
+ $tput->get('parm_index')
+ )
+ );
+ }
+
+ if (0 < $count['down']) {
+ $output->writeAll(
+ \str_replace(
+ '%p1%d',
+ $count['down'] * $repeat,
+ $tput->get('parm_rindex')
+ )
+ );
+ }
+
+ return;
+ }
+
+ /**
+ * Minimize the window.
+ */
+ public static function minimize()
+ {
+ if (\defined('PHP_WINDOWS_VERSION_PLATFORM')) {
+ return;
+ }
+
+ // DECSLPP.
+ Console::getOutput()->writeAll("\033[2t");
+
+ return;
+ }
+
+ /**
+ * Restore the window (de-minimize).
+ */
+ public static function restore()
+ {
+ if (\defined('PHP_WINDOWS_VERSION_PLATFORM')) {
+ return;
+ }
+
+ Console::getOutput()->writeAll("\033[1t");
+
+ return;
+ }
+
+ /**
+ * Raise the window to the front of the stacking order.
+ */
+ public static function raise()
+ {
+ if (\defined('PHP_WINDOWS_VERSION_PLATFORM')) {
+ return;
+ }
+
+ Console::getOutput()->writeAll("\033[5t");
+
+ return;
+ }
+
+ /**
+ * Lower the window to the bottom of the stacking order.
+ */
+ public static function lower()
+ {
+ if (\defined('PHP_WINDOWS_VERSION_PLATFORM')) {
+ return;
+ }
+
+ Console::getOutput()->writeAll("\033[6t");
+
+ return;
+ }
+
+ /**
+ * Set title.
+ */
+ public static function setTitle(string $title)
+ {
+ if (\defined('PHP_WINDOWS_VERSION_PLATFORM')) {
+ return;
+ }
+
+ // DECSLPP.
+ Console::getOutput()->writeAll("\033]0;".$title."\033\\");
+
+ return;
+ }
+
+ /**
+ * Get title.
+ */
+ public static function getTitle()
+ {
+ if (\defined('PHP_WINDOWS_VERSION_PLATFORM')) {
+ return null;
+ }
+
+ // DECSLPP.
+ Console::getOutput()->writeAll("\033[21t");
+
+ $input = Console::getInput();
+ $read = [$input->getStream()->getStream()];
+ $write = [];
+ $except = [];
+ $out = null;
+
+ if (0 === \stream_select($read, $write, $except, 0, 50000)) {
+ return $out;
+ }
+
+ // Read \033]l\033\
+ $input->read(3); // skip \033, ] and l.
+
+ while (true) {
+ $char = $input->readCharacter();
+
+ if ("\033" === $char) {
+ $chaar = $input->readCharacter();
+
+ if ('\\' === $chaar) {
+ break;
+ }
+
+ $char .= $chaar;
+ }
+
+ $out .= $char;
+ }
+
+ return $out;
+ }
+
+ /**
+ * Get label.
+ */
+ public static function getLabel()
+ {
+ if (\defined('PHP_WINDOWS_VERSION_PLATFORM')) {
+ return null;
+ }
+
+ // DECSLPP.
+ Console::getOutput()->writeAll("\033[20t");
+
+ $input = Console::getInput();
+ $read = [$input->getStream()->getStream()];
+ $write = [];
+ $except = [];
+ $out = null;
+
+ if (0 === \stream_select($read, $write, $except, 0, 50000)) {
+ return $out;
+ }
+
+ // Read \033]L\033\
+ $input->read(3); // skip \033, ] and L.
+
+ while (true) {
+ $char = $input->readCharacter();
+
+ if ("\033" === $char) {
+ $chaar = $input->readCharacter();
+
+ if ('\\' === $chaar) {
+ break;
+ }
+
+ $char .= $chaar;
+ }
+
+ $out .= $char;
+ }
+
+ return $out;
+ }
+
+ /**
+ * Refresh the window.
+ */
+ public static function refresh()
+ {
+ if (\defined('PHP_WINDOWS_VERSION_PLATFORM')) {
+ return;
+ }
+
+ // DECSLPP.
+ Console::getOutput()->writeAll("\033[7t");
+
+ return;
+ }
+
+ /**
+ * Set clipboard value.
+ */
+ public static function copy(string $data)
+ {
+ if (\defined('PHP_WINDOWS_VERSION_PLATFORM')) {
+ return;
+ }
+
+ $out = "\033]52;;".\base64_encode($data)."\033\\";
+ $output = Console::getOutput();
+ $considerMultiplexer = $output->considerMultiplexer(true);
+
+ $output->writeAll($out);
+ $output->considerMultiplexer($considerMultiplexer);
+
+ return;
+ }
+}
+
+/*
+ * Advanced interaction.
+ */
+Console::advancedInteraction();
+
+/*
+ * Event.
+ */
+if (\function_exists('pcntl_signal')) {
+ ConsoleWindow::getInstance();
+ \pcntl_signal(
+ \SIGWINCH,
+ function () {
+ static $_window = null;
+
+ if (null === $_window) {
+ $_window = ConsoleWindow::getInstance();
+ }
+
+ Event::notify(
+ 'hoa://Event/Console/Window:resize',
+ $_window,
+ new EventBucket([
+ 'size' => ConsoleWindow::getSize(),
+ ])
+ );
+ }
+ );
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/Event.php b/vendor/psy/psysh/src/Readline/Hoa/Event.php
new file mode 100644
index 000000000..bb08f328a
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/Event.php
@@ -0,0 +1,193 @@
+ new self(),
+ self::KEY_SOURCE => null,
+ ];
+ }
+
+ return self::$_register[$eventId][self::KEY_EVENT];
+ }
+
+ /**
+ * Declares a new object in the observable collection.
+ * Note: Hoa's libraries use `hoa://Event/anID` for their observable objects.
+ */
+ public static function register(string $eventId, /* Source|string */ $source)
+ {
+ if (true === self::eventExists($eventId)) {
+ throw new EventException('Cannot redeclare an event with the same ID, i.e. the event '.'ID %s already exists.', 0, $eventId);
+ }
+
+ if (\is_object($source) && !($source instanceof EventSource)) {
+ throw new EventException('The source must implement \Hoa\Event\Source '.'interface; given %s.', 1, \get_class($source));
+ } else {
+ $reflection = new \ReflectionClass($source);
+
+ if (false === $reflection->implementsInterface('\Psy\Readline\Hoa\EventSource')) {
+ throw new EventException('The source must implement \Hoa\Event\Source '.'interface; given %s.', 2, $source);
+ }
+ }
+
+ if (!isset(self::$_register[$eventId][self::KEY_EVENT])) {
+ self::$_register[$eventId][self::KEY_EVENT] = new self();
+ }
+
+ self::$_register[$eventId][self::KEY_SOURCE] = $source;
+ }
+
+ /**
+ * Undeclares an object in the observable collection.
+ *
+ * If `$hard` is set to `true, then the source and its attached callables
+ * will be deleted.
+ */
+ public static function unregister(string $eventId, bool $hard = false)
+ {
+ if (false !== $hard) {
+ unset(self::$_register[$eventId]);
+ } else {
+ self::$_register[$eventId][self::KEY_SOURCE] = null;
+ }
+ }
+
+ /**
+ * Attach an object to an event.
+ *
+ * It can be a callable or an accepted callable form (please, see the
+ * `Hoa\Consistency\Xcallable` class).
+ */
+ public function attach($callable): self
+ {
+ $callable = Xcallable::from($callable);
+ $this->_callable[$callable->getHash()] = $callable;
+
+ return $this;
+ }
+
+ /**
+ * Detaches an object to an event.
+ *
+ * Please see `self::attach` method.
+ */
+ public function detach($callable): self
+ {
+ unset($this->_callable[Xcallable::from($callable)->getHash()]);
+
+ return $this;
+ }
+
+ /**
+ * Checks if at least one callable is attached to an event.
+ */
+ public function isListened(): bool
+ {
+ return !empty($this->_callable);
+ }
+
+ /**
+ * Notifies, i.e. send data to observers.
+ */
+ public static function notify(string $eventId, EventSource $source, EventBucket $data)
+ {
+ if (false === self::eventExists($eventId)) {
+ throw new EventException('Event ID %s does not exist, cannot send notification.', 3, $eventId);
+ }
+
+ $data->setSource($source);
+ $event = self::getEvent($eventId);
+
+ foreach ($event->_callable as $callable) {
+ $callable($data);
+ }
+ }
+
+ /**
+ * Checks whether an event exists.
+ */
+ public static function eventExists(string $eventId): bool
+ {
+ return
+ \array_key_exists($eventId, self::$_register) &&
+ self::$_register[$eventId][self::KEY_SOURCE] !== null;
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/EventBucket.php b/vendor/psy/psysh/src/Readline/Hoa/EventBucket.php
new file mode 100644
index 000000000..37d3ca15a
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/EventBucket.php
@@ -0,0 +1,109 @@
+setData($data);
+
+ return;
+ }
+
+ /**
+ * Sends this object on the event channel.
+ */
+ public function send(string $eventId, EventSource $source)
+ {
+ return Event::notify($eventId, $source, $this);
+ }
+
+ /**
+ * Sets a new source.
+ */
+ public function setSource(EventSource $source)
+ {
+ $old = $this->_source;
+ $this->_source = $source;
+
+ return $old;
+ }
+
+ /**
+ * Returns the source.
+ */
+ public function getSource()
+ {
+ return $this->_source;
+ }
+
+ /**
+ * Sets new data.
+ */
+ public function setData($data)
+ {
+ $old = $this->_data;
+ $this->_data = $data;
+
+ return $old;
+ }
+
+ /**
+ * Returns the data.
+ */
+ public function getData()
+ {
+ return $this->_data;
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/EventException.php b/vendor/psy/psysh/src/Readline/Hoa/EventException.php
new file mode 100644
index 000000000..9517d9c96
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/EventException.php
@@ -0,0 +1,44 @@
+_source = $source;
+ $this->addIds($ids);
+
+ return;
+ }
+
+ /**
+ * Adds acceptable ID (or reset).
+ */
+ public function addIds(array $ids)
+ {
+ foreach ($ids as $id) {
+ $this->_callables[$id] = [];
+ }
+ }
+
+ /**
+ * Attaches a callable to a listenable component.
+ */
+ public function attach(string $listenerId, $callable): self
+ {
+ if (false === $this->listenerExists($listenerId)) {
+ throw new EventException('Cannot listen %s because it is not defined.', 0, $listenerId);
+ }
+
+ $callable = Xcallable::from($callable);
+ $this->_callables[$listenerId][$callable->getHash()] = $callable;
+
+ return $this;
+ }
+
+ /**
+ * Detaches a callable from a listenable component.
+ */
+ public function detach(string $listenerId, $callable): self
+ {
+ unset($this->_callables[$listenerId][Xcallable::from($callable)->getHash()]);
+
+ return $this;
+ }
+
+ /**
+ * Detaches all callables from a listenable component.
+ */
+ public function detachAll(string $listenerId): self
+ {
+ unset($this->_callables[$listenerId]);
+
+ return $this;
+ }
+
+ /**
+ * Checks if a listener exists.
+ */
+ public function listenerExists(string $listenerId): bool
+ {
+ return \array_key_exists($listenerId, $this->_callables);
+ }
+
+ /**
+ * Sends/fires a bucket to a listener.
+ */
+ public function fire(string $listenerId, EventBucket $data): array
+ {
+ if (false === $this->listenerExists($listenerId)) {
+ throw new EventException('Cannot fire on %s because it is not defined.', 1, $listenerId);
+ }
+
+ $data->setSource($this->_source);
+ $out = [];
+
+ foreach ($this->_callables[$listenerId] as $callable) {
+ $out[] = $callable($data);
+ }
+
+ return $out;
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/EventListens.php b/vendor/psy/psysh/src/Readline/Hoa/EventListens.php
new file mode 100644
index 000000000..41f1172b5
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/EventListens.php
@@ -0,0 +1,83 @@
+getListener();
+
+ if (null === $listener) {
+ throw new EventException('Cannot attach a callable to the listener %s because '.'it has not been initialized yet.', 0, static::class);
+ }
+
+ $listener->attach($listenerId, $callable);
+
+ return $this;
+ }
+
+ /**
+ * Sets a new listener.
+ */
+ protected function setListener(EventListener $listener)
+ {
+ $old = $this->_listener;
+ $this->_listener = $listener;
+
+ return $old;
+ }
+
+ /**
+ * Returns the listener.
+ */
+ protected function getListener()
+ {
+ return $this->_listener;
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/EventSource.php b/vendor/psy/psysh/src/Readline/Hoa/EventSource.php
new file mode 100644
index 000000000..3a495d4b6
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/EventSource.php
@@ -0,0 +1,44 @@
+send();
+
+ return;
+ }
+
+ /**
+ * Sends the exception on `hoa://Event/Exception`.
+ */
+ public function send()
+ {
+ Event::notify(
+ 'hoa://Event/Exception',
+ $this,
+ new EventBucket($this)
+ );
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/ExceptionIdle.php b/vendor/psy/psysh/src/Readline/Hoa/ExceptionIdle.php
new file mode 100644
index 000000000..1d44c4350
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/ExceptionIdle.php
@@ -0,0 +1,267 @@
+_tmpArguments = $arguments;
+ parent::__construct($message, $code, $previous);
+ $this->_rawMessage = $message;
+ $this->message = @\vsprintf($message, $this->getArguments());
+
+ return;
+ }
+
+ /**
+ * Returns the backtrace.
+ *
+ * Do not use `Exception::getTrace` any more.
+ */
+ public function getBacktrace()
+ {
+ if (null === $this->_trace) {
+ $this->_trace = $this->getTrace();
+ }
+
+ return $this->_trace;
+ }
+
+ /**
+ * Returns the previous exception if any.
+ *
+ * Do not use `Exception::getPrevious` any more.
+ */
+ public function getPreviousThrow()
+ {
+ if (null === $this->_previous) {
+ $this->_previous = $this->getPrevious();
+ }
+
+ return $this->_previous;
+ }
+
+ /**
+ * Returns the arguments of the message.
+ */
+ public function getArguments()
+ {
+ if (null === $this->_arguments) {
+ $arguments = $this->_tmpArguments;
+
+ if (!\is_array($arguments)) {
+ $arguments = [$arguments];
+ }
+
+ foreach ($arguments as &$value) {
+ if (null === $value) {
+ $value = '(null)';
+ }
+ }
+
+ $this->_arguments = $arguments;
+ unset($this->_tmpArguments);
+ }
+
+ return $this->_arguments;
+ }
+
+ /**
+ * Returns the raw message.
+ */
+ public function getRawMessage(): string
+ {
+ return $this->_rawMessage;
+ }
+
+ /**
+ * Returns the message already formatted.
+ */
+ public function getFormattedMessage(): string
+ {
+ return $this->getMessage();
+ }
+
+ /**
+ * Returns the source of the exception (class, method, function, main etc.).
+ */
+ public function getFrom(): string
+ {
+ $trace = $this->getBacktrace();
+ $from = '{main}';
+
+ if (!empty($trace)) {
+ $t = $trace[0];
+ $from = '';
+
+ if (isset($t['class'])) {
+ $from .= $t['class'].'::';
+ }
+
+ if (isset($t['function'])) {
+ $from .= $t['function'].'()';
+ }
+ }
+
+ return $from;
+ }
+
+ /**
+ * Raises an exception as a string.
+ */
+ public function raise(bool $includePrevious = false): string
+ {
+ $message = $this->getFormattedMessage();
+ $trace = $this->getBacktrace();
+ $file = '/dev/null';
+ $line = -1;
+ $pre = $this->getFrom();
+
+ if (!empty($trace)) {
+ $file = $trace['file'] ?? null;
+ $line = $trace['line'] ?? null;
+ }
+
+ $pre .= ': ';
+
+ try {
+ $out =
+ $pre.'('.$this->getCode().') '.$message."\n".
+ 'in '.$this->getFile().' at line '.
+ $this->getLine().'.';
+ } catch (\Exception $e) {
+ $out =
+ $pre.'('.$this->getCode().') '.$message."\n".
+ 'in '.$file.' around line '.$line.'.';
+ }
+
+ if (true === $includePrevious &&
+ null !== $previous = $this->getPreviousThrow()) {
+ $out .=
+ "\n\n".' ⬇'."\n\n".
+ 'Nested exception ('.\get_class($previous).'):'."\n".
+ ($previous instanceof self
+ ? $previous->raise(true)
+ : $previous->getMessage());
+ }
+
+ return $out;
+ }
+
+ /**
+ * Catches uncaught exception (only `Hoa\Exception\Idle` and children).
+ */
+ public static function uncaught(\Throwable $exception)
+ {
+ if (!($exception instanceof self)) {
+ throw $exception;
+ }
+
+ while (0 < \ob_get_level()) {
+ \ob_end_flush();
+ }
+
+ echo 'Uncaught exception ('.\get_class($exception).'):'."\n".
+ $exception->raise(true);
+ }
+
+ /**
+ * String representation of object.
+ */
+ public function __toString(): string
+ {
+ return $this->raise();
+ }
+
+ /**
+ * Enables uncaught exception handler.
+ *
+ * This is restricted to Hoa's exceptions only.
+ */
+ public static function enableUncaughtHandler(bool $enable = true)
+ {
+ if (false === $enable) {
+ return \restore_exception_handler();
+ }
+
+ return \set_exception_handler(function ($exception) {
+ return self::uncaught($exception);
+ });
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/File.php b/vendor/psy/psysh/src/Readline/Hoa/File.php
new file mode 100644
index 000000000..bdfd94789
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/File.php
@@ -0,0 +1,278 @@
+setMode($mode);
+
+ switch ($streamName) {
+ case '0':
+ $streamName = 'php://stdin';
+
+ break;
+
+ case '1':
+ $streamName = 'php://stdout';
+
+ break;
+
+ case '2':
+ $streamName = 'php://stderr';
+
+ break;
+
+ default:
+ if (true === \ctype_digit($streamName)) {
+ if (\PHP_VERSION_ID >= 50306) {
+ $streamName = 'php://fd/'.$streamName;
+ } else {
+ throw new FileException('You need PHP5.3.6 to use a file descriptor '.'other than 0, 1 or 2 (tried %d with PHP%s).', 0, [$streamName, \PHP_VERSION]);
+ }
+ }
+ }
+
+ parent::__construct($streamName, $context, $wait);
+
+ return;
+ }
+
+ /**
+ * Open the stream and return the associated resource.
+ */
+ protected function &_open(string $streamName, StreamContext $context = null)
+ {
+ if (\substr($streamName, 0, 4) === 'file' &&
+ false === \is_dir(\dirname($streamName))) {
+ throw new FileException('Directory %s does not exist. Could not open file %s.', 1, [\dirname($streamName), \basename($streamName)]);
+ }
+
+ if (null === $context) {
+ if (false === $out = @\fopen($streamName, $this->getMode(), true)) {
+ throw new FileException('Failed to open stream %s.', 2, $streamName);
+ }
+
+ return $out;
+ }
+
+ $out = @\fopen(
+ $streamName,
+ $this->getMode(),
+ true,
+ $context->getContext()
+ );
+
+ if (false === $out) {
+ throw new FileException('Failed to open stream %s.', 3, $streamName);
+ }
+
+ return $out;
+ }
+
+ /**
+ * Close the current stream.
+ */
+ protected function _close(): bool
+ {
+ return @\fclose($this->getStream());
+ }
+
+ /**
+ * Start a new buffer.
+ * The callable acts like a light filter.
+ */
+ public function newBuffer($callable = null, int $size = null): int
+ {
+ $this->setStreamBuffer($size);
+
+ // @TODO manage $callable as a filter?
+
+ return 1;
+ }
+
+ /**
+ * Flush the output to a stream.
+ */
+ public function flush(): bool
+ {
+ return \fflush($this->getStream());
+ }
+
+ /**
+ * Delete buffer.
+ */
+ public function deleteBuffer(): bool
+ {
+ return $this->disableStreamBuffer();
+ }
+
+ /**
+ * Get bufffer level.
+ */
+ public function getBufferLevel(): int
+ {
+ return 1;
+ }
+
+ /**
+ * Get buffer size.
+ */
+ public function getBufferSize(): int
+ {
+ return $this->getStreamBufferSize();
+ }
+
+ /**
+ * Portable advisory locking.
+ */
+ public function lock(int $operation): bool
+ {
+ return \flock($this->getStream(), $operation);
+ }
+
+ /**
+ * Rewind the position of a stream pointer.
+ */
+ public function rewind(): bool
+ {
+ return \rewind($this->getStream());
+ }
+
+ /**
+ * Seek on a stream pointer.
+ */
+ public function seek(int $offset, int $whence = StreamPointable::SEEK_SET): int
+ {
+ return \fseek($this->getStream(), $offset, $whence);
+ }
+
+ /**
+ * Get the current position of the stream pointer.
+ */
+ public function tell(): int
+ {
+ $stream = $this->getStream();
+
+ if (null === $stream) {
+ return 0;
+ }
+
+ return \ftell($stream);
+ }
+
+ /**
+ * Create a file.
+ */
+ public static function create(string $name)
+ {
+ if (\file_exists($name)) {
+ return true;
+ }
+
+ return \touch($name);
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/FileDirectory.php b/vendor/psy/psysh/src/Readline/Hoa/FileDirectory.php
new file mode 100644
index 000000000..e7191410e
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/FileDirectory.php
@@ -0,0 +1,221 @@
+setMode($mode);
+ parent::__construct($streamName, $context, $wait);
+
+ return;
+ }
+
+ /**
+ * Open the stream and return the associated resource.
+ */
+ protected function &_open(string $streamName, StreamContext $context = null)
+ {
+ if (false === \is_dir($streamName)) {
+ if ($this->getMode() === self::MODE_READ) {
+ throw new FileDoesNotExistException('Directory %s does not exist.', 0, $streamName);
+ } else {
+ self::create(
+ $streamName,
+ $this->getMode(),
+ null !== $context
+ ? $context->getContext()
+ : null
+ );
+ }
+ }
+
+ $out = null;
+
+ return $out;
+ }
+
+ /**
+ * Close the current stream.
+ */
+ protected function _close(): bool
+ {
+ return true;
+ }
+
+ /**
+ * Recursive copy of a directory.
+ */
+ public function copy(string $to, bool $force = StreamTouchable::DO_NOT_OVERWRITE): bool
+ {
+ if (empty($to)) {
+ throw new FileException('The destination path (to copy) is empty.', 1);
+ }
+
+ $from = $this->getStreamName();
+ $fromLength = \strlen($from) + 1;
+ $finder = new FileFinder();
+ $finder->in($from);
+
+ self::create($to, self::MODE_CREATE_RECURSIVE);
+
+ foreach ($finder as $file) {
+ $relative = \substr($file->getPathname(), $fromLength);
+ $_to = $to.\DIRECTORY_SEPARATOR.$relative;
+
+ if (true === $file->isDir()) {
+ self::create($_to, self::MODE_CREATE);
+
+ continue;
+ }
+
+ // This is not possible to do `$file->open()->copy();
+ // $file->close();` because the file will be opened in read and
+ // write mode. In a PHAR for instance, this operation is
+ // forbidden. So a special care must be taken to open file in read
+ // only mode.
+ $handle = null;
+
+ if (true === $file->isFile()) {
+ $handle = new FileRead($file->getPathname());
+ } elseif (true === $file->isDir()) {
+ $handle = new self($file->getPathName());
+ } elseif (true === $file->isLink()) {
+ $handle = new FileLinkRead($file->getPathName());
+ }
+
+ if (null !== $handle) {
+ $handle->copy($_to, $force);
+ $handle->close();
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Delete a directory.
+ */
+ public function delete(): bool
+ {
+ $from = $this->getStreamName();
+ $finder = new FileFinder();
+ $finder->in($from)
+ ->childFirst();
+
+ foreach ($finder as $file) {
+ $file->open()->delete();
+ $file->close();
+ }
+
+ if (null === $this->getStreamContext()) {
+ return @\rmdir($from);
+ }
+
+ return @\rmdir($from, $this->getStreamContext()->getContext());
+ }
+
+ /**
+ * Create a directory.
+ */
+ public static function create(
+ string $name,
+ string $mode = self::MODE_CREATE_RECURSIVE,
+ string $context = null
+ ): bool {
+ if (true === \is_dir($name)) {
+ return true;
+ }
+
+ if (empty($name)) {
+ return false;
+ }
+
+ if (null !== $context) {
+ if (false === StreamContext::contextExists($context)) {
+ throw new FileException('Context %s was not previously declared, cannot retrieve '.'this context.', 2, $context);
+ } else {
+ $context = StreamContext::getInstance($context);
+ }
+ }
+
+ if (null === $context) {
+ return @\mkdir(
+ $name,
+ 0755,
+ self::MODE_CREATE_RECURSIVE === $mode
+ );
+ }
+
+ return @\mkdir(
+ $name,
+ 0755,
+ self::MODE_CREATE_RECURSIVE === $mode,
+ $context->getContext()
+ );
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/FileDoesNotExistException.php b/vendor/psy/psysh/src/Readline/Hoa/FileDoesNotExistException.php
new file mode 100644
index 000000000..81599a5de
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/FileDoesNotExistException.php
@@ -0,0 +1,48 @@
+_flags = IteratorFileSystem::KEY_AS_PATHNAME
+ | IteratorFileSystem::CURRENT_AS_FILEINFO
+ | IteratorFileSystem::SKIP_DOTS;
+ $this->_first = \RecursiveIteratorIterator::SELF_FIRST;
+
+ return;
+ }
+
+ /**
+ * Select a directory to scan.
+ */
+ public function in($paths): self
+ {
+ if (!\is_array($paths)) {
+ $paths = [$paths];
+ }
+
+ foreach ($paths as $path) {
+ if (1 === \preg_match('/[\*\?\[\]]/', $path)) {
+ $iterator = new \CallbackFilterIterator(
+ new \GlobIterator(\rtrim($path, \DIRECTORY_SEPARATOR)),
+ function ($current) {
+ return $current->isDir();
+ }
+ );
+
+ foreach ($iterator as $fileInfo) {
+ $this->_paths[] = $fileInfo->getPathname();
+ }
+ } else {
+ $this->_paths[] = $path;
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Set max depth for recursion.
+ */
+ public function maxDepth(int $depth): self
+ {
+ $this->_maxDepth = $depth;
+
+ return $this;
+ }
+
+ /**
+ * Include files in the result.
+ */
+ public function files(): self
+ {
+ $this->_types[] = 'file';
+
+ return $this;
+ }
+
+ /**
+ * Include directories in the result.
+ */
+ public function directories(): self
+ {
+ $this->_types[] = 'dir';
+
+ return $this;
+ }
+
+ /**
+ * Include links in the result.
+ */
+ public function links(): self
+ {
+ $this->_types[] = 'link';
+
+ return $this;
+ }
+
+ /**
+ * Follow symbolink links.
+ */
+ public function followSymlinks(bool $flag = true): self
+ {
+ if (true === $flag) {
+ $this->_flags ^= IteratorFileSystem::FOLLOW_SYMLINKS;
+ } else {
+ $this->_flags |= IteratorFileSystem::FOLLOW_SYMLINKS;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Include files that match a regex.
+ * Example:
+ * $this->name('#\.php$#');.
+ */
+ public function name(string $regex): self
+ {
+ $this->_filters[] = function (\SplFileInfo $current) use ($regex) {
+ return 0 !== \preg_match($regex, $current->getBasename());
+ };
+
+ return $this;
+ }
+
+ /**
+ * Exclude directories that match a regex.
+ * Example:
+ * $this->notIn('#^\.(git|hg)$#');.
+ */
+ public function notIn(string $regex): self
+ {
+ $this->_filters[] = function (\SplFileInfo $current) use ($regex) {
+ foreach (\explode(\DIRECTORY_SEPARATOR, $current->getPathname()) as $part) {
+ if (0 !== \preg_match($regex, $part)) {
+ return false;
+ }
+ }
+
+ return true;
+ };
+
+ return $this;
+ }
+
+ /**
+ * Include files that respect a certain size.
+ * The size is a string of the form:
+ * operator number unit
+ * where
+ * • operator could be: <, <=, >, >= or =;
+ * • number is a positive integer;
+ * • unit could be: b (default), Kb, Mb, Gb, Tb, Pb, Eb, Zb, Yb.
+ * Example:
+ * $this->size('>= 12Kb');.
+ */
+ public function size(string $size): self
+ {
+ if (0 === \preg_match('#^(<|<=|>|>=|=)\s*(\d+)\s*((?:[KMGTPEZY])b)?$#', $size, $matches)) {
+ return $this;
+ }
+
+ $number = (float) ($matches[2]);
+ $unit = $matches[3] ?? 'b';
+ $operator = $matches[1];
+
+ switch ($unit) {
+ case 'b':
+ break;
+
+ // kilo
+ case 'Kb':
+ $number <<= 10;
+
+ break;
+
+ // mega.
+ case 'Mb':
+ $number <<= 20;
+
+ break;
+
+ // giga.
+ case 'Gb':
+ $number <<= 30;
+
+ break;
+
+ // tera.
+ case 'Tb':
+ $number *= 1099511627776;
+
+ break;
+
+ // peta.
+ case 'Pb':
+ $number *= 1024 ** 5;
+
+ break;
+
+ // exa.
+ case 'Eb':
+ $number *= 1024 ** 6;
+
+ break;
+
+ // zetta.
+ case 'Zb':
+ $number *= 1024 ** 7;
+
+ break;
+
+ // yota.
+ case 'Yb':
+ $number *= 1024 ** 8;
+
+ break;
+ }
+
+ $filter = null;
+
+ switch ($operator) {
+ case '<':
+ $filter = function (\SplFileInfo $current) use ($number) {
+ return $current->getSize() < $number;
+ };
+
+ break;
+
+ case '<=':
+ $filter = function (\SplFileInfo $current) use ($number) {
+ return $current->getSize() <= $number;
+ };
+
+ break;
+
+ case '>':
+ $filter = function (\SplFileInfo $current) use ($number) {
+ return $current->getSize() > $number;
+ };
+
+ break;
+
+ case '>=':
+ $filter = function (\SplFileInfo $current) use ($number) {
+ return $current->getSize() >= $number;
+ };
+
+ break;
+
+ case '=':
+ $filter = function (\SplFileInfo $current) use ($number) {
+ return $current->getSize() === $number;
+ };
+
+ break;
+ }
+
+ $this->_filters[] = $filter;
+
+ return $this;
+ }
+
+ /**
+ * Whether we should include dots or not (respectively . and ..).
+ */
+ public function dots(bool $flag = true): self
+ {
+ if (true === $flag) {
+ $this->_flags ^= IteratorFileSystem::SKIP_DOTS;
+ } else {
+ $this->_flags |= IteratorFileSystem::SKIP_DOTS;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Include files that are owned by a certain owner.
+ */
+ public function owner(int $owner): self
+ {
+ $this->_filters[] = function (\SplFileInfo $current) use ($owner) {
+ return $current->getOwner() === $owner;
+ };
+
+ return $this;
+ }
+
+ /**
+ * Format date.
+ * Date can have the following syntax:
+ * date
+ * since date
+ * until date
+ * If the date does not have the “ago” keyword, it will be added.
+ * Example: “42 hours” is equivalent to “since 42 hours” which is equivalent
+ * to “since 42 hours ago”.
+ */
+ protected function formatDate(string $date, &$operator): int
+ {
+ $operator = -1;
+
+ if (0 === \preg_match('#\bago\b#', $date)) {
+ $date .= ' ago';
+ }
+
+ if (0 !== \preg_match('#^(since|until)\b(.+)$#', $date, $matches)) {
+ $time = \strtotime($matches[2]);
+
+ if ('until' === $matches[1]) {
+ $operator = 1;
+ }
+ } else {
+ $time = \strtotime($date);
+ }
+
+ return $time;
+ }
+
+ /**
+ * Include files that have been changed from a certain date.
+ * Example:
+ * $this->changed('since 13 days');.
+ */
+ public function changed(string $date): self
+ {
+ $time = $this->formatDate($date, $operator);
+
+ if (-1 === $operator) {
+ $this->_filters[] = function (\SplFileInfo $current) use ($time) {
+ return $current->getCTime() >= $time;
+ };
+ } else {
+ $this->_filters[] = function (\SplFileInfo $current) use ($time) {
+ return $current->getCTime() < $time;
+ };
+ }
+
+ return $this;
+ }
+
+ /**
+ * Include files that have been modified from a certain date.
+ * Example:
+ * $this->modified('since 13 days');.
+ */
+ public function modified(string $date): self
+ {
+ $time = $this->formatDate($date, $operator);
+
+ if (-1 === $operator) {
+ $this->_filters[] = function (\SplFileInfo $current) use ($time) {
+ return $current->getMTime() >= $time;
+ };
+ } else {
+ $this->_filters[] = function (\SplFileInfo $current) use ($time) {
+ return $current->getMTime() < $time;
+ };
+ }
+
+ return $this;
+ }
+
+ /**
+ * Add your own filter.
+ * The callback will receive 3 arguments: $current, $key and $iterator. It
+ * must return a boolean: true to include the file, false to exclude it.
+ * Example:
+ * // Include files that are readable
+ * $this->filter(function ($current) {
+ * return $current->isReadable();
+ * });.
+ */
+ public function filter($callback): self
+ {
+ $this->_filters[] = $callback;
+
+ return $this;
+ }
+
+ /**
+ * Sort result by name.
+ * If \Collator exists (from ext/intl), the $locale argument will be used
+ * for its constructor. Else, strcmp() will be used.
+ * Example:
+ * $this->sortByName('fr_FR');.
+ */
+ public function sortByName(string $locale = 'root'): self
+ {
+ if (true === \class_exists('Collator', false)) {
+ $collator = new \Collator($locale);
+
+ $this->_sorts[] = function (\SplFileInfo $a, \SplFileInfo $b) use ($collator) {
+ return $collator->compare($a->getPathname(), $b->getPathname());
+ };
+ } else {
+ $this->_sorts[] = function (\SplFileInfo $a, \SplFileInfo $b) {
+ return \strcmp($a->getPathname(), $b->getPathname());
+ };
+ }
+
+ return $this;
+ }
+
+ /**
+ * Sort result by size.
+ * Example:
+ * $this->sortBySize();.
+ */
+ public function sortBySize(): self
+ {
+ $this->_sorts[] = function (\SplFileInfo $a, \SplFileInfo $b) {
+ return $a->getSize() < $b->getSize();
+ };
+
+ return $this;
+ }
+
+ /**
+ * Add your own sort.
+ * The callback will receive 2 arguments: $a and $b. Please see the uasort()
+ * function.
+ * Example:
+ * // Sort files by their modified time.
+ * $this->sort(function ($a, $b) {
+ * return $a->getMTime() < $b->getMTime();
+ * });.
+ */
+ public function sort($callable): self
+ {
+ $this->_sorts[] = $callable;
+
+ return $this;
+ }
+
+ /**
+ * Child comes first when iterating.
+ */
+ public function childFirst(): self
+ {
+ $this->_first = \RecursiveIteratorIterator::CHILD_FIRST;
+
+ return $this;
+ }
+
+ /**
+ * Get the iterator.
+ */
+ public function getIterator()
+ {
+ $_iterator = new \AppendIterator();
+ $types = $this->getTypes();
+
+ if (!empty($types)) {
+ $this->_filters[] = function (\SplFileInfo $current) use ($types) {
+ return \in_array($current->getType(), $types);
+ };
+ }
+
+ $maxDepth = $this->getMaxDepth();
+ $splFileInfo = $this->getSplFileInfo();
+
+ foreach ($this->getPaths() as $path) {
+ if (1 === $maxDepth) {
+ $iterator = new \IteratorIterator(
+ new IteratorRecursiveDirectory(
+ $path,
+ $this->getFlags(),
+ $splFileInfo
+ ),
+ $this->getFirst()
+ );
+ } else {
+ $iterator = new \RecursiveIteratorIterator(
+ new IteratorRecursiveDirectory(
+ $path,
+ $this->getFlags(),
+ $splFileInfo
+ ),
+ $this->getFirst()
+ );
+
+ if (1 < $maxDepth) {
+ $iterator->setMaxDepth($maxDepth - 1);
+ }
+ }
+
+ $_iterator->append($iterator);
+ }
+
+ foreach ($this->getFilters() as $filter) {
+ $_iterator = new \CallbackFilterIterator(
+ $_iterator,
+ $filter
+ );
+ }
+
+ $sorts = $this->getSorts();
+
+ if (empty($sorts)) {
+ return $_iterator;
+ }
+
+ $array = \iterator_to_array($_iterator);
+
+ foreach ($sorts as $sort) {
+ \uasort($array, $sort);
+ }
+
+ return new \ArrayIterator($array);
+ }
+
+ /**
+ * Set SplFileInfo classname.
+ */
+ public function setSplFileInfo(string $splFileInfo): string
+ {
+ $old = $this->_splFileInfo;
+ $this->_splFileInfo = $splFileInfo;
+
+ return $old;
+ }
+
+ /**
+ * Get SplFileInfo classname.
+ */
+ public function getSplFileInfo(): string
+ {
+ return $this->_splFileInfo;
+ }
+
+ /**
+ * Get all paths.
+ */
+ protected function getPaths(): array
+ {
+ return $this->_paths;
+ }
+
+ /**
+ * Get max depth.
+ */
+ public function getMaxDepth(): int
+ {
+ return $this->_maxDepth;
+ }
+
+ /**
+ * Get types.
+ */
+ public function getTypes(): array
+ {
+ return $this->_types;
+ }
+
+ /**
+ * Get filters.
+ */
+ protected function getFilters(): array
+ {
+ return $this->_filters;
+ }
+
+ /**
+ * Get sorts.
+ */
+ protected function getSorts(): array
+ {
+ return $this->_sorts;
+ }
+
+ /**
+ * Get flags.
+ */
+ public function getFlags(): int
+ {
+ return $this->_flags;
+ }
+
+ /**
+ * Get first.
+ */
+ public function getFirst(): int
+ {
+ return $this->_first;
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/FileGeneric.php b/vendor/psy/psysh/src/Readline/Hoa/FileGeneric.php
new file mode 100644
index 000000000..aa3b70cf7
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/FileGeneric.php
@@ -0,0 +1,487 @@
+getStreamName());
+ }
+
+ /**
+ * Get directory name component of path.
+ */
+ public function getDirname(): string
+ {
+ return \dirname($this->getStreamName());
+ }
+
+ /**
+ * Get size.
+ */
+ public function getSize(): int
+ {
+ if (false === $this->getStatistic()) {
+ return false;
+ }
+
+ return \filesize($this->getStreamName());
+ }
+
+ /**
+ * Get informations about a file.
+ */
+ public function getStatistic(): array
+ {
+ return \fstat($this->getStream());
+ }
+
+ /**
+ * Get last access time of file.
+ */
+ public function getATime(): int
+ {
+ return \fileatime($this->getStreamName());
+ }
+
+ /**
+ * Get inode change time of file.
+ */
+ public function getCTime(): int
+ {
+ return \filectime($this->getStreamName());
+ }
+
+ /**
+ * Get file modification time.
+ */
+ public function getMTime(): int
+ {
+ return \filemtime($this->getStreamName());
+ }
+
+ /**
+ * Get file group.
+ */
+ public function getGroup(): int
+ {
+ return \filegroup($this->getStreamName());
+ }
+
+ /**
+ * Get file owner.
+ */
+ public function getOwner(): int
+ {
+ return \fileowner($this->getStreamName());
+ }
+
+ /**
+ * Get file permissions.
+ */
+ public function getPermissions(): int
+ {
+ return \fileperms($this->getStreamName());
+ }
+
+ /**
+ * Get file permissions as a string.
+ * Result sould be interpreted like this:
+ * * s: socket;
+ * * l: symbolic link;
+ * * -: regular;
+ * * b: block special;
+ * * d: directory;
+ * * c: character special;
+ * * p: FIFO pipe;
+ * * u: unknown.
+ */
+ public function getReadablePermissions(): string
+ {
+ $p = $this->getPermissions();
+
+ if (($p & 0xC000) === 0xC000) {
+ $out = 's';
+ } elseif (($p & 0xA000) === 0xA000) {
+ $out = 'l';
+ } elseif (($p & 0x8000) === 0x8000) {
+ $out = '-';
+ } elseif (($p & 0x6000) === 0x6000) {
+ $out = 'b';
+ } elseif (($p & 0x4000) === 0x4000) {
+ $out = 'd';
+ } elseif (($p & 0x2000) === 0x2000) {
+ $out = 'c';
+ } elseif (($p & 0x1000) === 0x1000) {
+ $out = 'p';
+ } else {
+ $out = 'u';
+ }
+
+ $out .=
+ (($p & 0x0100) ? 'r' : '-').
+ (($p & 0x0080) ? 'w' : '-').
+ (($p & 0x0040) ?
+ (($p & 0x0800) ? 's' : 'x') :
+ (($p & 0x0800) ? 'S' : '-')).
+ (($p & 0x0020) ? 'r' : '-').
+ (($p & 0x0010) ? 'w' : '-').
+ (($p & 0x0008) ?
+ (($p & 0x0400) ? 's' : 'x') :
+ (($p & 0x0400) ? 'S' : '-')).
+ (($p & 0x0004) ? 'r' : '-').
+ (($p & 0x0002) ? 'w' : '-').
+ (($p & 0x0001) ?
+ (($p & 0x0200) ? 't' : 'x') :
+ (($p & 0x0200) ? 'T' : '-'));
+
+ return $out;
+ }
+
+ /**
+ * Check if the file is readable.
+ */
+ public function isReadable(): bool
+ {
+ return \is_readable($this->getStreamName());
+ }
+
+ /**
+ * Check if the file is writable.
+ */
+ public function isWritable(): bool
+ {
+ return \is_writable($this->getStreamName());
+ }
+
+ /**
+ * Check if the file is executable.
+ */
+ public function isExecutable(): bool
+ {
+ return \is_executable($this->getStreamName());
+ }
+
+ /**
+ * Clear file status cache.
+ */
+ public function clearStatisticCache()
+ {
+ \clearstatcache(true, $this->getStreamName());
+ }
+
+ /**
+ * Clear all files status cache.
+ */
+ public static function clearAllStatisticCaches()
+ {
+ \clearstatcache();
+ }
+
+ /**
+ * Set access and modification time of file.
+ */
+ public function touch(int $time = null, int $atime = null): bool
+ {
+ if (null === $time) {
+ $time = \time();
+ }
+
+ if (null === $atime) {
+ $atime = $time;
+ }
+
+ return \touch($this->getStreamName(), $time, $atime);
+ }
+
+ /**
+ * Copy file.
+ * Return the destination file path if succeed, false otherwise.
+ */
+ public function copy(string $to, bool $force = StreamTouchable::DO_NOT_OVERWRITE): bool
+ {
+ $from = $this->getStreamName();
+
+ if ($force === StreamTouchable::DO_NOT_OVERWRITE &&
+ true === \file_exists($to)) {
+ return true;
+ }
+
+ if (null === $this->getStreamContext()) {
+ return @\copy($from, $to);
+ }
+
+ return @\copy($from, $to, $this->getStreamContext()->getContext());
+ }
+
+ /**
+ * Move a file.
+ */
+ public function move(
+ string $name,
+ bool $force = StreamTouchable::DO_NOT_OVERWRITE,
+ bool $mkdir = StreamTouchable::DO_NOT_MAKE_DIRECTORY
+ ): bool {
+ $from = $this->getStreamName();
+
+ if ($force === StreamTouchable::DO_NOT_OVERWRITE &&
+ true === \file_exists($name)) {
+ return false;
+ }
+
+ if (StreamTouchable::MAKE_DIRECTORY === $mkdir) {
+ FileDirectory::create(
+ \dirname($name),
+ FileDirectory::MODE_CREATE_RECURSIVE
+ );
+ }
+
+ if (null === $this->getStreamContext()) {
+ return @\rename($from, $name);
+ }
+
+ return @\rename($from, $name, $this->getStreamContext()->getContext());
+ }
+
+ /**
+ * Delete a file.
+ */
+ public function delete(): bool
+ {
+ if (null === $this->getStreamContext()) {
+ return @\unlink($this->getStreamName());
+ }
+
+ return @\unlink(
+ $this->getStreamName(),
+ $this->getStreamContext()->getContext()
+ );
+ }
+
+ /**
+ * Change file group.
+ */
+ public function changeGroup($group): bool
+ {
+ return \chgrp($this->getStreamName(), $group);
+ }
+
+ /**
+ * Change file mode.
+ */
+ public function changeMode(int $mode): bool
+ {
+ return \chmod($this->getStreamName(), $mode);
+ }
+
+ /**
+ * Change file owner.
+ */
+ public function changeOwner($user): bool
+ {
+ return \chown($this->getStreamName(), $user);
+ }
+
+ /**
+ * Change the current umask.
+ */
+ public static function umask(int $umask = null): int
+ {
+ if (null === $umask) {
+ return \umask();
+ }
+
+ return \umask($umask);
+ }
+
+ /**
+ * Check if it is a file.
+ */
+ public function isFile(): bool
+ {
+ return \is_file($this->getStreamName());
+ }
+
+ /**
+ * Check if it is a link.
+ */
+ public function isLink(): bool
+ {
+ return \is_link($this->getStreamName());
+ }
+
+ /**
+ * Check if it is a directory.
+ */
+ public function isDirectory(): bool
+ {
+ return \is_dir($this->getStreamName());
+ }
+
+ /**
+ * Check if it is a socket.
+ */
+ public function isSocket(): bool
+ {
+ return \filetype($this->getStreamName()) === 'socket';
+ }
+
+ /**
+ * Check if it is a FIFO pipe.
+ */
+ public function isFIFOPipe(): bool
+ {
+ return \filetype($this->getStreamName()) === 'fifo';
+ }
+
+ /**
+ * Check if it is character special file.
+ */
+ public function isCharacterSpecial(): bool
+ {
+ return \filetype($this->getStreamName()) === 'char';
+ }
+
+ /**
+ * Check if it is block special.
+ */
+ public function isBlockSpecial(): bool
+ {
+ return \filetype($this->getStreamName()) === 'block';
+ }
+
+ /**
+ * Check if it is an unknown type.
+ */
+ public function isUnknown(): bool
+ {
+ return \filetype($this->getStreamName()) === 'unknown';
+ }
+
+ /**
+ * Set the open mode.
+ */
+ protected function setMode(string $mode)
+ {
+ $old = $this->_mode;
+ $this->_mode = $mode;
+
+ return $old;
+ }
+
+ /**
+ * Get the open mode.
+ */
+ public function getMode()
+ {
+ return $this->_mode;
+ }
+
+ /**
+ * Get inode.
+ */
+ public function getINode(): int
+ {
+ return \fileinode($this->getStreamName());
+ }
+
+ /**
+ * Check if the system is case sensitive or not.
+ */
+ public static function isCaseSensitive(): bool
+ {
+ return !(
+ \file_exists(\mb_strtolower(__FILE__)) &&
+ \file_exists(\mb_strtoupper(__FILE__))
+ );
+ }
+
+ /**
+ * Get a canonicalized absolute pathname.
+ */
+ public function getRealPath(): string
+ {
+ if (false === $out = \realpath($this->getStreamName())) {
+ return $this->getStreamName();
+ }
+
+ return $out;
+ }
+
+ /**
+ * Get file extension (if exists).
+ */
+ public function getExtension(): string
+ {
+ return \pathinfo(
+ $this->getStreamName(),
+ \PATHINFO_EXTENSION
+ );
+ }
+
+ /**
+ * Get filename without extension.
+ */
+ public function getFilename(): string
+ {
+ $file = \basename($this->getStreamName());
+
+ if (\defined('PATHINFO_FILENAME')) {
+ return \pathinfo($file, \PATHINFO_FILENAME);
+ }
+
+ if (\strstr($file, '.')) {
+ return \substr($file, 0, \strrpos($file, '.'));
+ }
+
+ return $file;
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/FileLink.php b/vendor/psy/psysh/src/Readline/Hoa/FileLink.php
new file mode 100644
index 000000000..21a4485f9
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/FileLink.php
@@ -0,0 +1,149 @@
+getStreamName());
+ }
+
+ /**
+ * Change file group.
+ */
+ public function changeGroup($group): bool
+ {
+ return \lchgrp($this->getStreamName(), $group);
+ }
+
+ /**
+ * Change file owner.
+ */
+ public function changeOwner($user): bool
+ {
+ return \lchown($this->getStreamName(), $user);
+ }
+
+ /**
+ * Get file permissions.
+ */
+ public function getPermissions(): int
+ {
+ return 41453; // i.e. lrwxr-xr-x
+ }
+
+ /**
+ * Get the target of a symbolic link.
+ */
+ public function getTarget(): FileGeneric
+ {
+ $target = \dirname($this->getStreamName()).\DIRECTORY_SEPARATOR.
+ $this->getTargetName();
+ $context = null !== $this->getStreamContext()
+ ? $this->getStreamContext()->getCurrentId()
+ : null;
+
+ if (true === \is_link($target)) {
+ return new FileLinkReadWrite(
+ $target,
+ File::MODE_APPEND_READ_WRITE,
+ $context
+ );
+ } elseif (true === \is_file($target)) {
+ return new FileReadWrite(
+ $target,
+ File::MODE_APPEND_READ_WRITE,
+ $context
+ );
+ } elseif (true === \is_dir($target)) {
+ return new FileDirectory(
+ $target,
+ File::MODE_READ,
+ $context
+ );
+ }
+
+ throw new FileException('Cannot find an appropriated object that matches with '.'path %s when defining it.', 1, $target);
+ }
+
+ /**
+ * Get the target name of a symbolic link.
+ */
+ public function getTargetName(): string
+ {
+ return \readlink($this->getStreamName());
+ }
+
+ /**
+ * Create a link.
+ */
+ public static function create(string $name, string $target): bool
+ {
+ if (false !== \linkinfo($name)) {
+ return true;
+ }
+
+ return \symlink($target, $name);
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/FileLinkRead.php b/vendor/psy/psysh/src/Readline/Hoa/FileLinkRead.php
new file mode 100644
index 000000000..37bb514cb
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/FileLinkRead.php
@@ -0,0 +1,231 @@
+getMode(), $createModes)) {
+ throw new FileException('Open mode are not supported; given %d. Only %s are supported.', 0, [$this->getMode(), \implode(', ', $createModes)]);
+ }
+
+ \preg_match('#^(\w+)://#', $streamName, $match);
+
+ if (((isset($match[1]) && $match[1] === 'file') || !isset($match[1])) &&
+ !\file_exists($streamName)) {
+ throw new FileDoesNotExistException('File %s does not exist.', 1, $streamName);
+ }
+
+ $out = parent::_open($streamName, $context);
+
+ return $out;
+ }
+
+ /**
+ * Test for end-of-file.
+ *
+ * @return bool
+ */
+ public function eof(): bool
+ {
+ return \feof($this->getStream());
+ }
+
+ /**
+ * Read n characters.
+ *
+ * @param int $length length
+ *
+ * @return string
+ *
+ * @throws \Hoa\File\Exception
+ */
+ public function read(int $length)
+ {
+ if (0 > $length) {
+ throw new FileException('Length must be greater than 0, given %d.', 2, $length);
+ }
+
+ return \fread($this->getStream(), $length);
+ }
+
+ /**
+ * Alias of $this->read().
+ *
+ * @param int $length length
+ *
+ * @return string
+ */
+ public function readString(int $length)
+ {
+ return $this->read($length);
+ }
+
+ /**
+ * Read a character.
+ *
+ * @return string
+ */
+ public function readCharacter()
+ {
+ return \fgetc($this->getStream());
+ }
+
+ /**
+ * Read a boolean.
+ *
+ * @return bool
+ */
+ public function readBoolean()
+ {
+ return (bool) $this->read(1);
+ }
+
+ /**
+ * Read an integer.
+ *
+ * @param int $length length
+ *
+ * @return int
+ */
+ public function readInteger(int $length = 1)
+ {
+ return (int) $this->read($length);
+ }
+
+ /**
+ * Read a float.
+ *
+ * @param int $length length
+ *
+ * @return float
+ */
+ public function readFloat(int $length = 1)
+ {
+ return (float) $this->read($length);
+ }
+
+ /**
+ * Read an array.
+ * Alias of the $this->scanf() method.
+ *
+ * @param string $format format (see printf's formats)
+ *
+ * @return array
+ */
+ public function readArray(string $format = null)
+ {
+ return $this->scanf($format);
+ }
+
+ /**
+ * Read a line.
+ *
+ * @return string
+ */
+ public function readLine()
+ {
+ return \fgets($this->getStream());
+ }
+
+ /**
+ * Read all, i.e. read as much as possible.
+ *
+ * @param int $offset offset
+ *
+ * @return string
+ */
+ public function readAll(int $offset = 0)
+ {
+ return \stream_get_contents($this->getStream(), -1, $offset);
+ }
+
+ /**
+ * Parse input from a stream according to a format.
+ *
+ * @param string $format format (see printf's formats)
+ *
+ * @return array
+ */
+ public function scanf(string $format): array
+ {
+ return \fscanf($this->getStream(), $format);
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/FileLinkReadWrite.php b/vendor/psy/psysh/src/Readline/Hoa/FileLinkReadWrite.php
new file mode 100644
index 000000000..0d16585cf
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/FileLinkReadWrite.php
@@ -0,0 +1,279 @@
+getMode(), $createModes)) {
+ throw new FileException('Open mode are not supported; given %d. Only %s are supported.', 0, [$this->getMode(), \implode(', ', $createModes)]);
+ }
+
+ \preg_match('#^(\w+)://#', $streamName, $match);
+
+ if (((isset($match[1]) && $match[1] === 'file') || !isset($match[1])) &&
+ !\file_exists($streamName) &&
+ parent::MODE_READ_WRITE === $this->getMode()) {
+ throw new FileDoesNotExistException('File %s does not exist.', 1, $streamName);
+ }
+
+ $out = parent::_open($streamName, $context);
+
+ return $out;
+ }
+
+ /**
+ * Test for end-of-file.
+ */
+ public function eof(): bool
+ {
+ return \feof($this->getStream());
+ }
+
+ /**
+ * Read n characters.
+ */
+ public function read(int $length)
+ {
+ if (0 > $length) {
+ throw new FileException('Length must be greater than 0, given %d.', 2, $length);
+ }
+
+ return \fread($this->getStream(), $length);
+ }
+
+ /**
+ * Alias of $this->read().
+ */
+ public function readString(int $length)
+ {
+ return $this->read($length);
+ }
+
+ /**
+ * Read a character.
+ */
+ public function readCharacter()
+ {
+ return \fgetc($this->getStream());
+ }
+
+ /**
+ * Read a boolean.
+ */
+ public function readBoolean()
+ {
+ return (bool) $this->read(1);
+ }
+
+ /**
+ * Read an integer.
+ */
+ public function readInteger(int $length = 1)
+ {
+ return (int) $this->read($length);
+ }
+
+ /**
+ * Read a float.
+ */
+ public function readFloat(int $length = 1)
+ {
+ return (float) $this->read($length);
+ }
+
+ /**
+ * Read an array.
+ * Alias of the $this->scanf() method.
+ */
+ public function readArray(string $format = null)
+ {
+ return $this->scanf($format);
+ }
+
+ /**
+ * Read a line.
+ */
+ public function readLine()
+ {
+ return \fgets($this->getStream());
+ }
+
+ /**
+ * Read all, i.e. read as much as possible.
+ */
+ public function readAll(int $offset = 0)
+ {
+ return \stream_get_contents($this->getStream(), -1, $offset);
+ }
+
+ /**
+ * Parse input from a stream according to a format.
+ */
+ public function scanf(string $format): array
+ {
+ return \fscanf($this->getStream(), $format);
+ }
+
+ /**
+ * Write n characters.
+ */
+ public function write(string $string, int $length)
+ {
+ if (0 > $length) {
+ throw new FileException('Length must be greater than 0, given %d.', 3, $length);
+ }
+
+ return \fwrite($this->getStream(), $string, $length);
+ }
+
+ /**
+ * Write a string.
+ */
+ public function writeString(string $string)
+ {
+ $string = (string) $string;
+
+ return $this->write($string, \strlen($string));
+ }
+
+ /**
+ * Write a character.
+ */
+ public function writeCharacter(string $char)
+ {
+ return $this->write((string) $char[0], 1);
+ }
+
+ /**
+ * Write a boolean.
+ */
+ public function writeBoolean(bool $boolean)
+ {
+ return $this->write((string) (bool) $boolean, 1);
+ }
+
+ /**
+ * Write an integer.
+ */
+ public function writeInteger(int $integer)
+ {
+ $integer = (string) (int) $integer;
+
+ return $this->write($integer, \strlen($integer));
+ }
+
+ /**
+ * Write a float.
+ */
+ public function writeFloat(float $float)
+ {
+ $float = (string) (float) $float;
+
+ return $this->write($float, \strlen($float));
+ }
+
+ /**
+ * Write an array.
+ */
+ public function writeArray(array $array)
+ {
+ $array = \var_export($array, true);
+
+ return $this->write($array, \strlen($array));
+ }
+
+ /**
+ * Write a line.
+ */
+ public function writeLine(string $line)
+ {
+ if (false === $n = \strpos($line, "\n")) {
+ return $this->write($line."\n", \strlen($line) + 1);
+ }
+
+ ++$n;
+
+ return $this->write(\substr($line, 0, $n), $n);
+ }
+
+ /**
+ * Write all, i.e. as much as possible.
+ */
+ public function writeAll(string $string)
+ {
+ return $this->write($string, \strlen($string));
+ }
+
+ /**
+ * Truncate a file to a given length.
+ */
+ public function truncate(int $size): bool
+ {
+ return \ftruncate($this->getStream(), $size);
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/FileRead.php b/vendor/psy/psysh/src/Readline/Hoa/FileRead.php
new file mode 100644
index 000000000..9e10fe692
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/FileRead.php
@@ -0,0 +1,177 @@
+getMode(), $createModes)) {
+ throw new FileException('Open mode are not supported; given %d. Only %s are supported.', 0, [$this->getMode(), \implode(', ', $createModes)]);
+ }
+
+ \preg_match('#^(\w+)://#', $streamName, $match);
+
+ if (((isset($match[1]) && $match[1] === 'file') || !isset($match[1])) &&
+ !\file_exists($streamName)) {
+ throw new FileDoesNotExistException('File %s does not exist.', 1, $streamName);
+ }
+
+ $out = parent::_open($streamName, $context);
+
+ return $out;
+ }
+
+ /**
+ * Test for end-of-file.
+ */
+ public function eof(): bool
+ {
+ return \feof($this->getStream());
+ }
+
+ /**
+ * Read n characters.
+ */
+ public function read(int $length)
+ {
+ if (0 > $length) {
+ throw new FileException('Length must be greater than 0, given %d.', 2, $length);
+ }
+
+ return \fread($this->getStream(), $length);
+ }
+
+ /**
+ * Alias of $this->read().
+ */
+ public function readString(int $length)
+ {
+ return $this->read($length);
+ }
+
+ /**
+ * Read a character.
+ */
+ public function readCharacter()
+ {
+ return \fgetc($this->getStream());
+ }
+
+ /**
+ * Read a boolean.
+ */
+ public function readBoolean()
+ {
+ return (bool) $this->read(1);
+ }
+
+ /**
+ * Read an integer.
+ */
+ public function readInteger(int $length = 1)
+ {
+ return (int) $this->read($length);
+ }
+
+ /**
+ * Read a float.
+ */
+ public function readFloat(int $length = 1)
+ {
+ return (float) $this->read($length);
+ }
+
+ /**
+ * Read an array.
+ * Alias of the $this->scanf() method.
+ */
+ public function readArray(string $format = null)
+ {
+ return $this->scanf($format);
+ }
+
+ /**
+ * Read a line.
+ */
+ public function readLine()
+ {
+ return \fgets($this->getStream());
+ }
+
+ /**
+ * Read all, i.e. read as much as possible.
+ */
+ public function readAll(int $offset = 0)
+ {
+ return \stream_get_contents($this->getStream(), -1, $offset);
+ }
+
+ /**
+ * Parse input from a stream according to a format.
+ */
+ public function scanf(string $format): array
+ {
+ return \fscanf($this->getStream(), $format);
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/FileReadWrite.php b/vendor/psy/psysh/src/Readline/Hoa/FileReadWrite.php
new file mode 100644
index 000000000..406b6aa73
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/FileReadWrite.php
@@ -0,0 +1,279 @@
+getMode(), $createModes)) {
+ throw new FileException('Open mode are not supported; given %d. Only %s are supported.', 0, [$this->getMode(), \implode(', ', $createModes)]);
+ }
+
+ \preg_match('#^(\w+)://#', $streamName, $match);
+
+ if (((isset($match[1]) && $match[1] === 'file') || !isset($match[1])) &&
+ !\file_exists($streamName) &&
+ parent::MODE_READ_WRITE === $this->getMode()) {
+ throw new FileDoesNotExistException('File %s does not exist.', 1, $streamName);
+ }
+
+ $out = parent::_open($streamName, $context);
+
+ return $out;
+ }
+
+ /**
+ * Test for end-of-file.
+ */
+ public function eof(): bool
+ {
+ return \feof($this->getStream());
+ }
+
+ /**
+ * Read n characters.
+ */
+ public function read(int $length)
+ {
+ if (0 > $length) {
+ throw new FileException('Length must be greater than 0, given %d.', 2, $length);
+ }
+
+ return \fread($this->getStream(), $length);
+ }
+
+ /**
+ * Alias of $this->read().
+ */
+ public function readString(int $length)
+ {
+ return $this->read($length);
+ }
+
+ /**
+ * Read a character.
+ */
+ public function readCharacter()
+ {
+ return \fgetc($this->getStream());
+ }
+
+ /**
+ * Read a boolean.
+ */
+ public function readBoolean()
+ {
+ return (bool) $this->read(1);
+ }
+
+ /**
+ * Read an integer.
+ */
+ public function readInteger(int $length = 1)
+ {
+ return (int) $this->read($length);
+ }
+
+ /**
+ * Read a float.
+ */
+ public function readFloat(int $length = 1)
+ {
+ return (float) $this->read($length);
+ }
+
+ /**
+ * Read an array.
+ * Alias of the $this->scanf() method.
+ */
+ public function readArray(string $format = null)
+ {
+ return $this->scanf($format);
+ }
+
+ /**
+ * Read a line.
+ */
+ public function readLine()
+ {
+ return \fgets($this->getStream());
+ }
+
+ /**
+ * Read all, i.e. read as much as possible.
+ */
+ public function readAll(int $offset = 0)
+ {
+ return \stream_get_contents($this->getStream(), -1, $offset);
+ }
+
+ /**
+ * Parse input from a stream according to a format.
+ */
+ public function scanf(string $format): array
+ {
+ return \fscanf($this->getStream(), $format);
+ }
+
+ /**
+ * Write n characters.
+ */
+ public function write(string $string, int $length)
+ {
+ if (0 > $length) {
+ throw new FileException('Length must be greater than 0, given %d.', 3, $length);
+ }
+
+ return \fwrite($this->getStream(), $string, $length);
+ }
+
+ /**
+ * Write a string.
+ */
+ public function writeString(string $string)
+ {
+ $string = (string) $string;
+
+ return $this->write($string, \strlen($string));
+ }
+
+ /**
+ * Write a character.
+ */
+ public function writeCharacter(string $char)
+ {
+ return $this->write((string) $char[0], 1);
+ }
+
+ /**
+ * Write a boolean.
+ */
+ public function writeBoolean(bool $boolean)
+ {
+ return $this->write((string) (bool) $boolean, 1);
+ }
+
+ /**
+ * Write an integer.
+ */
+ public function writeInteger(int $integer)
+ {
+ $integer = (string) (int) $integer;
+
+ return $this->write($integer, \strlen($integer));
+ }
+
+ /**
+ * Write a float.
+ */
+ public function writeFloat(float $float)
+ {
+ $float = (string) (float) $float;
+
+ return $this->write($float, \strlen($float));
+ }
+
+ /**
+ * Write an array.
+ */
+ public function writeArray(array $array)
+ {
+ $array = \var_export($array, true);
+
+ return $this->write($array, \strlen($array));
+ }
+
+ /**
+ * Write a line.
+ */
+ public function writeLine(string $line)
+ {
+ if (false === $n = \strpos($line, "\n")) {
+ return $this->write($line."\n", \strlen($line) + 1);
+ }
+
+ ++$n;
+
+ return $this->write(\substr($line, 0, $n), $n);
+ }
+
+ /**
+ * Write all, i.e. as much as possible.
+ */
+ public function writeAll(string $string)
+ {
+ return $this->write($string, \strlen($string));
+ }
+
+ /**
+ * Truncate a file to a given length.
+ */
+ public function truncate(int $size): bool
+ {
+ return \ftruncate($this->getStream(), $size);
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/IStream.php b/vendor/psy/psysh/src/Readline/Hoa/IStream.php
new file mode 100644
index 000000000..9b9949a24
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/IStream.php
@@ -0,0 +1,50 @@
+_splFileInfoClass = $splFileInfoClass;
+
+ if (null === $flags) {
+ parent::__construct($path);
+ } else {
+ parent::__construct($path, $flags);
+ }
+
+ return;
+ }
+
+ /**
+ * Current.
+ * Please, see \FileSystemIterator::current() method.
+ */
+ #[\ReturnTypeWillChange]
+ public function current()
+ {
+ $out = parent::current();
+
+ if (null !== $this->_splFileInfoClass &&
+ $out instanceof \SplFileInfo) {
+ $out->setInfoClass($this->_splFileInfoClass);
+ $out = $out->getFileInfo();
+ }
+
+ return $out;
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/IteratorRecursiveDirectory.php b/vendor/psy/psysh/src/Readline/Hoa/IteratorRecursiveDirectory.php
new file mode 100644
index 000000000..ad6951233
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/IteratorRecursiveDirectory.php
@@ -0,0 +1,126 @@
+_relativePath = $path;
+ $this->setSplFileInfoClass($splFileInfoClass);
+
+ return;
+ }
+
+ /**
+ * Current.
+ * Please, see \RecursiveDirectoryIterator::current() method.
+ */
+ #[\ReturnTypeWillChange]
+ public function current()
+ {
+ $out = parent::current();
+
+ if (null !== $this->_splFileInfoClass &&
+ $out instanceof \SplFileInfo) {
+ $out->setInfoClass($this->_splFileInfoClass);
+ $out = $out->getFileInfo();
+
+ if ($out instanceof IteratorSplFileInfo) {
+ $out->setRelativePath($this->getRelativePath());
+ }
+ }
+
+ return $out;
+ }
+
+ /**
+ * Get children.
+ * Please, see \RecursiveDirectoryIterator::getChildren() method.
+ */
+ #[\ReturnTypeWillChange]
+ public function getChildren()
+ {
+ $out = parent::getChildren();
+ $out->_relativePath = $this->getRelativePath();
+ $out->setSplFileInfoClass($this->_splFileInfoClass);
+
+ return $out;
+ }
+
+ /**
+ * Set SplFileInfo classname.
+ */
+ public function setSplFileInfoClass($splFileInfoClass)
+ {
+ $this->_splFileInfoClass = $splFileInfoClass;
+ }
+
+ /**
+ * Get relative path (if given).
+ */
+ public function getRelativePath(): string
+ {
+ return $this->_relativePath;
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/IteratorSplFileInfo.php b/vendor/psy/psysh/src/Readline/Hoa/IteratorSplFileInfo.php
new file mode 100644
index 000000000..3cf54b845
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/IteratorSplFileInfo.php
@@ -0,0 +1,122 @@
+getMTime()) {
+ $this->_hash = \md5($this->getPathname().$mtime);
+ }
+
+ $this->_relativePath = $relativePath;
+
+ return;
+ }
+
+ /**
+ * Get the hash.
+ */
+ public function getHash(): string
+ {
+ return $this->_hash;
+ }
+
+ /**
+ * Get the MTime.
+ */
+ public function getMTime(): int
+ {
+ try {
+ return parent::getMTime();
+ } catch (\RuntimeException $e) {
+ return -1;
+ }
+ }
+
+ /**
+ * Set relative path.
+ */
+ public function setRelativePath(string $relativePath)
+ {
+ $old = $this->_relativePath;
+ $this->_relativePath = $relativePath;
+
+ return $old;
+ }
+
+ /**
+ * Get relative path (if given).
+ */
+ public function getRelativePath()
+ {
+ return $this->_relativePath;
+ }
+
+ /**
+ * Get relative pathname (if possible).
+ */
+ public function getRelativePathname(): string
+ {
+ if (null === $relative = $this->getRelativePath()) {
+ return $this->getPathname();
+ }
+
+ return \substr($this->getPathname(), \strlen($relative));
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/Protocol.php b/vendor/psy/psysh/src/Readline/Hoa/Protocol.php
new file mode 100644
index 000000000..51d064e02
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/Protocol.php
@@ -0,0 +1,223 @@
+initialize();
+
+ return;
+ }
+
+ /**
+ * Singleton.
+ * To use the `hoa://` protocol shared by everyone.
+ */
+ public static function getInstance(): self
+ {
+ if (null === static::$_instance) {
+ static::$_instance = new self();
+ }
+
+ return static::$_instance;
+ }
+
+ /**
+ * Initialize the protocol.
+ */
+ protected function initialize()
+ {
+ $root = \dirname(__DIR__, 3);
+ $argv0 = \realpath($_SERVER['argv'][0]);
+
+ $cwd =
+ 'cli' === \PHP_SAPI
+ ? false !== $argv0 ? \dirname($argv0) : ''
+ : \getcwd();
+
+ $this[] = new ProtocolNode(
+ 'Application',
+ $cwd.\DIRECTORY_SEPARATOR,
+ [
+ new ProtocolNode('Public', 'Public'.\DIRECTORY_SEPARATOR),
+ ]
+ );
+
+ $this[] = new ProtocolNode(
+ 'Data',
+ \dirname($cwd).\DIRECTORY_SEPARATOR,
+ [
+ new ProtocolNode(
+ 'Etc',
+ 'Etc'.\DIRECTORY_SEPARATOR,
+ [
+ new ProtocolNode('Configuration', 'Configuration'.\DIRECTORY_SEPARATOR),
+ new ProtocolNode('Locale', 'Locale'.\DIRECTORY_SEPARATOR),
+ ]
+ ),
+ new ProtocolNode('Lost+found', 'Lost+found'.\DIRECTORY_SEPARATOR),
+ new ProtocolNode('Temporary', 'Temporary'.\DIRECTORY_SEPARATOR),
+ new ProtocolNode(
+ 'Variable',
+ 'Variable'.\DIRECTORY_SEPARATOR,
+ [
+ new ProtocolNode('Cache', 'Cache'.\DIRECTORY_SEPARATOR),
+ new ProtocolNode('Database', 'Database'.\DIRECTORY_SEPARATOR),
+ new ProtocolNode('Log', 'Log'.\DIRECTORY_SEPARATOR),
+ new ProtocolNode('Private', 'Private'.\DIRECTORY_SEPARATOR),
+ new ProtocolNode('Run', 'Run'.\DIRECTORY_SEPARATOR),
+ new ProtocolNode('Test', 'Test'.\DIRECTORY_SEPARATOR),
+ ]
+ ),
+ ]
+ );
+
+ $this[] = new ProtocolNodeLibrary(
+ 'Library',
+ $root.\DIRECTORY_SEPARATOR.'Hoathis'.\DIRECTORY_SEPARATOR.';'.
+ $root.\DIRECTORY_SEPARATOR.'Hoa'.\DIRECTORY_SEPARATOR
+ );
+ }
+
+ /**
+ * Resolve (unfold) an `hoa://` path to its real resource.
+ *
+ * If `$exists` is set to `true`, try to find the first that exists,
+ * otherwise returns the first solution. If `$unfold` is set to `true`,
+ * it returns all the paths.
+ */
+ public function resolve(string $path, bool $exists = true, bool $unfold = false)
+ {
+ if (\substr($path, 0, 6) !== 'hoa://') {
+ if (true === \is_dir($path)) {
+ $path = \rtrim($path, '/\\');
+
+ if ('' === $path) {
+ $path = '/';
+ }
+ }
+
+ return $path;
+ }
+
+ if (isset(self::$_cache[$path])) {
+ $handle = self::$_cache[$path];
+ } else {
+ $out = $this->_resolve($path, $handle);
+
+ // Not a path but a resource.
+ if (!\is_array($handle)) {
+ return $out;
+ }
+
+ $handle = \array_values(\array_unique($handle, \SORT_REGULAR));
+
+ foreach ($handle as &$entry) {
+ if (true === \is_dir($entry)) {
+ $entry = \rtrim($entry, '/\\');
+
+ if ('' === $entry) {
+ $entry = '/';
+ }
+ }
+ }
+
+ self::$_cache[$path] = $handle;
+ }
+
+ if (true === $unfold) {
+ if (true !== $exists) {
+ return $handle;
+ }
+
+ $out = [];
+
+ foreach ($handle as $solution) {
+ if (\file_exists($solution)) {
+ $out[] = $solution;
+ }
+ }
+
+ return $out;
+ }
+
+ if (true !== $exists) {
+ return $handle[0];
+ }
+
+ foreach ($handle as $solution) {
+ if (\file_exists($solution)) {
+ return $solution;
+ }
+ }
+
+ return static::NO_RESOLUTION;
+ }
+
+ /**
+ * Clear the cache.
+ */
+ public static function clearCache()
+ {
+ self::$_cache = [];
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/ProtocolException.php b/vendor/psy/psysh/src/Readline/Hoa/ProtocolException.php
new file mode 100644
index 000000000..6b624bb9e
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/ProtocolException.php
@@ -0,0 +1,44 @@
+_name = $name;
+ }
+
+ if (null !== $reach) {
+ $this->_reach = $reach;
+ }
+
+ foreach ($children as $child) {
+ $this[] = $child;
+ }
+
+ return;
+ }
+
+ /**
+ * Add a node.
+ */
+ #[\ReturnTypeWillChange]
+ public function offsetSet($name, $node)
+ {
+ if (!($node instanceof self)) {
+ throw new ProtocolException('Protocol node must extend %s.', 0, __CLASS__);
+ }
+
+ if (empty($name)) {
+ $name = $node->getName();
+ }
+
+ if (empty($name)) {
+ throw new ProtocolException('Cannot add a node to the `hoa://` protocol without a name.', 1);
+ }
+
+ $this->_children[$name] = $node;
+ }
+
+ /**
+ * Get a specific node.
+ */
+ public function offsetGet($name): self
+ {
+ if (!isset($this[$name])) {
+ throw new ProtocolException('Node %s does not exist.', 2, $name);
+ }
+
+ return $this->_children[$name];
+ }
+
+ /**
+ * Check if a node exists.
+ */
+ public function offsetExists($name): bool
+ {
+ return true === \array_key_exists($name, $this->_children);
+ }
+
+ /**
+ * Remove a node.
+ */
+ #[\ReturnTypeWillChange]
+ public function offsetUnset($name)
+ {
+ unset($this->_children[$name]);
+ }
+
+ /**
+ * Resolve a path, i.e. iterate the nodes tree and reach the queue of
+ * the path.
+ */
+ protected function _resolve(string $path, &$accumulator, string $id = null)
+ {
+ if (\substr($path, 0, 6) === 'hoa://') {
+ $path = \substr($path, 6);
+ }
+
+ if (empty($path)) {
+ return null;
+ }
+
+ if (null === $accumulator) {
+ $accumulator = [];
+ $posId = \strpos($path, '#');
+
+ if (false !== $posId) {
+ $id = \substr($path, $posId + 1);
+ $path = \substr($path, 0, $posId);
+ } else {
+ $id = null;
+ }
+ }
+
+ $path = \trim($path, '/');
+ $pos = \strpos($path, '/');
+
+ if (false !== $pos) {
+ $next = \substr($path, 0, $pos);
+ } else {
+ $next = $path;
+ }
+
+ if (isset($this[$next])) {
+ if (false === $pos) {
+ if (null === $id) {
+ $this->_resolveChoice($this[$next]->reach(), $accumulator);
+
+ return true;
+ }
+
+ $accumulator = null;
+
+ return $this[$next]->reachId($id);
+ }
+
+ $tnext = $this[$next];
+ $this->_resolveChoice($tnext->reach(), $accumulator);
+
+ return $tnext->_resolve(\substr($path, $pos + 1), $accumulator, $id);
+ }
+
+ $this->_resolveChoice($this->reach($path), $accumulator);
+
+ return true;
+ }
+
+ /**
+ * Resolve choices, i.e. a reach value has a “;”.
+ */
+ protected function _resolveChoice($reach, &$accumulator)
+ {
+ if (null === $reach) {
+ $reach = '';
+ }
+
+ if (empty($accumulator)) {
+ $accumulator = \explode(';', $reach);
+
+ return;
+ }
+
+ if (false === \strpos($reach, ';')) {
+ if (false !== $pos = \strrpos($reach, "\r")) {
+ $reach = \substr($reach, $pos + 1);
+
+ foreach ($accumulator as &$entry) {
+ $entry = null;
+ }
+ }
+
+ foreach ($accumulator as &$entry) {
+ $entry .= $reach;
+ }
+
+ return;
+ }
+
+ $choices = \explode(';', $reach);
+ $ref = $accumulator;
+ $accumulator = [];
+
+ foreach ($choices as $choice) {
+ if (false !== $pos = \strrpos($choice, "\r")) {
+ $choice = \substr($choice, $pos + 1);
+
+ foreach ($ref as $entry) {
+ $accumulator[] = $choice;
+ }
+ } else {
+ foreach ($ref as $entry) {
+ $accumulator[] = $entry.$choice;
+ }
+ }
+ }
+
+ unset($ref);
+
+ return;
+ }
+
+ /**
+ * Queue of the node.
+ * Generic one. Must be overrided in children classes.
+ */
+ public function reach(string $queue = null)
+ {
+ return empty($queue) ? $this->_reach : $queue;
+ }
+
+ /**
+ * ID of the component.
+ * Generic one. Should be overrided in children classes.
+ */
+ public function reachId(string $id)
+ {
+ throw new ProtocolException('The node %s has no ID support (tried to reach #%s).', 4, [$this->getName(), $id]);
+ }
+
+ /**
+ * Set a new reach value.
+ */
+ public function setReach(string $reach)
+ {
+ $old = $this->_reach;
+ $this->_reach = $reach;
+
+ return $old;
+ }
+
+ /**
+ * Get node's name.
+ */
+ public function getName()
+ {
+ return $this->_name;
+ }
+
+ /**
+ * Get reach's root.
+ */
+ protected function getReach()
+ {
+ return $this->_reach;
+ }
+
+ /**
+ * Get an iterator.
+ */
+ public function getIterator(): \ArrayIterator
+ {
+ return new \ArrayIterator($this->_children);
+ }
+
+ /**
+ * Get root the protocol.
+ */
+ public static function getRoot(): Protocol
+ {
+ return Protocol::getInstance();
+ }
+
+ /**
+ * Print a tree of component.
+ */
+ public function __toString(): string
+ {
+ static $i = 0;
+
+ $out = \str_repeat(' ', $i).$this->getName()."\n";
+
+ foreach ($this as $node) {
+ ++$i;
+ $out .= $node;
+ --$i;
+ }
+
+ return $out;
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/ProtocolNodeLibrary.php b/vendor/psy/psysh/src/Readline/Hoa/ProtocolNodeLibrary.php
new file mode 100644
index 000000000..dfb0cb206
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/ProtocolNodeLibrary.php
@@ -0,0 +1,90 @@
+_reach) as $part) {
+ $out[] = "\r".$part.\strtolower($head).$queue;
+ }
+
+ $out[] = "\r".\dirname(__DIR__, 5).$queue;
+
+ return \implode(';', $out);
+ }
+
+ $out = [];
+
+ foreach (\explode(';', $this->_reach) as $part) {
+ $pos = \strrpos(\rtrim($part, \DIRECTORY_SEPARATOR), \DIRECTORY_SEPARATOR) + 1;
+ $head = \substr($part, 0, $pos);
+ $tail = \substr($part, $pos);
+ $out[] = $head.\strtolower($tail);
+ }
+
+ $this->_reach = \implode(';', $out);
+
+ return parent::reach($queue);
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/ProtocolWrapper.php b/vendor/psy/psysh/src/Readline/Hoa/ProtocolWrapper.php
new file mode 100644
index 000000000..8d525e7ef
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/ProtocolWrapper.php
@@ -0,0 +1,473 @@
+resolve($path, $exists);
+ }
+
+ /**
+ * Retrieve the underlying resource.
+ *
+ * `$castAs` can be `STREAM_CAST_FOR_SELECT` when `stream_select` is
+ * calling `stream_cast` or `STREAM_CAST_AS_STREAM` when `stream_cast` is
+ * called for other uses.
+ */
+ public function stream_cast(int $castAs)
+ {
+ return null;
+ }
+
+ /**
+ * Closes a resource.
+ * This method is called in response to `fclose`.
+ * All resources that were locked, or allocated, by the wrapper should be
+ * released.
+ */
+ public function stream_close()
+ {
+ if (true === @\fclose($this->getStream())) {
+ $this->_stream = null;
+ $this->_streamName = null;
+ }
+ }
+
+ /**
+ * Tests for end-of-file on a file pointer.
+ * This method is called in response to feof().
+ */
+ public function stream_eof(): bool
+ {
+ return \feof($this->getStream());
+ }
+
+ /**
+ * Flush the output.
+ * This method is called in respond to fflush().
+ * If we have cached data in our stream but not yet stored it into the
+ * underlying storage, we should do so now.
+ */
+ public function stream_flush(): bool
+ {
+ return \fflush($this->getStream());
+ }
+
+ /**
+ * Advisory file locking.
+ * This method is called in response to flock(), when file_put_contents()
+ * (when flags contains LOCK_EX), stream_set_blocking() and when closing the
+ * stream (LOCK_UN).
+ *
+ * Operation is one the following:
+ * * LOCK_SH to acquire a shared lock (reader) ;
+ * * LOCK_EX to acquire an exclusive lock (writer) ;
+ * * LOCK_UN to release a lock (shared or exclusive) ;
+ * * LOCK_NB if we don't want flock() to
+ * block while locking (not supported on
+ * Windows).
+ */
+ public function stream_lock(int $operation): bool
+ {
+ return \flock($this->getStream(), $operation);
+ }
+
+ /**
+ * Change stream options.
+ * This method is called to set metadata on the stream. It is called when
+ * one of the following functions is called on a stream URL: touch, chmod,
+ * chown or chgrp.
+ *
+ * Option must be one of the following constant:
+ * * STREAM_META_TOUCH,
+ * * STREAM_META_OWNER_NAME,
+ * * STREAM_META_OWNER,
+ * * STREAM_META_GROUP_NAME,
+ * * STREAM_META_GROUP,
+ * * STREAM_META_ACCESS.
+ *
+ * Values are arguments of `touch`, `chmod`, `chown`, and `chgrp`.
+ */
+ public function stream_metadata(string $path, int $option, $values): bool
+ {
+ $path = static::realPath($path, false);
+
+ switch ($option) {
+ case \STREAM_META_TOUCH:
+ $arity = \count($values);
+
+ if (0 === $arity) {
+ $out = \touch($path);
+ } elseif (1 === $arity) {
+ $out = \touch($path, $values[0]);
+ } else {
+ $out = \touch($path, $values[0], $values[1]);
+ }
+
+ break;
+
+ case \STREAM_META_OWNER_NAME:
+ case \STREAM_META_OWNER:
+ $out = \chown($path, $values);
+
+ break;
+
+ case \STREAM_META_GROUP_NAME:
+ case \STREAM_META_GROUP:
+ $out = \chgrp($path, $values);
+
+ break;
+
+ case \STREAM_META_ACCESS:
+ $out = \chmod($path, $values);
+
+ break;
+
+ default:
+ $out = false;
+ }
+
+ return $out;
+ }
+
+ /**
+ * Open file or URL.
+ * This method is called immediately after the wrapper is initialized (f.e.
+ * by fopen() and file_get_contents()).
+ */
+ public function stream_open(string $path, string $mode, int $options, &$openedPath): bool
+ {
+ $path = static::realPath($path, 'r' === $mode[0]);
+
+ if (Protocol::NO_RESOLUTION === $path) {
+ return false;
+ }
+
+ if (null === $this->context) {
+ $openedPath = \fopen($path, $mode, $options & \STREAM_USE_PATH);
+ } else {
+ $openedPath = \fopen(
+ $path,
+ $mode,
+ (bool) ($options & \STREAM_USE_PATH),
+ $this->context
+ );
+ }
+
+ if (false === \is_resource($openedPath)) {
+ return false;
+ }
+
+ $this->_stream = $openedPath;
+ $this->_streamName = $path;
+
+ return true;
+ }
+
+ /**
+ * Read from stream.
+ * This method is called in response to fread() and fgets().
+ */
+ public function stream_read(int $size): string
+ {
+ return \fread($this->getStream(), $size);
+ }
+
+ /**
+ * Seek to specific location in a stream.
+ * This method is called in response to fseek().
+ * The read/write position of the stream should be updated according to the
+ * $offset and $whence.
+ *
+ * The possible values for `$whence` are:
+ * * SEEK_SET to set position equal to $offset bytes,
+ * * SEEK_CUR to set position to current location plus `$offset`,
+ * * SEEK_END to set position to end-of-file plus `$offset`.
+ */
+ public function stream_seek(int $offset, int $whence = \SEEK_SET): bool
+ {
+ return 0 === \fseek($this->getStream(), $offset, $whence);
+ }
+
+ /**
+ * Retrieve information about a file resource.
+ * This method is called in response to fstat().
+ */
+ public function stream_stat(): array
+ {
+ return \fstat($this->getStream());
+ }
+
+ /**
+ * Retrieve the current position of a stream.
+ * This method is called in response to ftell().
+ */
+ public function stream_tell(): int
+ {
+ return \ftell($this->getStream());
+ }
+
+ /**
+ * Truncate a stream to a given length.
+ */
+ public function stream_truncate(int $size): bool
+ {
+ return \ftruncate($this->getStream(), $size);
+ }
+
+ /**
+ * Write to stream.
+ * This method is called in response to fwrite().
+ */
+ public function stream_write(string $data): int
+ {
+ return \fwrite($this->getStream(), $data);
+ }
+
+ /**
+ * Close directory handle.
+ * This method is called in to closedir().
+ * Any resources which were locked, or allocated, during opening and use of
+ * the directory stream should be released.
+ */
+ public function dir_closedir()
+ {
+ \closedir($this->getStream());
+ $this->_stream = null;
+ $this->_streamName = null;
+ }
+
+ /**
+ * Open directory handle.
+ * This method is called in response to opendir().
+ *
+ * The `$options` input represents whether or not to enforce safe_mode
+ * (0x04). It is not used here.
+ */
+ public function dir_opendir(string $path, int $options): bool
+ {
+ $path = static::realPath($path);
+ $handle = null;
+
+ if (null === $this->context) {
+ $handle = @\opendir($path);
+ } else {
+ $handle = @\opendir($path, $this->context);
+ }
+
+ if (false === $handle) {
+ return false;
+ }
+
+ $this->_stream = $handle;
+ $this->_streamName = $path;
+
+ return true;
+ }
+
+ /**
+ * Read entry from directory handle.
+ * This method is called in response to readdir().
+ *
+ * @return mixed
+ */
+ public function dir_readdir()
+ {
+ return \readdir($this->getStream());
+ }
+
+ /**
+ * Rewind directory handle.
+ * This method is called in response to rewinddir().
+ * Should reset the output generated by self::dir_readdir, i.e. the next
+ * call to self::dir_readdir should return the first entry in the location
+ * returned by self::dir_opendir.
+ */
+ public function dir_rewinddir()
+ {
+ \rewinddir($this->getStream());
+ }
+
+ /**
+ * Create a directory.
+ * This method is called in response to mkdir().
+ */
+ public function mkdir(string $path, int $mode, int $options): bool
+ {
+ if (null === $this->context) {
+ return \mkdir(
+ static::realPath($path, false),
+ $mode,
+ $options | \STREAM_MKDIR_RECURSIVE
+ );
+ }
+
+ return \mkdir(
+ static::realPath($path, false),
+ $mode,
+ (bool) ($options | \STREAM_MKDIR_RECURSIVE),
+ $this->context
+ );
+ }
+
+ /**
+ * Rename a file or directory.
+ * This method is called in response to rename().
+ * Should attempt to rename $from to $to.
+ */
+ public function rename(string $from, string $to): bool
+ {
+ if (null === $this->context) {
+ return \rename(static::realPath($from), static::realPath($to, false));
+ }
+
+ return \rename(
+ static::realPath($from),
+ static::realPath($to, false),
+ $this->context
+ );
+ }
+
+ /**
+ * Remove a directory.
+ * This method is called in response to rmdir().
+ * The `$options` input is a bitwise mask of values. It is not used here.
+ */
+ public function rmdir(string $path, int $options): bool
+ {
+ if (null === $this->context) {
+ return \rmdir(static::realPath($path));
+ }
+
+ return \rmdir(static::realPath($path), $this->context);
+ }
+
+ /**
+ * Delete a file.
+ * This method is called in response to unlink().
+ */
+ public function unlink(string $path): bool
+ {
+ if (null === $this->context) {
+ return \unlink(static::realPath($path));
+ }
+
+ return \unlink(static::realPath($path), $this->context);
+ }
+
+ /**
+ * Retrieve information about a file.
+ * This method is called in response to all stat() related functions.
+ * The `$flags` input holds additional flags set by the streams API. It
+ * can hold one or more of the following values OR'd together.
+ * STREAM_URL_STAT_LINK: for resource with the ability to link to other
+ * resource (such as an HTTP location: forward, or a filesystem
+ * symlink). This flag specified that only information about the link
+ * itself should be returned, not the resource pointed to by the
+ * link. This flag is set in response to calls to lstat(), is_link(), or
+ * filetype(). STREAM_URL_STAT_QUIET: if this flag is set, our wrapper
+ * should not raise any errors. If this flag is not set, we are
+ * responsible for reporting errors using the trigger_error() function
+ * during stating of the path.
+ */
+ public function url_stat(string $path, int $flags)
+ {
+ $path = static::realPath($path);
+
+ if (Protocol::NO_RESOLUTION === $path) {
+ if ($flags & \STREAM_URL_STAT_QUIET) {
+ return 0;
+ } else {
+ return \trigger_error(
+ 'Path '.$path.' cannot be resolved.',
+ \E_WARNING
+ );
+ }
+ }
+
+ if ($flags & \STREAM_URL_STAT_LINK) {
+ return @\lstat($path);
+ }
+
+ return @\stat($path);
+ }
+
+ /**
+ * Get stream resource.
+ */
+ public function getStream()
+ {
+ return $this->_stream;
+ }
+
+ /**
+ * Get stream name.
+ */
+ public function getStreamName()
+ {
+ return $this->_streamName;
+ }
+}
+
+/*
+ * Register the `hoa://` protocol.
+ */
+\stream_wrapper_register('hoa', ProtocolWrapper::class);
diff --git a/vendor/psy/psysh/src/Readline/Hoa/Readline.php b/vendor/psy/psysh/src/Readline/Hoa/Readline.php
new file mode 100644
index 000000000..0338c9026
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/Readline.php
@@ -0,0 +1,1032 @@
+_mapping["\033[A"] = [$this, '_bindArrowUp'];
+ $this->_mapping["\033[B"] = [$this, '_bindArrowDown'];
+ $this->_mapping["\033[C"] = [$this, '_bindArrowRight'];
+ $this->_mapping["\033[D"] = [$this, '_bindArrowLeft'];
+ $this->_mapping["\001"] = [$this, '_bindControlA'];
+ $this->_mapping["\002"] = [$this, '_bindControlB'];
+ $this->_mapping["\005"] = [$this, '_bindControlE'];
+ $this->_mapping["\006"] = [$this, '_bindControlF'];
+ $this->_mapping["\010"] =
+ $this->_mapping["\177"] = [$this, '_bindBackspace'];
+ $this->_mapping["\027"] = [$this, '_bindControlW'];
+ $this->_mapping["\n"] = [$this, '_bindNewline'];
+ $this->_mapping["\t"] = [$this, '_bindTab'];
+
+ return;
+ }
+
+ /**
+ * Read a line from the input.
+ */
+ public function readLine(string $prefix = null)
+ {
+ $input = Console::getInput();
+
+ if (true === $input->eof()) {
+ return false;
+ }
+
+ $direct = Console::isDirect($input->getStream()->getStream());
+ $output = Console::getOutput();
+
+ if (false === $direct || \defined('PHP_WINDOWS_VERSION_PLATFORM')) {
+ $out = $input->readLine();
+
+ if (false === $out) {
+ return false;
+ }
+
+ $out = \substr($out, 0, -1);
+
+ if (true === $direct) {
+ $output->writeAll($prefix);
+ } else {
+ $output->writeAll($prefix.$out."\n");
+ }
+
+ return $out;
+ }
+
+ $this->resetLine();
+ $this->setPrefix($prefix);
+ $read = [$input->getStream()->getStream()];
+ $write = $except = [];
+ $output->writeAll($prefix);
+
+ while (true) {
+ @\stream_select($read, $write, $except, 30, 0);
+
+ if (empty($read)) {
+ $read = [$input->getStream()->getStream()];
+
+ continue;
+ }
+
+ $char = $this->_read();
+ $this->_buffer = $char;
+ $return = $this->_readLine($char);
+
+ if (0 === ($return & self::STATE_NO_ECHO)) {
+ $output->writeAll($this->_buffer);
+ }
+
+ if (0 !== ($return & self::STATE_BREAK)) {
+ break;
+ }
+ }
+
+ return $this->getLine();
+ }
+
+ /**
+ * Readline core.
+ */
+ public function _readLine(string $char)
+ {
+ if (isset($this->_mapping[$char]) &&
+ \is_callable($this->_mapping[$char])) {
+ $mapping = $this->_mapping[$char];
+
+ return $mapping($this);
+ }
+
+ if (isset($this->_mapping[$char])) {
+ $this->_buffer = $this->_mapping[$char];
+ } elseif (false === Ustring::isCharPrintable($char)) {
+ ConsoleCursor::bip();
+
+ return static::STATE_CONTINUE | static::STATE_NO_ECHO;
+ }
+
+ if ($this->getLineLength() === $this->getLineCurrent()) {
+ $this->appendLine($this->_buffer);
+
+ return static::STATE_CONTINUE;
+ }
+
+ $this->insertLine($this->_buffer);
+ $tail = \mb_substr(
+ $this->getLine(),
+ $this->getLineCurrent() - 1
+ );
+ $this->_buffer = "\033[K".$tail.\str_repeat(
+ "\033[D",
+ \mb_strlen($tail) - 1
+ );
+
+ return static::STATE_CONTINUE;
+ }
+
+ /**
+ * Add mappings.
+ */
+ public function addMappings(array $mappings)
+ {
+ foreach ($mappings as $key => $mapping) {
+ $this->addMapping($key, $mapping);
+ }
+ }
+
+ /**
+ * Add a mapping.
+ * Supported key:
+ * • \e[… for \033[…;
+ * • \C-… for Ctrl-…;
+ * • abc for a simple mapping.
+ * A mapping is a callable that has only one parameter of type
+ * Hoa\Console\Readline and that returns a self::STATE_* constant.
+ */
+ public function addMapping(string $key, $mapping)
+ {
+ if ('\e[' === \substr($key, 0, 3)) {
+ $this->_mapping["\033[".\substr($key, 3)] = $mapping;
+ } elseif ('\C-' === \substr($key, 0, 3)) {
+ $_key = \ord(\strtolower(\substr($key, 3))) - 96;
+ $this->_mapping[\chr($_key)] = $mapping;
+ } else {
+ $this->_mapping[$key] = $mapping;
+ }
+ }
+
+ /**
+ * Add an entry in the history.
+ */
+ public function addHistory(string $line = null)
+ {
+ if (empty($line)) {
+ return;
+ }
+
+ $this->_history[] = $line;
+ $this->_historyCurrent = $this->_historySize++;
+ }
+
+ /**
+ * Clear history.
+ */
+ public function clearHistory()
+ {
+ unset($this->_history);
+ $this->_history = [];
+ $this->_historyCurrent = 0;
+ $this->_historySize = 1;
+ }
+
+ /**
+ * Get an entry in the history.
+ */
+ public function getHistory(int $i = null)
+ {
+ if (null === $i) {
+ $i = $this->_historyCurrent;
+ }
+
+ if (!isset($this->_history[$i])) {
+ return null;
+ }
+
+ return $this->_history[$i];
+ }
+
+ /**
+ * Go backward in the history.
+ */
+ public function previousHistory()
+ {
+ if (0 >= $this->_historyCurrent) {
+ return $this->getHistory(0);
+ }
+
+ return $this->getHistory($this->_historyCurrent--);
+ }
+
+ /**
+ * Go forward in the history.
+ */
+ public function nextHistory()
+ {
+ if ($this->_historyCurrent + 1 >= $this->_historySize) {
+ return $this->getLine();
+ }
+
+ return $this->getHistory(++$this->_historyCurrent);
+ }
+
+ /**
+ * Get current line.
+ */
+ public function getLine()
+ {
+ return $this->_line;
+ }
+
+ /**
+ * Append to current line.
+ */
+ public function appendLine(string $append)
+ {
+ $this->_line .= $append;
+ $this->_lineLength = \mb_strlen($this->_line);
+ $this->_lineCurrent = $this->_lineLength;
+ }
+
+ /**
+ * Insert into current line at the current seek.
+ */
+ public function insertLine(string $insert)
+ {
+ if ($this->_lineLength === $this->_lineCurrent) {
+ return $this->appendLine($insert);
+ }
+
+ $this->_line = \mb_substr($this->_line, 0, $this->_lineCurrent).
+ $insert.
+ \mb_substr($this->_line, $this->_lineCurrent);
+ $this->_lineLength = \mb_strlen($this->_line);
+ $this->_lineCurrent += \mb_strlen($insert);
+
+ return;
+ }
+
+ /**
+ * Reset current line.
+ */
+ protected function resetLine()
+ {
+ $this->_line = null;
+ $this->_lineCurrent = 0;
+ $this->_lineLength = 0;
+ }
+
+ /**
+ * Get current line seek.
+ */
+ public function getLineCurrent(): int
+ {
+ return $this->_lineCurrent;
+ }
+
+ /**
+ * Get current line length.
+ *
+ * @return int
+ */
+ public function getLineLength(): int
+ {
+ return $this->_lineLength;
+ }
+
+ /**
+ * Set prefix.
+ */
+ public function setPrefix(string $prefix)
+ {
+ $this->_prefix = $prefix;
+ }
+
+ /**
+ * Get prefix.
+ */
+ public function getPrefix()
+ {
+ return $this->_prefix;
+ }
+
+ /**
+ * Get buffer. Not for user.
+ */
+ public function getBuffer()
+ {
+ return $this->_buffer;
+ }
+
+ /**
+ * Set an autocompleter.
+ */
+ public function setAutocompleter(Autocompleter $autocompleter)
+ {
+ $old = $this->_autocompleter;
+ $this->_autocompleter = $autocompleter;
+
+ return $old;
+ }
+
+ /**
+ * Get the autocompleter.
+ *
+ * @return ?Autocompleter
+ */
+ public function getAutocompleter()
+ {
+ return $this->_autocompleter;
+ }
+
+ /**
+ * Read on input. Not for user.
+ */
+ public function _read(int $length = 512): string
+ {
+ return Console::getInput()->read($length);
+ }
+
+ /**
+ * Set current line. Not for user.
+ */
+ public function setLine(string $line)
+ {
+ $this->_line = $line;
+ $this->_lineLength = \mb_strlen($this->_line ?: '');
+ $this->_lineCurrent = $this->_lineLength;
+ }
+
+ /**
+ * Set current line seek. Not for user.
+ */
+ public function setLineCurrent(int $current)
+ {
+ $this->_lineCurrent = $current;
+ }
+
+ /**
+ * Set line length. Not for user.
+ */
+ public function setLineLength(int $length)
+ {
+ $this->_lineLength = $length;
+ }
+
+ /**
+ * Set buffer. Not for user.
+ */
+ public function setBuffer(string $buffer)
+ {
+ $this->_buffer = $buffer;
+ }
+
+ /**
+ * Up arrow binding.
+ * Go backward in the history.
+ */
+ public function _bindArrowUp(self $self): int
+ {
+ if (0 === (static::STATE_CONTINUE & static::STATE_NO_ECHO)) {
+ ConsoleCursor::clear('↔');
+ Console::getOutput()->writeAll($self->getPrefix());
+ }
+ $buffer = $self->previousHistory() ?? '';
+ $self->setBuffer($buffer);
+ $self->setLine($buffer);
+
+ return static::STATE_CONTINUE;
+ }
+
+ /**
+ * Down arrow binding.
+ * Go forward in the history.
+ */
+ public function _bindArrowDown(self $self): int
+ {
+ if (0 === (static::STATE_CONTINUE & static::STATE_NO_ECHO)) {
+ ConsoleCursor::clear('↔');
+ Console::getOutput()->writeAll($self->getPrefix());
+ }
+
+ $self->setBuffer($buffer = $self->nextHistory());
+ $self->setLine($buffer);
+
+ return static::STATE_CONTINUE;
+ }
+
+ /**
+ * Right arrow binding.
+ * Move cursor to the right.
+ */
+ public function _bindArrowRight(self $self): int
+ {
+ if ($self->getLineLength() > $self->getLineCurrent()) {
+ if (0 === (static::STATE_CONTINUE & static::STATE_NO_ECHO)) {
+ ConsoleCursor::move('→');
+ }
+
+ $self->setLineCurrent($self->getLineCurrent() + 1);
+ }
+
+ $self->setBuffer('');
+
+ return static::STATE_CONTINUE;
+ }
+
+ /**
+ * Left arrow binding.
+ * Move cursor to the left.
+ */
+ public function _bindArrowLeft(self $self): int
+ {
+ if (0 < $self->getLineCurrent()) {
+ if (0 === (static::STATE_CONTINUE & static::STATE_NO_ECHO)) {
+ ConsoleCursor::move('←');
+ }
+
+ $self->setLineCurrent($self->getLineCurrent() - 1);
+ }
+
+ $self->setBuffer('');
+
+ return static::STATE_CONTINUE;
+ }
+
+ /**
+ * Backspace and Control-H binding.
+ * Delete the first character at the right of the cursor.
+ */
+ public function _bindBackspace(self $self): int
+ {
+ $buffer = '';
+
+ if (0 < $self->getLineCurrent()) {
+ if (0 === (static::STATE_CONTINUE & static::STATE_NO_ECHO)) {
+ ConsoleCursor::move('←');
+ ConsoleCursor::clear('→');
+ }
+
+ if ($self->getLineLength() === $current = $self->getLineCurrent()) {
+ $self->setLine(\mb_substr($self->getLine(), 0, -1));
+ } else {
+ $line = $self->getLine();
+ $current = $self->getLineCurrent();
+ $tail = \mb_substr($line, $current);
+ $buffer = $tail.\str_repeat("\033[D", \mb_strlen($tail));
+ $self->setLine(\mb_substr($line, 0, $current - 1).$tail);
+ $self->setLineCurrent($current - 1);
+ }
+ }
+
+ $self->setBuffer($buffer);
+
+ return static::STATE_CONTINUE;
+ }
+
+ /**
+ * Control-A binding.
+ * Move cursor to beginning of line.
+ */
+ public function _bindControlA(self $self): int
+ {
+ for ($i = $self->getLineCurrent() - 1; 0 <= $i; --$i) {
+ $self->_bindArrowLeft($self);
+ }
+
+ return static::STATE_CONTINUE;
+ }
+
+ /**
+ * Control-B binding.
+ * Move cursor backward one word.
+ */
+ public function _bindControlB(self $self): int
+ {
+ $current = $self->getLineCurrent();
+
+ if (0 === $current) {
+ return static::STATE_CONTINUE;
+ }
+
+ $words = \preg_split(
+ '#\b#u',
+ $self->getLine(),
+ -1,
+ \PREG_SPLIT_OFFSET_CAPTURE | \PREG_SPLIT_NO_EMPTY
+ );
+
+ for (
+ $i = 0, $max = \count($words) - 1;
+ $i < $max && $words[$i + 1][1] < $current;
+ ++$i
+ ) {
+ }
+
+ for ($j = $words[$i][1] + 1; $current >= $j; ++$j) {
+ $self->_bindArrowLeft($self);
+ }
+
+ return static::STATE_CONTINUE;
+ }
+
+ /**
+ * Control-E binding.
+ * Move cursor to end of line.
+ */
+ public function _bindControlE(self $self): int
+ {
+ for (
+ $i = $self->getLineCurrent(), $max = $self->getLineLength();
+ $i < $max;
+ ++$i
+ ) {
+ $self->_bindArrowRight($self);
+ }
+
+ return static::STATE_CONTINUE;
+ }
+
+ /**
+ * Control-F binding.
+ * Move cursor forward one word.
+ */
+ public function _bindControlF(self $self): int
+ {
+ $current = $self->getLineCurrent();
+
+ if ($self->getLineLength() === $current) {
+ return static::STATE_CONTINUE;
+ }
+
+ $words = \preg_split(
+ '#\b#u',
+ $self->getLine(),
+ -1,
+ \PREG_SPLIT_OFFSET_CAPTURE | \PREG_SPLIT_NO_EMPTY
+ );
+
+ for (
+ $i = 0, $max = \count($words) - 1;
+ $i < $max && $words[$i][1] < $current;
+ ++$i
+ ) {
+ }
+
+ if (!isset($words[$i + 1])) {
+ $words[$i + 1] = [1 => $self->getLineLength()];
+ }
+
+ for ($j = $words[$i + 1][1]; $j > $current; --$j) {
+ $self->_bindArrowRight($self);
+ }
+
+ return static::STATE_CONTINUE;
+ }
+
+ /**
+ * Control-W binding.
+ * Delete first backward word.
+ */
+ public function _bindControlW(self $self): int
+ {
+ $current = $self->getLineCurrent();
+
+ if (0 === $current) {
+ return static::STATE_CONTINUE;
+ }
+
+ $words = \preg_split(
+ '#\b#u',
+ $self->getLine(),
+ -1,
+ \PREG_SPLIT_OFFSET_CAPTURE | \PREG_SPLIT_NO_EMPTY
+ );
+
+ for (
+ $i = 0, $max = \count($words) - 1;
+ $i < $max && $words[$i + 1][1] < $current;
+ ++$i
+ ) {
+ }
+
+ for ($j = $words[$i][1] + 1; $current >= $j; ++$j) {
+ $self->_bindBackspace($self);
+ }
+
+ return static::STATE_CONTINUE;
+ }
+
+ /**
+ * Newline binding.
+ */
+ public function _bindNewline(self $self): int
+ {
+ $self->addHistory($self->getLine());
+
+ return static::STATE_BREAK;
+ }
+
+ /**
+ * Tab binding.
+ */
+ public function _bindTab(self $self): int
+ {
+ $output = Console::getOutput();
+ $autocompleter = $self->getAutocompleter();
+ $state = static::STATE_CONTINUE | static::STATE_NO_ECHO;
+
+ if (null === $autocompleter) {
+ return $state;
+ }
+
+ $current = $self->getLineCurrent();
+ $line = $self->getLine();
+
+ if (0 === $current) {
+ return $state;
+ }
+
+ $matches = \preg_match_all(
+ '#'.$autocompleter->getWordDefinition().'$#u',
+ \mb_substr($line, 0, $current),
+ $words
+ );
+
+ if (0 === $matches) {
+ return $state;
+ }
+
+ $word = $words[0][0];
+
+ if ('' === \trim($word)) {
+ return $state;
+ }
+
+ $solution = $autocompleter->complete($word);
+ $length = \mb_strlen($word);
+
+ if (null === $solution) {
+ return $state;
+ }
+
+ if (\is_array($solution)) {
+ $_solution = $solution;
+ $count = \count($_solution) - 1;
+ $cWidth = 0;
+ $window = ConsoleWindow::getSize();
+ $wWidth = $window['x'];
+ $cursor = ConsoleCursor::getPosition();
+
+ \array_walk($_solution, function (&$value) use (&$cWidth) {
+ $handle = \mb_strlen($value);
+
+ if ($handle > $cWidth) {
+ $cWidth = $handle;
+ }
+
+ return;
+ });
+ \array_walk($_solution, function (&$value) use (&$cWidth) {
+ $handle = \mb_strlen($value);
+
+ if ($handle >= $cWidth) {
+ return;
+ }
+
+ $value .= \str_repeat(' ', $cWidth - $handle);
+
+ return;
+ });
+
+ $mColumns = (int) \floor($wWidth / ($cWidth + 2));
+ $mLines = (int) \ceil(($count + 1) / $mColumns);
+ --$mColumns;
+ $i = 0;
+
+ if (0 > $window['y'] - $cursor['y'] - $mLines) {
+ ConsoleWindow::scroll('↑', $mLines);
+ ConsoleCursor::move('↑', $mLines);
+ }
+
+ ConsoleCursor::save();
+ ConsoleCursor::hide();
+ ConsoleCursor::move('↓ LEFT');
+ ConsoleCursor::clear('↓');
+
+ foreach ($_solution as $j => $s) {
+ $output->writeAll("\033[0m".$s."\033[0m");
+
+ if ($i++ < $mColumns) {
+ $output->writeAll(' ');
+ } else {
+ $i = 0;
+
+ if (isset($_solution[$j + 1])) {
+ $output->writeAll("\n");
+ }
+ }
+ }
+
+ ConsoleCursor::restore();
+ ConsoleCursor::show();
+
+ ++$mColumns;
+ $input = Console::getInput();
+ $read = [$input->getStream()->getStream()];
+ $write = $except = [];
+ $mColumn = -1;
+ $mLine = -1;
+ $coord = -1;
+ $unselect = function () use (
+ &$mColumn,
+ &$mLine,
+ &$coord,
+ &$_solution,
+ &$cWidth,
+ $output
+ ) {
+ ConsoleCursor::save();
+ ConsoleCursor::hide();
+ ConsoleCursor::move('↓ LEFT');
+ ConsoleCursor::move('→', $mColumn * ($cWidth + 2));
+ ConsoleCursor::move('↓', $mLine);
+ $output->writeAll("\033[0m".$_solution[$coord]."\033[0m");
+ ConsoleCursor::restore();
+ ConsoleCursor::show();
+
+ return;
+ };
+ $select = function () use (
+ &$mColumn,
+ &$mLine,
+ &$coord,
+ &$_solution,
+ &$cWidth,
+ $output
+ ) {
+ ConsoleCursor::save();
+ ConsoleCursor::hide();
+ ConsoleCursor::move('↓ LEFT');
+ ConsoleCursor::move('→', $mColumn * ($cWidth + 2));
+ ConsoleCursor::move('↓', $mLine);
+ $output->writeAll("\033[7m".$_solution[$coord]."\033[0m");
+ ConsoleCursor::restore();
+ ConsoleCursor::show();
+
+ return;
+ };
+ $init = function () use (
+ &$mColumn,
+ &$mLine,
+ &$coord,
+ &$select
+ ) {
+ $mColumn = 0;
+ $mLine = 0;
+ $coord = 0;
+ $select();
+
+ return;
+ };
+
+ while (true) {
+ @\stream_select($read, $write, $except, 30, 0);
+
+ if (empty($read)) {
+ $read = [$input->getStream()->getStream()];
+
+ continue;
+ }
+
+ switch ($char = $self->_read()) {
+ case "\033[A":
+ if (-1 === $mColumn && -1 === $mLine) {
+ $init();
+
+ break;
+ }
+
+ $unselect();
+ $coord = \max(0, $coord - $mColumns);
+ $mLine = (int) \floor($coord / $mColumns);
+ $mColumn = $coord % $mColumns;
+ $select();
+
+ break;
+
+ case "\033[B":
+ if (-1 === $mColumn && -1 === $mLine) {
+ $init();
+
+ break;
+ }
+
+ $unselect();
+ $coord = \min($count, $coord + $mColumns);
+ $mLine = (int) \floor($coord / $mColumns);
+ $mColumn = $coord % $mColumns;
+ $select();
+
+ break;
+
+ case "\t":
+ case "\033[C":
+ if (-1 === $mColumn && -1 === $mLine) {
+ $init();
+
+ break;
+ }
+
+ $unselect();
+ $coord = \min($count, $coord + 1);
+ $mLine = (int) \floor($coord / $mColumns);
+ $mColumn = $coord % $mColumns;
+ $select();
+
+ break;
+
+ case "\033[D":
+ if (-1 === $mColumn && -1 === $mLine) {
+ $init();
+
+ break;
+ }
+
+ $unselect();
+ $coord = \max(0, $coord - 1);
+ $mLine = (int) \floor($coord / $mColumns);
+ $mColumn = $coord % $mColumns;
+ $select();
+
+ break;
+
+ case "\n":
+ if (-1 !== $mColumn && -1 !== $mLine) {
+ $tail = \mb_substr($line, $current);
+ $current -= $length;
+ $self->setLine(
+ \mb_substr($line, 0, $current).
+ $solution[$coord].
+ $tail
+ );
+ $self->setLineCurrent(
+ $current + \mb_strlen($solution[$coord])
+ );
+
+ ConsoleCursor::move('←', $length);
+ $output->writeAll($solution[$coord]);
+ ConsoleCursor::clear('→');
+ $output->writeAll($tail);
+ ConsoleCursor::move('←', \mb_strlen($tail));
+ }
+
+ // no break
+ default:
+ $mColumn = -1;
+ $mLine = -1;
+ $coord = -1;
+ ConsoleCursor::save();
+ ConsoleCursor::move('↓ LEFT');
+ ConsoleCursor::clear('↓');
+ ConsoleCursor::restore();
+
+ if ("\033" !== $char && "\n" !== $char) {
+ $self->setBuffer($char);
+
+ return $self->_readLine($char);
+ }
+
+ break 2;
+ }
+ }
+
+ return $state;
+ }
+
+ $tail = \mb_substr($line, $current);
+ $current -= $length;
+ $self->setLine(
+ \mb_substr($line, 0, $current).
+ $solution.
+ $tail
+ );
+ $self->setLineCurrent(
+ $current + \mb_strlen($solution)
+ );
+
+ ConsoleCursor::move('←', $length);
+ $output->writeAll($solution);
+ ConsoleCursor::clear('→');
+ $output->writeAll($tail);
+ ConsoleCursor::move('←', \mb_strlen($tail));
+
+ return $state;
+ }
+}
+
+/*
+ * Advanced interaction.
+ */
+Console::advancedInteraction();
diff --git a/vendor/psy/psysh/src/Readline/Hoa/Stream.php b/vendor/psy/psysh/src/Readline/Hoa/Stream.php
new file mode 100644
index 000000000..62e56ce3f
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/Stream.php
@@ -0,0 +1,571 @@
+_open()` method. Please, see the `self::_getStream()` method.
+ */
+ public function __construct(string $streamName, string $context = null, bool $wait = false)
+ {
+ $this->_streamName = $streamName;
+ $this->_context = $context;
+ $this->_hasBeenDeferred = $wait;
+ $this->setListener(
+ new EventListener(
+ $this,
+ [
+ 'authrequire',
+ 'authresult',
+ 'complete',
+ 'connect',
+ 'failure',
+ 'mimetype',
+ 'progress',
+ 'redirect',
+ 'resolve',
+ 'size',
+ ]
+ )
+ );
+
+ if (true === $wait) {
+ return;
+ }
+
+ $this->open();
+
+ return;
+ }
+
+ /**
+ * Get a stream in the register.
+ * If the stream does not exist, try to open it by calling the
+ * $handler->_open() method.
+ */
+ private static function &_getStream(
+ string $streamName,
+ self $handler,
+ string $context = null
+ ): array {
+ $name = \md5($streamName);
+
+ if (null !== $context) {
+ if (false === StreamContext::contextExists($context)) {
+ throw new StreamException('Context %s was not previously declared, cannot retrieve '.'this context.', 0, $context);
+ }
+
+ $context = StreamContext::getInstance($context);
+ }
+
+ if (!isset(self::$_register[$name])) {
+ self::$_register[$name] = [
+ self::NAME => $streamName,
+ self::HANDLER => $handler,
+ self::RESOURCE => $handler->_open($streamName, $context),
+ self::CONTEXT => $context,
+ ];
+ Event::register(
+ 'hoa://Event/Stream/'.$streamName,
+ $handler
+ );
+ // Add :open-ready?
+ Event::register(
+ 'hoa://Event/Stream/'.$streamName.':close-before',
+ $handler
+ );
+ } else {
+ $handler->_borrowing = true;
+ }
+
+ if (null === self::$_register[$name][self::RESOURCE]) {
+ self::$_register[$name][self::RESOURCE]
+ = $handler->_open($streamName, $context);
+ }
+
+ return self::$_register[$name];
+ }
+
+ /**
+ * Open the stream and return the associated resource.
+ * Note: This method is protected, but do not forget that it could be
+ * overloaded into a public context.
+ */
+ abstract protected function &_open(string $streamName, StreamContext $context = null);
+
+ /**
+ * Close the current stream.
+ * Note: this method is protected, but do not forget that it could be
+ * overloaded into a public context.
+ */
+ abstract protected function _close(): bool;
+
+ /**
+ * Open the stream.
+ */
+ final public function open(): self
+ {
+ $context = $this->_context;
+
+ if (true === $this->hasBeenDeferred()) {
+ if (null === $context) {
+ $handle = StreamContext::getInstance(\uniqid());
+ $handle->setParameters([
+ 'notification' => [$this, '_notify'],
+ ]);
+ $context = $handle->getId();
+ } elseif (true === StreamContext::contextExists($context)) {
+ $handle = StreamContext::getInstance($context);
+ $parameters = $handle->getParameters();
+
+ if (!isset($parameters['notification'])) {
+ $handle->setParameters([
+ 'notification' => [$this, '_notify'],
+ ]);
+ }
+ }
+ }
+
+ $this->_bufferSize = self::DEFAULT_BUFFER_SIZE;
+ $this->_bucket = self::_getStream(
+ $this->_streamName,
+ $this,
+ $context
+ );
+
+ return $this;
+ }
+
+ /**
+ * Close the current stream.
+ */
+ final public function close()
+ {
+ $streamName = $this->getStreamName();
+
+ if (null === $streamName) {
+ return;
+ }
+
+ $name = \md5($streamName);
+
+ if (!isset(self::$_register[$name])) {
+ return;
+ }
+
+ Event::notify(
+ 'hoa://Event/Stream/'.$streamName.':close-before',
+ $this,
+ new EventBucket()
+ );
+
+ if (false === $this->_close()) {
+ return;
+ }
+
+ unset(self::$_register[$name]);
+ $this->_bucket[self::HANDLER] = null;
+ Event::unregister(
+ 'hoa://Event/Stream/'.$streamName
+ );
+ Event::unregister(
+ 'hoa://Event/Stream/'.$streamName.':close-before'
+ );
+
+ return;
+ }
+
+ /**
+ * Get the current stream name.
+ */
+ public function getStreamName()
+ {
+ if (empty($this->_bucket)) {
+ return null;
+ }
+
+ return $this->_bucket[self::NAME];
+ }
+
+ /**
+ * Get the current stream.
+ */
+ public function getStream()
+ {
+ if (empty($this->_bucket)) {
+ return null;
+ }
+
+ return $this->_bucket[self::RESOURCE];
+ }
+
+ /**
+ * Get the current stream context.
+ */
+ public function getStreamContext()
+ {
+ if (empty($this->_bucket)) {
+ return null;
+ }
+
+ return $this->_bucket[self::CONTEXT];
+ }
+
+ /**
+ * Get stream handler according to its name.
+ */
+ public static function getStreamHandler(string $streamName)
+ {
+ $name = \md5($streamName);
+
+ if (!isset(self::$_register[$name])) {
+ return null;
+ }
+
+ return self::$_register[$name][self::HANDLER];
+ }
+
+ /**
+ * Set the current stream. Useful to manage a stack of streams (e.g. socket
+ * and select). Notice that it could be unsafe to use this method without
+ * taking time to think about it two minutes. Resource of type “Unknown” is
+ * considered as valid.
+ */
+ public function _setStream($stream)
+ {
+ if (false === \is_resource($stream) &&
+ ('resource' !== \gettype($stream) ||
+ 'Unknown' !== \get_resource_type($stream))) {
+ throw new StreamException('Try to change the stream resource with an invalid one; '.'given %s.', 1, \gettype($stream));
+ }
+
+ $old = $this->_bucket[self::RESOURCE];
+ $this->_bucket[self::RESOURCE] = $stream;
+
+ return $old;
+ }
+
+ /**
+ * Check if the stream is opened.
+ */
+ public function isOpened(): bool
+ {
+ return \is_resource($this->getStream());
+ }
+
+ /**
+ * Set the timeout period.
+ */
+ public function setStreamTimeout(int $seconds, int $microseconds = 0): bool
+ {
+ return \stream_set_timeout($this->getStream(), $seconds, $microseconds);
+ }
+
+ /**
+ * Whether the opening of the stream has been deferred.
+ */
+ protected function hasBeenDeferred()
+ {
+ return $this->_hasBeenDeferred;
+ }
+
+ /**
+ * Check whether the connection has timed out or not.
+ * This is basically a shortcut of `getStreamMetaData` + the `timed_out`
+ * index, but the resulting code is more readable.
+ */
+ public function hasTimedOut(): bool
+ {
+ $metaData = $this->getStreamMetaData();
+
+ return true === $metaData['timed_out'];
+ }
+
+ /**
+ * Set blocking/non-blocking mode.
+ */
+ public function setStreamBlocking(bool $mode): bool
+ {
+ return \stream_set_blocking($this->getStream(), $mode);
+ }
+
+ /**
+ * Set stream buffer.
+ * Output using fwrite() (or similar function) is normally buffered at 8 Ko.
+ * This means that if there are two processes wanting to write to the same
+ * output stream, each is paused after 8 Ko of data to allow the other to
+ * write.
+ */
+ public function setStreamBuffer(int $buffer): bool
+ {
+ // Zero means success.
+ $out = 0 === \stream_set_write_buffer($this->getStream(), $buffer);
+
+ if (true === $out) {
+ $this->_bufferSize = $buffer;
+ }
+
+ return $out;
+ }
+
+ /**
+ * Disable stream buffering.
+ * Alias of $this->setBuffer(0).
+ */
+ public function disableStreamBuffer(): bool
+ {
+ return $this->setStreamBuffer(0);
+ }
+
+ /**
+ * Get stream buffer size.
+ */
+ public function getStreamBufferSize(): int
+ {
+ return $this->_bufferSize;
+ }
+
+ /**
+ * Get stream wrapper name.
+ */
+ public function getStreamWrapperName(): string
+ {
+ if (false === $pos = \strpos($this->getStreamName(), '://')) {
+ return 'file';
+ }
+
+ return \substr($this->getStreamName(), 0, $pos);
+ }
+
+ /**
+ * Get stream meta data.
+ */
+ public function getStreamMetaData(): array
+ {
+ return \stream_get_meta_data($this->getStream());
+ }
+
+ /**
+ * Whether this stream is already opened by another handler.
+ */
+ public function isBorrowing(): bool
+ {
+ return $this->_borrowing;
+ }
+
+ /**
+ * Notification callback.
+ */
+ public function _notify(
+ int $ncode,
+ int $severity,
+ $message,
+ $code,
+ $transferred,
+ $max
+ ) {
+ static $_map = [
+ \STREAM_NOTIFY_AUTH_REQUIRED => 'authrequire',
+ \STREAM_NOTIFY_AUTH_RESULT => 'authresult',
+ \STREAM_NOTIFY_COMPLETED => 'complete',
+ \STREAM_NOTIFY_CONNECT => 'connect',
+ \STREAM_NOTIFY_FAILURE => 'failure',
+ \STREAM_NOTIFY_MIME_TYPE_IS => 'mimetype',
+ \STREAM_NOTIFY_PROGRESS => 'progress',
+ \STREAM_NOTIFY_REDIRECTED => 'redirect',
+ \STREAM_NOTIFY_RESOLVE => 'resolve',
+ \STREAM_NOTIFY_FILE_SIZE_IS => 'size',
+ ];
+
+ $this->getListener()->fire($_map[$ncode], new EventBucket([
+ 'code' => $code,
+ 'severity' => $severity,
+ 'message' => $message,
+ 'transferred' => $transferred,
+ 'max' => $max,
+ ]));
+ }
+
+ /**
+ * Call the $handler->close() method on each stream in the static stream
+ * register.
+ * This method does not check the return value of $handler->close(). Thus,
+ * if a stream is persistent, the $handler->close() should do anything. It
+ * is a very generic method.
+ */
+ final public static function _Hoa_Stream()
+ {
+ foreach (self::$_register as $entry) {
+ $entry[self::HANDLER]->close();
+ }
+
+ return;
+ }
+
+ /**
+ * Transform object to string.
+ */
+ public function __toString(): string
+ {
+ return $this->getStreamName();
+ }
+
+ /**
+ * Close the stream when destructing.
+ */
+ public function __destruct()
+ {
+ if (false === $this->isOpened()) {
+ return;
+ }
+
+ $this->close();
+
+ return;
+ }
+}
+
+/**
+ * Class \Hoa\Stream\_Protocol.
+ *
+ * The `hoa://Library/Stream` node.
+ *
+ * @license New BSD License
+ */
+class _Protocol extends ProtocolNode
+{
+ /**
+ * Component's name.
+ *
+ * @var string
+ */
+ protected $_name = 'Stream';
+
+ /**
+ * ID of the component.
+ *
+ * @param string $id ID of the component
+ *
+ * @return mixed
+ */
+ public function reachId(string $id)
+ {
+ return Stream::getStreamHandler($id);
+ }
+}
+
+/*
+ * Shutdown method.
+ */
+\register_shutdown_function([Stream::class, '_Hoa_Stream']);
+
+/**
+ * Add the `hoa://Library/Stream` node. Should be use to reach/get an entry
+ * in the stream register.
+ */
+$protocol = Protocol::getInstance();
+$protocol['Library'][] = new _Protocol();
diff --git a/vendor/psy/psysh/src/Readline/Hoa/StreamBufferable.php b/vendor/psy/psysh/src/Readline/Hoa/StreamBufferable.php
new file mode 100644
index 000000000..e431021a8
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/StreamBufferable.php
@@ -0,0 +1,73 @@
+_id = $id;
+ $this->_context = \stream_context_create();
+
+ return;
+ }
+
+ /**
+ * Multiton.
+ */
+ public static function getInstance(string $id): self
+ {
+ if (false === static::contextExists($id)) {
+ static::$_instances[$id] = new self($id);
+ }
+
+ return static::$_instances[$id];
+ }
+
+ /**
+ * Get context ID.
+ */
+ public function getId(): string
+ {
+ return $this->_id;
+ }
+
+ /**
+ * Check if a context exists.
+ */
+ public static function contextExists(string $id): bool
+ {
+ return \array_key_exists($id, static::$_instances);
+ }
+
+ /**
+ * Set options.
+ * Please, see http://php.net/context.
+ */
+ public function setOptions(array $options): bool
+ {
+ return \stream_context_set_option($this->getContext(), $options);
+ }
+
+ /**
+ * Set parameters.
+ * Please, see http://php.net/context.params.
+ */
+ public function setParameters(array $parameters): bool
+ {
+ return \stream_context_set_params($this->getContext(), $parameters);
+ }
+
+ /**
+ * Get options.
+ */
+ public function getOptions(): array
+ {
+ return \stream_context_get_options($this->getContext());
+ }
+
+ /**
+ * Get parameters.
+ */
+ public function getParameters(): array
+ {
+ return \stream_context_get_params($this->getContext());
+ }
+
+ /**
+ * Get context as a resource.
+ */
+ public function getContext()
+ {
+ return $this->_context;
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/StreamException.php b/vendor/psy/psysh/src/Readline/Hoa/StreamException.php
new file mode 100644
index 000000000..21da03cfb
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/StreamException.php
@@ -0,0 +1,46 @@
+read().
+ */
+ public function readString(int $length);
+
+ /**
+ * Read a character.
+ * It could be equivalent to $this->read(1).
+ */
+ public function readCharacter();
+
+ /**
+ * Read a boolean.
+ */
+ public function readBoolean();
+
+ /**
+ * Read an integer.
+ */
+ public function readInteger(int $length = 1);
+
+ /**
+ * Read a float.
+ */
+ public function readFloat(int $length = 1);
+
+ /**
+ * Read an array.
+ * In most cases, it could be an alias to the $this->scanf() method.
+ */
+ public function readArray();
+
+ /**
+ * Read a line.
+ */
+ public function readLine();
+
+ /**
+ * Read all, i.e. read as much as possible.
+ */
+ public function readAll(int $offset = 0);
+
+ /**
+ * Parse input from a stream according to a format.
+ */
+ public function scanf(string $format): array;
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/StreamLockable.php b/vendor/psy/psysh/src/Readline/Hoa/StreamLockable.php
new file mode 100644
index 000000000..c19c4dba0
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/StreamLockable.php
@@ -0,0 +1,85 @@
+lock() to block while locking.
+ *
+ * @const int
+ */
+ const LOCK_NO_BLOCK = \LOCK_NB;
+
+ /**
+ * Portable advisory locking.
+ * Should take a look at stream_supports_lock().
+ *
+ * @param int $operation operation, use the self::LOCK_* constants
+ *
+ * @return bool
+ */
+ public function lock(int $operation): bool;
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/StreamOut.php b/vendor/psy/psysh/src/Readline/Hoa/StreamOut.php
new file mode 100644
index 000000000..e4bb925e1
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/StreamOut.php
@@ -0,0 +1,95 @@
+ $c || (0x7F <= $c && $c < 0xA0)) {
+ return -1;
+ }
+
+ // Non-spacing characters.
+ if (0xAD !== $c &&
+ 0 !== \preg_match('#^[\p{Mn}\p{Me}\p{Cf}\x{1160}-\x{11ff}\x{200b}]#u', $char)) {
+ return 0;
+ }
+
+ // If we arrive here, $c is not a combining C0/C1 control character.
+ return 1 +
+ (0x1100 <= $c &&
+ (0x115F >= $c || // Hangul Jamo init. consonants
+ 0x2329 === $c || 0x232A === $c ||
+ (0x2E80 <= $c && 0xA4CF >= $c &&
+ 0x303F !== $c) || // CJK…Yi
+ (0xAC00 <= $c && 0xD7A3 >= $c) || // Hangul Syllables
+ (0xF900 <= $c && 0xFAFF >= $c) || // CJK Compatibility Ideographs
+ (0xFE10 <= $c && 0xFE19 >= $c) || // Vertical forms
+ (0xFE30 <= $c && 0xFE6F >= $c) || // CJK Compatibility Forms
+ (0xFF00 <= $c && 0xFF60 >= $c) || // Fullwidth Forms
+ (0xFFE0 <= $c && 0xFFE6 >= $c) ||
+ (0x20000 <= $c && 0x2FFFD >= $c) ||
+ (0x30000 <= $c && 0x3FFFD >= $c)));
+ }
+
+ /**
+ * Check whether the character is printable or not.
+ */
+ public static function isCharPrintable(string $char): bool
+ {
+ return 1 <= static::getCharWidth($char);
+ }
+
+ /**
+ * Get a decimal code representation of a specific character.
+ */
+ public static function toCode(string $char): int
+ {
+ $char = (string) $char;
+ $code = \ord($char[0]);
+ $bytes = 1;
+
+ if (!($code & 0x80)) { // 0xxxxxxx
+ return $code;
+ }
+
+ if (($code & 0xE0) === 0xC0) { // 110xxxxx
+ $bytes = 2;
+ $code = $code & ~0xC0;
+ } elseif (($code & 0xF0) === 0xE0) { // 1110xxxx
+ $bytes = 3;
+ $code = $code & ~0xE0;
+ } elseif (($code & 0xF8) === 0xF0) { // 11110xxx
+ $bytes = 4;
+ $code = $code & ~0xF0;
+ }
+
+ for ($i = 2; $i <= $bytes; $i++) { // 10xxxxxx
+ $code = ($code << 6) + (\ord($char[$i - 1]) & ~0x80);
+ }
+
+ return $code;
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/Hoa/Xcallable.php b/vendor/psy/psysh/src/Readline/Hoa/Xcallable.php
new file mode 100644
index 000000000..e1160a556
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Hoa/Xcallable.php
@@ -0,0 +1,256 @@
+method` or
+ * closure. They all have the same behaviour. This callable is an extension of
+ * native PHP callable (aka callback) to integrate Hoa's structures.
+ */
+class Xcallable
+{
+ /**
+ * Callback with the PHP format.
+ */
+ protected $_callback = null;
+
+ /**
+ * Callable hash.
+ */
+ protected $_hash = null;
+
+ /**
+ * Allocates a xcallable based on a callback.
+ *
+ * Accepted forms:
+ * * `'function'`,
+ * * `'class::method'`,
+ * * `'class', 'method'`,
+ * * `$object, 'method'`,
+ * * `$object, ''`,
+ * * `function (…) { … }`,
+ * * `['class', 'method']`,
+ * * `[$object, 'method']`.
+ *
+ * # Examples
+ *
+ * ```php
+ * $toUpper = new Hoa\Consistency\Xcallable('strtoupper');
+ * assert('FOO' === $toUpper('foo'));
+ * ```
+ *
+ * # Exceptions
+ *
+ * A `Hoa\Consistency\Exception` exception is thrown if the callback form
+ * is invalid.
+ *
+ * ```php,must_throw(Hoa\Consistency\Exception)
+ * new Hoa\Consistency\Xcallable('Foo:');
+ * ```
+ */
+ public function __construct($call, $able = '')
+ {
+ if ($call instanceof \Closure) {
+ $this->_callback = $call;
+
+ return;
+ }
+
+ if (!\is_string($able)) {
+ throw new Exception('Bad callback form; the able part must be a string.', 0);
+ }
+
+ if ('' === $able) {
+ if (\is_string($call)) {
+ if (false === \strpos($call, '::')) {
+ if (!\function_exists($call)) {
+ throw new Exception('Bad callback form; function %s does not exist.', 1, $call);
+ }
+
+ $this->_callback = $call;
+
+ return;
+ }
+
+ list($call, $able) = \explode('::', $call);
+ } elseif (\is_object($call)) {
+ if ($call instanceof StreamOut) {
+ $able = null;
+ } elseif (\method_exists($call, '__invoke')) {
+ $able = '__invoke';
+ } else {
+ throw new Exception('Bad callback form; an object but without a known '.'method.', 2);
+ }
+ } elseif (\is_array($call) && isset($call[0])) {
+ if (!isset($call[1])) {
+ $this->__construct($call[0]);
+ return;
+ }
+
+ $this->__construct($call[0], $call[1]);
+ return;
+ } else {
+ throw new Exception('Bad callback form.', 3);
+ }
+ }
+
+ $this->_callback = [$call, $able];
+
+ return;
+ }
+
+ /**
+ * Calls the callable.
+ */
+ public function __invoke(...$arguments)
+ {
+ $callback = $this->getValidCallback($arguments);
+
+ return $callback(...$arguments);
+ }
+
+ /**
+ * Returns a valid PHP callback.
+ */
+ public function getValidCallback(array &$arguments = [])
+ {
+ $callback = $this->_callback;
+ $head = null;
+
+ if (isset($arguments[0])) {
+ $head = &$arguments[0];
+ }
+
+ // If method is undetermined, we find it (we understand event bucket and
+ // stream).
+ if (null !== $head &&
+ \is_array($callback) &&
+ null === $callback[1]) {
+ if ($head instanceof EventBucket) {
+ $head = $head->getData();
+ }
+
+ switch ($type = \gettype($head)) {
+ case 'string':
+ if (1 === \strlen($head)) {
+ $method = 'writeCharacter';
+ } else {
+ $method = 'writeString';
+ }
+
+ break;
+
+ case 'boolean':
+ case 'integer':
+ case 'array':
+ $method = 'write'.\ucfirst($type);
+
+ break;
+
+ case 'double':
+ $method = 'writeFloat';
+
+ break;
+
+ default:
+ $method = 'writeAll';
+ $head = $head."\n";
+ }
+
+ $callback[1] = $method;
+ }
+
+ return $callback;
+ }
+
+ /**
+ * Computes the hash of this callable.
+ *
+ * Will produce:
+ * * `function#…`,
+ * * `class#…::…`,
+ * * `object(…)#…::…`,
+ * * `closure(…)`.
+ */
+ public function getHash(): string
+ {
+ if (null !== $this->_hash) {
+ return $this->_hash;
+ }
+
+ $_ = &$this->_callback;
+
+ if (\is_string($_)) {
+ return $this->_hash = 'function#'.$_;
+ }
+
+ if (\is_array($_)) {
+ return
+ $this->_hash =
+ (\is_object($_[0])
+ ? 'object('.\spl_object_hash($_[0]).')'.
+ '#'.\get_class($_[0])
+ : 'class#'.$_[0]).
+ '::'.
+ (null !== $_[1]
+ ? $_[1]
+ : '???');
+ }
+
+ return $this->_hash = 'closure('.\spl_object_hash($_).')';
+ }
+
+ /**
+ * The string representation of a callable is its hash.
+ */
+ public function __toString(): string
+ {
+ return $this->getHash();
+ }
+
+ /**
+ * Hoa's xcallable() helper.
+ */
+ public static function from($call, $able = '')
+ {
+ if ($call instanceof self) {
+ return $call;
+ }
+
+ return new self($call, $able);
+ }
+}
diff --git a/vendor/psy/psysh/src/Readline/HoaConsole.php b/vendor/psy/psysh/src/Readline/HoaConsole.php
index bd4d9d541..74febb6f7 100644
--- a/vendor/psy/psysh/src/Readline/HoaConsole.php
+++ b/vendor/psy/psysh/src/Readline/HoaConsole.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -11,111 +11,11 @@
namespace Psy\Readline;
-use Hoa\Console\Console;
-use Hoa\Console\Cursor;
-use Hoa\Console\Readline\Readline as HoaReadline;
-use Psy\Exception\BreakException;
-
/**
* Hoa\Console Readline implementation.
+ *
+ * @deprecated, use Userland readline
*/
-class HoaConsole implements Readline
+class HoaConsole extends Userland
{
- /** @var HoaReadline */
- private $hoaReadline;
-
- /** @var string|null */
- private $lastPrompt;
-
- /**
- * @return bool
- */
- public static function isSupported()
- {
- return \class_exists(Console::class, true);
- }
-
- public function __construct()
- {
- $this->hoaReadline = new HoaReadline();
- $this->hoaReadline->addMapping('\C-l', function () {
- $this->redisplay();
-
- return HoaReadline::STATE_NO_ECHO;
- });
- }
-
- /**
- * {@inheritdoc}
- */
- public function addHistory($line)
- {
- $this->hoaReadline->addHistory($line);
-
- return true;
- }
-
- /**
- * {@inheritdoc}
- */
- public function clearHistory()
- {
- $this->hoaReadline->clearHistory();
-
- return true;
- }
-
- /**
- * {@inheritdoc}
- */
- public function listHistory()
- {
- $i = 0;
- $list = [];
- while (($item = $this->hoaReadline->getHistory($i++)) !== null) {
- $list[] = $item;
- }
-
- return $list;
- }
-
- /**
- * {@inheritdoc}
- */
- public function readHistory()
- {
- return true;
- }
-
- /**
- * {@inheritdoc}
- *
- * @throws BreakException if user hits Ctrl+D
- *
- * @return string
- */
- public function readline($prompt = null)
- {
- $this->lastPrompt = $prompt;
-
- return $this->hoaReadline->readLine($prompt);
- }
-
- /**
- * {@inheritdoc}
- */
- public function redisplay()
- {
- $currentLine = $this->hoaReadline->getLine();
- Cursor::clear('all');
- echo $this->lastPrompt, $currentLine;
- }
-
- /**
- * {@inheritdoc}
- */
- public function writeHistory()
- {
- return true;
- }
}
diff --git a/vendor/psy/psysh/src/Readline/Libedit.php b/vendor/psy/psysh/src/Readline/Libedit.php
index 6c788d901..953ed2afd 100644
--- a/vendor/psy/psysh/src/Readline/Libedit.php
+++ b/vendor/psy/psysh/src/Readline/Libedit.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -29,10 +29,8 @@ class Libedit extends GNUReadline
/**
* Let's emulate GNU Readline by manually reading and parsing the history file!
- *
- * @return bool
*/
- public static function isSupported()
+ public static function isSupported(): bool
{
return \function_exists('readline') && !\function_exists('readline_list_history');
}
@@ -40,7 +38,15 @@ class Libedit extends GNUReadline
/**
* {@inheritdoc}
*/
- public function listHistory()
+ public static function supportsBracketedPaste(): bool
+ {
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function listHistory(): array
{
$history = \file_get_contents($this->historyFile);
if (!$history) {
@@ -64,7 +70,7 @@ class Libedit extends GNUReadline
/**
* {@inheritdoc}
*/
- public function writeHistory()
+ public function writeHistory(): bool
{
$res = parent::writeHistory();
@@ -93,7 +99,7 @@ class Libedit extends GNUReadline
*
* @return string|null
*/
- protected function parseHistoryLine($line)
+ protected function parseHistoryLine(string $line)
{
// empty line, comment or timestamp
if (!$line || $line[0] === "\0") {
diff --git a/vendor/psy/psysh/src/Readline/Readline.php b/vendor/psy/psysh/src/Readline/Readline.php
index 7e404dccc..e9b45b3c7 100644
--- a/vendor/psy/psysh/src/Readline/Readline.php
+++ b/vendor/psy/psysh/src/Readline/Readline.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -17,11 +17,21 @@ namespace Psy\Readline;
interface Readline
{
/**
- * Check whether this Readline class is supported by the current system.
- *
- * @return bool
+ * @param string|false $historyFile
+ * @param int|null $historySize
+ * @param bool|null $eraseDups
*/
- public static function isSupported();
+ public function __construct($historyFile = null, $historySize = 0, $eraseDups = false);
+
+ /**
+ * Check whether this Readline class is supported by the current system.
+ */
+ public static function isSupported(): bool;
+
+ /**
+ * Check whether this Readline class supports bracketed paste.
+ */
+ public static function supportsBracketedPaste(): bool;
/**
* Add a line to the command history.
@@ -30,28 +40,28 @@ interface Readline
*
* @return bool Success
*/
- public function addHistory($line);
+ public function addHistory(string $line): bool;
/**
* Clear the command history.
*
* @return bool Success
*/
- public function clearHistory();
+ public function clearHistory(): bool;
/**
* List the command history.
*
- * @return array
+ * @return string[]
*/
- public function listHistory();
+ public function listHistory(): array;
/**
* Read the command history.
*
* @return bool Success
*/
- public function readHistory();
+ public function readHistory(): bool;
/**
* Read a single line of input from the user.
@@ -60,7 +70,7 @@ interface Readline
*
* @return false|string
*/
- public function readline($prompt = null);
+ public function readline(string $prompt = null);
/**
* Redraw readline to redraw the display.
@@ -72,5 +82,5 @@ interface Readline
*
* @return bool Success
*/
- public function writeHistory();
+ public function writeHistory(): bool;
}
diff --git a/vendor/psy/psysh/src/Readline/Transient.php b/vendor/psy/psysh/src/Readline/Transient.php
index 884354dbd..43eb28519 100644
--- a/vendor/psy/psysh/src/Readline/Transient.php
+++ b/vendor/psy/psysh/src/Readline/Transient.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -28,11 +28,19 @@ class Transient implements Readline
*
* {@inheritdoc}
*/
- public static function isSupported()
+ public static function isSupported(): bool
{
return true;
}
+ /**
+ * {@inheritdoc}
+ */
+ public static function supportsBracketedPaste(): bool
+ {
+ return false;
+ }
+
/**
* Transient Readline constructor.
*/
@@ -47,7 +55,7 @@ class Transient implements Readline
/**
* {@inheritdoc}
*/
- public function addHistory($line)
+ public function addHistory(string $line): bool
{
if ($this->eraseDups) {
if (($key = \array_search($line, $this->history)) !== false) {
@@ -72,7 +80,7 @@ class Transient implements Readline
/**
* {@inheritdoc}
*/
- public function clearHistory()
+ public function clearHistory(): bool
{
$this->history = [];
@@ -82,7 +90,7 @@ class Transient implements Readline
/**
* {@inheritdoc}
*/
- public function listHistory()
+ public function listHistory(): array
{
return $this->history;
}
@@ -90,7 +98,7 @@ class Transient implements Readline
/**
* {@inheritdoc}
*/
- public function readHistory()
+ public function readHistory(): bool
{
return true;
}
@@ -100,9 +108,9 @@ class Transient implements Readline
*
* @throws BreakException if user hits Ctrl+D
*
- * @return string
+ * @return false|string
*/
- public function readline($prompt = null)
+ public function readline(string $prompt = null)
{
echo $prompt;
@@ -120,7 +128,7 @@ class Transient implements Readline
/**
* {@inheritdoc}
*/
- public function writeHistory()
+ public function writeHistory(): bool
{
return true;
}
diff --git a/vendor/psy/psysh/src/Readline/Userland.php b/vendor/psy/psysh/src/Readline/Userland.php
new file mode 100644
index 000000000..62018b770
--- /dev/null
+++ b/vendor/psy/psysh/src/Readline/Userland.php
@@ -0,0 +1,165 @@
+hoaReadline = new HoaReadline();
+ $this->hoaReadline->addMapping('\C-l', function () {
+ $this->redisplay();
+
+ return HoaReadline::STATE_NO_ECHO;
+ });
+
+ $this->tput = new HoaConsoleTput();
+ HoaConsole::setTput($this->tput);
+
+ $this->input = new HoaConsoleInput();
+ HoaConsole::setInput($this->input);
+
+ $this->output = new HoaConsoleOutput();
+ HoaConsole::setOutput($this->output);
+ }
+
+ /**
+ * Bootstrap some things that Hoa used to do itself.
+ */
+ public static function bootstrapHoa(bool $withTerminalResize = false)
+ {
+ // A side effect registers hoa:// stream wrapper
+ \class_exists('Psy\Readline\Hoa\ProtocolWrapper');
+
+ // A side effect registers hoa://Library/Stream
+ \class_exists('Psy\Readline\Hoa\Stream');
+
+ // A side effect binds terminal resize
+ $withTerminalResize && \class_exists('Psy\Readline\Hoa\ConsoleWindow');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addHistory(string $line): bool
+ {
+ $this->hoaReadline->addHistory($line);
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clearHistory(): bool
+ {
+ $this->hoaReadline->clearHistory();
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function listHistory(): array
+ {
+ $i = 0;
+ $list = [];
+ while (($item = $this->hoaReadline->getHistory($i++)) !== null) {
+ $list[] = $item;
+ }
+
+ return $list;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function readHistory(): bool
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @throws BreakException if user hits Ctrl+D
+ *
+ * @return string
+ */
+ public function readline(string $prompt = null)
+ {
+ $this->lastPrompt = $prompt;
+
+ return $this->hoaReadline->readLine($prompt);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function redisplay()
+ {
+ $currentLine = $this->hoaReadline->getLine();
+ HoaConsoleCursor::clear('all');
+ echo $this->lastPrompt, $currentLine;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function writeHistory(): bool
+ {
+ return true;
+ }
+}
diff --git a/vendor/psy/psysh/src/Reflection/ReflectionClassConstant.php b/vendor/psy/psysh/src/Reflection/ReflectionClassConstant.php
index 527308dfd..1d6999c9b 100644
--- a/vendor/psy/psysh/src/Reflection/ReflectionClassConstant.php
+++ b/vendor/psy/psysh/src/Reflection/ReflectionClassConstant.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -28,7 +28,7 @@ class ReflectionClassConstant implements \Reflector
* @param string|object $class
* @param string $name
*/
- public function __construct($class, $name)
+ public function __construct($class, string $name)
{
if (!$class instanceof \ReflectionClass) {
$class = new \ReflectionClass($class);
@@ -54,7 +54,7 @@ class ReflectionClassConstant implements \Reflector
*
* @return string|null
*/
- public static function export($class, $name, $return = false)
+ public static function export($class, string $name, bool $return = false)
{
$refl = new self($class, $name);
$value = $refl->getValue();
@@ -70,10 +70,8 @@ class ReflectionClassConstant implements \Reflector
/**
* Gets the declaring class.
- *
- * @return \ReflectionClass
*/
- public function getDeclaringClass()
+ public function getDeclaringClass(): \ReflectionClass
{
$parent = $this->class;
@@ -95,7 +93,7 @@ class ReflectionClassConstant implements \Reflector
*
* @return false
*/
- public function getDocComment()
+ public function getDocComment(): bool
{
return false;
}
@@ -106,20 +104,16 @@ class ReflectionClassConstant implements \Reflector
* Since this is only used for PHP < 7.1, we can just return "public". All
* the fancier modifiers are only available on PHP versions which have their
* own ReflectionClassConstant class :)
- *
- * @return int
*/
- public function getModifiers()
+ public function getModifiers(): int
{
return \ReflectionMethod::IS_PUBLIC;
}
/**
* Gets the constant name.
- *
- * @return string
*/
- public function getName()
+ public function getName(): string
{
return $this->name;
}
@@ -139,7 +133,7 @@ class ReflectionClassConstant implements \Reflector
*
* @return bool false
*/
- public function isPrivate()
+ public function isPrivate(): bool
{
return false;
}
@@ -149,7 +143,7 @@ class ReflectionClassConstant implements \Reflector
*
* @return bool false
*/
- public function isProtected()
+ public function isProtected(): bool
{
return false;
}
@@ -159,17 +153,15 @@ class ReflectionClassConstant implements \Reflector
*
* @return bool true
*/
- public function isPublic()
+ public function isPublic(): bool
{
return true;
}
/**
* To string.
- *
- * @return string
*/
- public function __toString()
+ public function __toString(): string
{
return $this->getName();
}
@@ -217,7 +209,7 @@ class ReflectionClassConstant implements \Reflector
*
* @return ReflectionClassConstant|\ReflectionClassConstant
*/
- public static function create($class, $name)
+ public static function create($class, string $name)
{
if (\class_exists(\ReflectionClassConstant::class)) {
return new \ReflectionClassConstant($class, $name);
diff --git a/vendor/psy/psysh/src/Reflection/ReflectionConstant.php b/vendor/psy/psysh/src/Reflection/ReflectionConstant.php
index cac76e764..b67b4ac26 100644
--- a/vendor/psy/psysh/src/Reflection/ReflectionConstant.php
+++ b/vendor/psy/psysh/src/Reflection/ReflectionConstant.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
diff --git a/vendor/psy/psysh/src/Reflection/ReflectionConstant_.php b/vendor/psy/psysh/src/Reflection/ReflectionConstant_.php
index 56c11ad01..07f81d157 100644
--- a/vendor/psy/psysh/src/Reflection/ReflectionConstant_.php
+++ b/vendor/psy/psysh/src/Reflection/ReflectionConstant_.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -42,7 +42,7 @@ class ReflectionConstant_ implements \Reflector
*
* @param string $name
*/
- public function __construct($name)
+ public function __construct(string $name)
{
$this->name = $name;
@@ -63,7 +63,7 @@ class ReflectionConstant_ implements \Reflector
*
* @return string|null
*/
- public static function export($name, $return = false)
+ public static function export(string $name, bool $return = false)
{
$refl = new self($name);
$value = $refl->getValue();
@@ -87,17 +87,15 @@ class ReflectionConstant_ implements \Reflector
*
* @return false
*/
- public function getDocComment()
+ public function getDocComment(): bool
{
return false;
}
/**
* Gets the constant name.
- *
- * @return string
*/
- public function getName()
+ public function getName(): string
{
return $this->name;
}
@@ -106,10 +104,8 @@ class ReflectionConstant_ implements \Reflector
* Gets the namespace name.
*
* Returns '' when the constant is not namespaced.
- *
- * @return string
*/
- public function getNamespaceName()
+ public function getNamespaceName(): string
{
if (!$this->inNamespace()) {
return '';
@@ -130,20 +126,16 @@ class ReflectionConstant_ implements \Reflector
/**
* Checks if this constant is defined in a namespace.
- *
- * @return bool
*/
- public function inNamespace()
+ public function inNamespace(): bool
{
return \strpos($this->name, '\\') !== false;
}
/**
* To string.
- *
- * @return string
*/
- public function __toString()
+ public function __toString(): string
{
return $this->getName();
}
diff --git a/vendor/psy/psysh/src/Reflection/ReflectionLanguageConstruct.php b/vendor/psy/psysh/src/Reflection/ReflectionLanguageConstruct.php
index 64f7f6d1c..890221469 100644
--- a/vendor/psy/psysh/src/Reflection/ReflectionLanguageConstruct.php
+++ b/vendor/psy/psysh/src/Reflection/ReflectionLanguageConstruct.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -74,7 +74,7 @@ class ReflectionLanguageConstruct extends \ReflectionFunctionAbstract
*
* @param string $keyword
*/
- public function __construct($keyword)
+ public function __construct(string $keyword)
{
if (!self::isLanguageConstruct($keyword)) {
throw new \InvalidArgumentException('Unknown language construct: '.$keyword);
@@ -95,20 +95,16 @@ class ReflectionLanguageConstruct extends \ReflectionFunctionAbstract
/**
* Get language construct name.
- *
- * @return string
*/
- public function getName()
+ public function getName(): string
{
return $this->keyword;
}
/**
* None of these return references.
- *
- * @return bool
*/
- public function returnsReference()
+ public function returnsReference(): bool
{
return false;
}
@@ -118,7 +114,7 @@ class ReflectionLanguageConstruct extends \ReflectionFunctionAbstract
*
* @return array
*/
- public function getParameters()
+ public function getParameters(): array
{
$params = [];
foreach (self::$languageConstructs[$this->keyword] as $parameter => $opts) {
@@ -133,8 +129,11 @@ class ReflectionLanguageConstruct extends \ReflectionFunctionAbstract
*
* (Hint: it always returns false)
*
- * @return bool false
+ * @todo remove \ReturnTypeWillChange attribute after dropping support for PHP 7.x (when we can use union types)
+ *
+ * @return string|false (false)
*/
+ #[\ReturnTypeWillChange]
public function getFileName()
{
return false;
@@ -142,10 +141,8 @@ class ReflectionLanguageConstruct extends \ReflectionFunctionAbstract
/**
* To string.
- *
- * @return string
*/
- public function __toString()
+ public function __toString(): string
{
return $this->getName();
}
@@ -154,10 +151,8 @@ class ReflectionLanguageConstruct extends \ReflectionFunctionAbstract
* Check whether keyword is a (known) language construct.
*
* @param string $keyword
- *
- * @return bool
*/
- public static function isLanguageConstruct($keyword)
+ public static function isLanguageConstruct(string $keyword): bool
{
return \array_key_exists($keyword, self::$languageConstructs);
}
diff --git a/vendor/psy/psysh/src/Reflection/ReflectionLanguageConstructParameter.php b/vendor/psy/psysh/src/Reflection/ReflectionLanguageConstructParameter.php
index 895fc2bb8..6f6335241 100644
--- a/vendor/psy/psysh/src/Reflection/ReflectionLanguageConstructParameter.php
+++ b/vendor/psy/psysh/src/Reflection/ReflectionLanguageConstructParameter.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -31,7 +31,10 @@ class ReflectionLanguageConstructParameter extends \ReflectionParameter
/**
* No class here.
+ *
+ * @todo remove \ReturnTypeWillChange attribute after dropping support for PHP 7.0 (when we can use nullable types)
*/
+ #[\ReturnTypeWillChange]
public function getClass()
{
return;
@@ -42,7 +45,7 @@ class ReflectionLanguageConstructParameter extends \ReflectionParameter
*
* @return bool
*/
- public function isArray()
+ public function isArray(): bool
{
return \array_key_exists('isArray', $this->opts) && $this->opts['isArray'];
}
@@ -50,13 +53,18 @@ class ReflectionLanguageConstructParameter extends \ReflectionParameter
/**
* Get param default value.
*
+ * @todo remove \ReturnTypeWillChange attribute after dropping support for PHP 7.x (when we can use mixed type)
+ *
* @return mixed
*/
+ #[\ReturnTypeWillChange]
public function getDefaultValue()
{
if ($this->isDefaultValueAvailable()) {
return $this->opts['defaultValue'];
}
+
+ return null;
}
/**
@@ -64,7 +72,7 @@ class ReflectionLanguageConstructParameter extends \ReflectionParameter
*
* @return string
*/
- public function getName()
+ public function getName(): string
{
return $this->parameter;
}
@@ -74,7 +82,7 @@ class ReflectionLanguageConstructParameter extends \ReflectionParameter
*
* @return bool
*/
- public function isOptional()
+ public function isOptional(): bool
{
return \array_key_exists('isOptional', $this->opts) && $this->opts['isOptional'];
}
@@ -84,7 +92,7 @@ class ReflectionLanguageConstructParameter extends \ReflectionParameter
*
* @return bool
*/
- public function isDefaultValueAvailable()
+ public function isDefaultValueAvailable(): bool
{
return \array_key_exists('defaultValue', $this->opts);
}
@@ -96,7 +104,7 @@ class ReflectionLanguageConstructParameter extends \ReflectionParameter
*
* @return bool
*/
- public function isPassedByReference()
+ public function isPassedByReference(): bool
{
return \array_key_exists('isPassedByReference', $this->opts) && $this->opts['isPassedByReference'];
}
diff --git a/vendor/psy/psysh/src/Reflection/ReflectionNamespace.php b/vendor/psy/psysh/src/Reflection/ReflectionNamespace.php
index f50a322a8..3c8b330c0 100644
--- a/vendor/psy/psysh/src/Reflection/ReflectionNamespace.php
+++ b/vendor/psy/psysh/src/Reflection/ReflectionNamespace.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -23,7 +23,7 @@ class ReflectionNamespace implements \Reflector
*
* @param string $name
*/
- public function __construct($name)
+ public function __construct(string $name)
{
$this->name = $name;
}
@@ -33,7 +33,7 @@ class ReflectionNamespace implements \Reflector
*
* @return string
*/
- public function getName()
+ public function getName(): string
{
return $this->name;
}
@@ -53,7 +53,7 @@ class ReflectionNamespace implements \Reflector
*
* @return string
*/
- public function __toString()
+ public function __toString(): string
{
return $this->getName();
}
diff --git a/vendor/psy/psysh/src/Shell.php b/vendor/psy/psysh/src/Shell.php
index af4c5c8d5..98379cfd6 100644
--- a/vendor/psy/psysh/src/Shell.php
+++ b/vendor/psy/psysh/src/Shell.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -15,13 +15,14 @@ use Psy\CodeCleaner\NoReturnValue;
use Psy\Exception\BreakException;
use Psy\Exception\ErrorException;
use Psy\Exception\Exception as PsyException;
+use Psy\Exception\RuntimeException;
use Psy\Exception\ThrowUpException;
-use Psy\Exception\TypeErrorException;
use Psy\ExecutionLoop\ProcessForker;
use Psy\ExecutionLoop\RunkitReloader;
use Psy\Formatter\TraceFormatter;
use Psy\Input\ShellInput;
use Psy\Input\SilentInput;
+use Psy\Output\ShellOutput;
use Psy\TabCompletion\Matcher;
use Psy\VarDumper\PresenterAware;
use Symfony\Component\Console\Application;
@@ -48,11 +49,15 @@ use Symfony\Component\Console\Output\OutputInterface;
*/
class Shell extends Application
{
- const VERSION = 'v0.10.12';
+ const VERSION = 'v0.11.12';
+ /** @deprecated */
const PROMPT = '>>> ';
+ /** @deprecated */
const BUFF_PROMPT = '... ';
+ /** @deprecated */
const REPLAY = '--> ';
+ /** @deprecated */
const RETVAL = '=> ';
private $config;
@@ -75,6 +80,7 @@ class Shell extends Application
private $commandsMatcher;
private $lastExecSuccess = true;
private $nonInteractive = false;
+ private $errorReporting;
/**
* Create a new Psy Shell.
@@ -107,7 +113,7 @@ class Shell extends Application
* This is used by the psysh bin to decide whether to start a shell on boot,
* or to simply autoload the library.
*/
- public static function isIncluded(array $trace)
+ public static function isIncluded(array $trace): bool
{
$isIncluded = isset($trace[0]['function']) &&
\in_array($trace[0]['function'], ['require', 'include', 'require_once', 'include_once']);
@@ -123,6 +129,14 @@ class Shell extends Application
return $isIncluded;
}
+ /**
+ * Check if the currently running PsySH bin is a phar archive.
+ */
+ public static function isPhar(): bool
+ {
+ return \class_exists("\Phar") && \Phar::running() !== '' && \strpos(__FILE__, \Phar::running(true)) === 0;
+ }
+
/**
* Invoke a Psy Shell from the current context.
*
@@ -134,7 +148,7 @@ class Shell extends Application
*
* @return array Scope variables from the debugger session
*/
- public static function debug(array $vars = [], $bindTo = null)
+ public static function debug(array $vars = [], $bindTo = null): array
{
return \Psy\debug($vars, $bindTo);
}
@@ -148,7 +162,7 @@ class Shell extends Application
*
* @return BaseCommand The registered command
*/
- public function add(BaseCommand $command)
+ public function add(BaseCommand $command): BaseCommand
{
if ($ret = parent::add($command)) {
if ($ret instanceof ContextAware) {
@@ -172,7 +186,7 @@ class Shell extends Application
*
* @return InputDefinition An InputDefinition instance
*/
- protected function getDefaultInputDefinition()
+ protected function getDefaultInputDefinition(): InputDefinition
{
return new InputDefinition([
new InputArgument('command', InputArgument::REQUIRED, 'The command to execute'),
@@ -185,7 +199,7 @@ class Shell extends Application
*
* @return array An array of default Command instances
*/
- protected function getDefaultCommands()
+ protected function getDefaultCommands(): array
{
$sudo = new Command\SudoCommand();
$sudo->setReadline($this->readline);
@@ -215,9 +229,9 @@ class Shell extends Application
}
/**
- * @return array
+ * @return Matcher\AbstractMatcher[]
*/
- protected function getDefaultMatchers()
+ protected function getDefaultMatchers(): array
{
// Store the Commands Matcher for later. If more commands are added,
// we'll update the Commands Matcher too.
@@ -253,7 +267,7 @@ class Shell extends Application
*
* @return array An array of Execution Loop Listener instances
*/
- protected function getDefaultLoopListeners()
+ protected function getDefaultLoopListeners(): array
{
$listeners = [];
@@ -311,7 +325,7 @@ class Shell extends Application
*
* @return int 0 if everything went fine, or an error code
*/
- public function run(InputInterface $input = null, OutputInterface $output = null)
+ public function run(InputInterface $input = null, OutputInterface $output = null): int
{
// We'll just ignore the input passed in, and set up our own!
$input = new ArrayInput([]);
@@ -325,7 +339,7 @@ class Shell extends Application
try {
return parent::run($input, $output);
- } catch (\Exception $e) {
+ } catch (\Throwable $e) {
$this->writeException($e);
}
@@ -335,14 +349,14 @@ class Shell extends Application
/**
* Runs PsySH.
*
- * @throws \Exception if thrown via the `throw-up` command
+ * @throws \Throwable if thrown via the `throw-up` command
*
* @param InputInterface $input An Input instance
* @param OutputInterface $output An Output instance
*
* @return int 0 if everything went fine, or an error code
*/
- public function doRun(InputInterface $input, OutputInterface $output)
+ public function doRun(InputInterface $input, OutputInterface $output): int
{
$this->setOutput($output);
$this->resetCodeBuffer();
@@ -361,11 +375,11 @@ class Shell extends Application
* Initializes tab completion and readline history, then spins up the
* execution loop.
*
- * @throws \Exception if thrown via the `throw-up` command
+ * @throws \Throwable if thrown via the `throw-up` command
*
* @return int 0 if everything went fine, or an error code
*/
- private function doInteractiveRun()
+ private function doInteractiveRun(): int
{
$this->initializeTabCompletion();
$this->readline->readHistory();
@@ -399,7 +413,7 @@ class Shell extends Application
*
* @return int 0 if everything went fine, or an error code
*/
- private function doNonInteractiveRun($rawOutput)
+ private function doNonInteractiveRun(bool $rawOutput): int
{
$this->nonInteractive = true;
@@ -457,8 +471,6 @@ class Shell extends Application
foreach ($__psysh__->getIncludes() as $__psysh_include__) {
try {
include_once $__psysh_include__;
- } catch (\Error $_e) {
- $__psysh__->writeException(ErrorException::fromError($_e));
} catch (\Exception $_e) {
$__psysh__->writeException($_e);
}
@@ -486,7 +498,7 @@ class Shell extends Application
*
* @param bool $interactive
*/
- public function getInput($interactive = true)
+ public function getInput(bool $interactive = true)
{
$this->codeBufferOpen = false;
@@ -543,7 +555,7 @@ class Shell extends Application
*
* @return bool true if the input is in an open string or comment
*/
- private function inputInOpenStringOrComment($input)
+ private function inputInOpenStringOrComment(string $input): bool
{
if (!$this->hasCode()) {
return false;
@@ -582,10 +594,8 @@ class Shell extends Application
* Run execution loop listeners on user input.
*
* @param string $input
- *
- * @return string
*/
- public function onInput($input)
+ public function onInput(string $input): string
{
foreach ($this->loopListeners as $listeners) {
if (($return = $listeners->onInput($this, $input)) !== null) {
@@ -600,11 +610,11 @@ class Shell extends Application
* Run execution loop listeners on code to be executed.
*
* @param string $code
- *
- * @return string
*/
- public function onExecute($code)
+ public function onExecute(string $code): string
{
+ $this->errorReporting = \error_reporting();
+
foreach ($this->loopListeners as $listener) {
if (($return = $listener->onExecute($this, $code)) !== null) {
$code = $return;
@@ -660,7 +670,7 @@ class Shell extends Application
*
* @return array Associative array of scope variables
*/
- public function getScopeVariables($includeBoundObject = true)
+ public function getScopeVariables(bool $includeBoundObject = true): array
{
$vars = $this->context->getAll();
@@ -680,7 +690,7 @@ class Shell extends Application
*
* @return array Associative array of magic scope variables
*/
- public function getSpecialScopeVariables($includeBoundObject = true)
+ public function getSpecialScopeVariables(bool $includeBoundObject = true): array
{
$vars = $this->context->getSpecialVariables();
@@ -702,7 +712,7 @@ class Shell extends Application
*
* @return array Associative array of scope variables which differ from $currentVars
*/
- public function getScopeVariablesDiff(array $currentVars)
+ public function getScopeVariablesDiff(array $currentVars): array
{
$newVars = [];
@@ -720,7 +730,7 @@ class Shell extends Application
*
* @return array Array of unused variable names
*/
- public function getUnusedCommandScopeVariableNames()
+ public function getUnusedCommandScopeVariableNames(): array
{
return $this->context->getUnusedCommandScopeVariableNames();
}
@@ -730,7 +740,7 @@ class Shell extends Application
*
* @return array Array of variable names
*/
- public function getScopeVariableNames()
+ public function getScopeVariableNames(): array
{
return \array_keys($this->context->getAll());
}
@@ -742,7 +752,7 @@ class Shell extends Application
*
* @return mixed
*/
- public function getScopeVariable($name)
+ public function getScopeVariable(string $name)
{
return $this->context->get($name);
}
@@ -800,9 +810,9 @@ class Shell extends Application
/**
* Get PHP files to be parsed and executed before running the interactive shell.
*
- * @return array
+ * @return string[]
*/
- public function getIncludes()
+ public function getIncludes(): array
{
return \array_merge($this->config->getDefaultIncludes(), $this->includes);
}
@@ -812,7 +822,7 @@ class Shell extends Application
*
* @return bool True if the code buffer contains code
*/
- public function hasCode()
+ public function hasCode(): bool
{
return !empty($this->codeBuffer);
}
@@ -824,7 +834,7 @@ class Shell extends Application
*
* @return bool True if the code buffer content is valid
*/
- protected function hasValidCode()
+ protected function hasValidCode(): bool
{
return !$this->codeBufferOpen && $this->code !== false;
}
@@ -835,7 +845,7 @@ class Shell extends Application
* @param string $code
* @param bool $silent
*/
- public function addCode($code, $silent = false)
+ public function addCode(string $code, bool $silent = false)
{
try {
// Code lines ending in \ keep the buffer open
@@ -848,7 +858,7 @@ class Shell extends Application
$this->codeBuffer[] = $silent ? new SilentInput($code) : $code;
$this->code = $this->cleaner->clean($this->codeBuffer, $this->config->requireSemicolons());
- } catch (\Exception $e) {
+ } catch (\Throwable $e) {
// Add failed code blocks to the readline history.
$this->addCodeBufferToHistory();
@@ -868,7 +878,7 @@ class Shell extends Application
* @param string $code
* @param bool $silent
*/
- private function setCode($code, $silent = false)
+ private function setCode(string $code, bool $silent = false)
{
if ($this->hasCode()) {
$this->codeStack[] = [$this->codeBuffer, $this->codeBufferOpen, $this->code];
@@ -880,10 +890,6 @@ class Shell extends Application
} catch (\Throwable $e) {
$this->popCodeStack();
- throw $e;
- } catch (\Exception $e) {
- $this->popCodeStack();
-
throw $e;
}
@@ -899,9 +905,9 @@ class Shell extends Application
*
* This is useful for commands which manipulate the buffer.
*
- * @return array
+ * @return string[]
*/
- public function getCodeBuffer()
+ public function getCodeBuffer(): array
{
return $this->codeBuffer;
}
@@ -915,7 +921,7 @@ class Shell extends Application
*
* @return mixed Who knows?
*/
- protected function runCommand($input)
+ protected function runCommand(string $input)
{
$command = $this->getCommand($input);
@@ -927,6 +933,9 @@ class Shell extends Application
if ($input->hasParameterOption(['--help', '-h'])) {
$helpCommand = $this->get('help');
+ if (!$helpCommand instanceof Command\HelpCommand) {
+ throw new RuntimeException('Invalid help command instance');
+ }
$helpCommand->setCommand($command);
return $helpCommand->run(new StringInput(''), $this->output);
@@ -955,7 +964,7 @@ class Shell extends Application
* @param string|array $input
* @param bool $silent
*/
- public function addInput($input, $silent = false)
+ public function addInput($input, bool $silent = false)
{
foreach ((array) $input as $line) {
$this->inputBuffer[] = $silent ? new SilentInput($line) : $line;
@@ -968,7 +977,7 @@ class Shell extends Application
* If the code buffer is valid, resets the code buffer and returns the
* current code.
*
- * @return string PHP code buffer contents
+ * @return string|null PHP code buffer contents
*/
public function flushCode()
{
@@ -1040,7 +1049,7 @@ class Shell extends Application
*
* @see CodeCleaner::getNamespace
*
- * @return string Current code namespace
+ * @return string|null Current code namespace
*/
public function getNamespace()
{
@@ -1057,8 +1066,14 @@ class Shell extends Application
* @param string $out
* @param int $phase Output buffering phase
*/
- public function writeStdout($out, $phase = \PHP_OUTPUT_HANDLER_END)
+ public function writeStdout(string $out, int $phase = \PHP_OUTPUT_HANDLER_END)
{
+ if ($phase & \PHP_OUTPUT_HANDLER_START) {
+ if ($this->output instanceof ShellOutput) {
+ $this->output->startPaging();
+ }
+ }
+
$isCleaning = $phase & \PHP_OUTPUT_HANDLER_CLEAN;
// Incremental flush
@@ -1073,7 +1088,7 @@ class Shell extends Application
// Write an extra newline if stdout didn't end with one
if ($this->outputWantsNewline) {
if (!$this->config->rawOutput() && !$this->config->outputIsPiped()) {
- $this->output->writeln(\sprintf('', $this->config->useUnicode() ? '⏎' : '\\n'));
+ $this->output->writeln(\sprintf('%s ', $this->config->useUnicode() ? '⏎' : '\\n'));
} else {
$this->output->writeln('');
}
@@ -1085,6 +1100,10 @@ class Shell extends Application
$this->context->setLastStdout($this->stdoutBuffer);
$this->stdoutBuffer = '';
}
+
+ if ($this->output instanceof ShellOutput) {
+ $this->output->stopPaging();
+ }
}
}
@@ -1099,7 +1118,7 @@ class Shell extends Application
* @param mixed $ret
* @param bool $rawOutput Write raw var_export-style values
*/
- public function writeReturnValue($ret, $rawOutput = false)
+ public function writeReturnValue($ret, bool $rawOutput = false)
{
$this->lastExecSuccess = true;
@@ -1112,25 +1131,32 @@ class Shell extends Application
if ($rawOutput) {
$formatted = \var_export($ret, true);
} else {
- $indent = \str_repeat(' ', \strlen(static::RETVAL));
+ $prompt = $this->config->theme()->returnValue();
+ $indent = \str_repeat(' ', \strlen($prompt));
$formatted = $this->presentValue($ret);
- $formatted = static::RETVAL.\str_replace(\PHP_EOL, \PHP_EOL.$indent, $formatted);
+ $formattedRetValue = \sprintf('%s ', $prompt);
+
+ $formatted = $formattedRetValue.\str_replace(\PHP_EOL, \PHP_EOL.$indent, $formatted);
}
- $this->output->writeln($formatted);
+ if ($this->output instanceof ShellOutput) {
+ $this->output->page($formatted.\PHP_EOL);
+ } else {
+ $this->output->writeln($formatted);
+ }
}
/**
- * Renders a caught Exception.
+ * Renders a caught Exception or Error.
*
* Exceptions are formatted according to severity. ErrorExceptions which were
* warnings or Strict errors aren't rendered as harshly as real errors.
*
* Stores $e as the last Exception in the Shell Context.
*
- * @param \Exception $e An exception instance
+ * @param \Throwable $e An exception or error instance
*/
- public function writeException(\Exception $e)
+ public function writeException(\Throwable $e)
{
// No need to write the break exception during a non-interactive run.
if ($e instanceof BreakException && $this->nonInteractive) {
@@ -1149,8 +1175,17 @@ class Shell extends Application
if ($output instanceof ConsoleOutput) {
$output = $output->getErrorOutput();
}
+
+ if (!$this->config->theme()->compact()) {
+ $output->writeln('');
+ }
+
$output->writeln($this->formatException($e));
+ if (!$this->config->theme()->compact()) {
+ $output->writeln('');
+ }
+
// Include an exception trace (as long as this isn't a BreakException).
if (!$e instanceof BreakException && $output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) {
$trace = TraceFormatter::formatTrace($e);
@@ -1168,32 +1203,34 @@ class Shell extends Application
* Check whether the last exec was successful.
*
* Returns true if a return value was logged rather than an exception.
- *
- * @return bool
*/
- public function getLastExecSuccess()
+ public function getLastExecSuccess(): bool
{
return $this->lastExecSuccess;
}
/**
- * Helper for formatting an exception for writeException().
+ * Helper for formatting an exception or error for writeException().
*
* @todo extract this to somewhere it makes more sense
*
- * @param \Exception $e
- *
- * @return string
+ * @param \Throwable $e
*/
- public function formatException(\Exception $e)
+ public function formatException(\Throwable $e): string
{
- $message = $e->getMessage();
- if (!$e instanceof PsyException) {
- if ($message === '') {
- $message = \get_class($e);
- } else {
- $message = \sprintf('%s with message \'%s\'', \get_class($e), $message);
- }
+ $indent = $this->config->theme()->compact() ? '' : ' ';
+
+ if ($e instanceof BreakException) {
+ return \sprintf('%s INFO %s.', $indent, \rtrim($e->getRawMessage(), '.'));
+ } elseif ($e instanceof PsyException) {
+ $message = $e->getLine() > 1
+ ? \sprintf('%s in %s on line %d', $e->getRawMessage(), $e->getFile(), $e->getLine())
+ : \sprintf('%s in %s', $e->getRawMessage(), $e->getFile());
+
+ $messageLabel = \strtoupper($this->getMessageLabel($e));
+ } else {
+ $message = $e->getMessage();
+ $messageLabel = $this->getMessageLabel($e);
}
$message = \preg_replace(
@@ -1202,21 +1239,28 @@ class Shell extends Application
$message
);
- $message = \str_replace(" in eval()'d code", ' in Psy Shell code', $message);
+ $message = \str_replace(" in eval()'d code", '', $message);
+ $message = \trim($message);
+
+ // Ensures the given string ends with punctuation...
+ if (!empty($message) && !\in_array(\substr($message, -1), ['.', '?', '!', ':'])) {
+ $message = "$message.";
+ }
+
+ // Ensures the given message only contains relative paths...
+ $message = \str_replace(\getcwd().\DIRECTORY_SEPARATOR, '', $message);
$severity = ($e instanceof \ErrorException) ? $this->getSeverity($e) : 'error';
- return \sprintf('<%s>%s%s>', $severity, OutputFormatter::escape($message), $severity);
+ return \sprintf('%s<%s> %s %s> %s', $indent, $severity, $messageLabel, $severity, OutputFormatter::escape($message));
}
/**
* Helper for getting an output style for the given ErrorException's level.
*
* @param \ErrorException $e
- *
- * @return string
*/
- protected function getSeverity(\ErrorException $e)
+ protected function getSeverity(\ErrorException $e): string
{
$severity = $e->getSeverity();
if ($severity & \error_reporting()) {
@@ -1227,6 +1271,8 @@ class Shell extends Application
case \E_COMPILE_WARNING:
case \E_USER_WARNING:
case \E_USER_NOTICE:
+ case \E_USER_DEPRECATED:
+ case \E_DEPRECATED:
case \E_STRICT:
return 'warning';
@@ -1239,6 +1285,51 @@ class Shell extends Application
}
}
+ /**
+ * Helper for getting an output style for the given ErrorException's level.
+ *
+ * @param \Throwable $e
+ */
+ protected function getMessageLabel(\Throwable $e): string
+ {
+ if ($e instanceof \ErrorException) {
+ $severity = $e->getSeverity();
+
+ if ($severity & \error_reporting()) {
+ switch ($severity) {
+ case \E_WARNING:
+ return 'Warning';
+ case \E_NOTICE:
+ return 'Notice';
+ case \E_CORE_WARNING:
+ return 'Core Warning';
+ case \E_COMPILE_WARNING:
+ return 'Compile Warning';
+ case \E_USER_WARNING:
+ return 'User Warning';
+ case \E_USER_NOTICE:
+ return 'User Notice';
+ case \E_USER_DEPRECATED:
+ return 'User Deprecated';
+ case \E_DEPRECATED:
+ return 'Deprecated';
+ case \E_STRICT:
+ return 'Strict';
+ }
+ }
+ }
+
+ if ($e instanceof PsyException) {
+ $exceptionShortName = (new \ReflectionClass($e))->getShortName();
+ $typeParts = \preg_split('/(?=[A-Z])/', $exceptionShortName);
+ \array_pop($typeParts); // Removes "Exception"
+
+ return \trim(\strtoupper(\implode(' ', $typeParts)));
+ }
+
+ return \get_class($e);
+ }
+
/**
* Execute code in the shell execution context.
*
@@ -1247,7 +1338,7 @@ class Shell extends Application
*
* @return mixed
*/
- public function execute($code, $throwExceptions = false)
+ public function execute(string $code, bool $throwExceptions = false)
{
$this->setCode($code, true);
$closure = new ExecutionClosure($this);
@@ -1258,11 +1349,7 @@ class Shell extends Application
try {
return $closure->execute();
- } catch (\TypeError $_e) {
- $this->writeException(TypeErrorException::fromTypeError($_e));
- } catch (\Error $_e) {
- $this->writeException(ErrorException::fromError($_e));
- } catch (\Exception $_e) {
+ } catch (\Throwable $_e) {
$this->writeException($_e);
}
}
@@ -1302,8 +1389,12 @@ class Shell extends Application
ErrorException::throwException($errno, $errstr, $errfile, $errline);
}
+ // When errors are suppressed, the error_reporting value will differ
+ // from when we started executing. In that case, we won't log errors.
+ $errorsSuppressed = $this->errorReporting !== null && $this->errorReporting !== \error_reporting();
+
// Otherwise log it and continue.
- if ($errno & \error_reporting() || $errno & $this->config->errorLoggingLevel()) {
+ if ($errno & \error_reporting() || (!$errorsSuppressed && ($errno & $this->config->errorLoggingLevel()))) {
$this->writeException(new ErrorException($errstr, 0, $errno, $errfile, $errline));
}
}
@@ -1317,7 +1408,7 @@ class Shell extends Application
*
* @return string Formatted value
*/
- protected function presentValue($val)
+ protected function presentValue($val): string
{
return $this->config->getPresenter()->present($val);
}
@@ -1329,7 +1420,7 @@ class Shell extends Application
*
* @return BaseCommand|null
*/
- protected function getCommand($input)
+ protected function getCommand(string $input)
{
$input = new StringInput($input);
if ($name = $input->getFirstArgument()) {
@@ -1344,7 +1435,7 @@ class Shell extends Application
*
* @return bool True if the shell has a command for the given input
*/
- protected function hasCommand($input)
+ protected function hasCommand(string $input): bool
{
if (\preg_match('/([^\s]+?)(?:\s|$)/A', \ltrim($input), $match)) {
return $this->has($match[1]);
@@ -1364,11 +1455,13 @@ class Shell extends Application
return null;
}
+ $theme = $this->config->theme();
+
if ($this->hasCode()) {
- return static::BUFF_PROMPT;
+ return $theme->bufferPrompt();
}
- return $this->config->getPrompt() ?: static::PROMPT;
+ return $theme->prompt();
}
/**
@@ -1382,14 +1475,16 @@ class Shell extends Application
*
* @param bool $interactive
*
- * @return string One line of user input
+ * @return string|false One line of user input
*/
- protected function readline($interactive = true)
+ protected function readline(bool $interactive = true)
{
+ $prompt = $this->config->theme()->replayPrompt();
+
if (!empty($this->inputBuffer)) {
$line = \array_shift($this->inputBuffer);
if (!$line instanceof SilentInput) {
- $this->output->writeln(\sprintf('', static::REPLAY, OutputFormatter::escape($line)));
+ $this->output->writeln(\sprintf('%s ', $prompt, OutputFormatter::escape($line)));
}
return $line;
@@ -1412,22 +1507,18 @@ class Shell extends Application
/**
* Get the shell output header.
- *
- * @return string
*/
- protected function getHeader()
+ protected function getHeader(): string
{
- return \sprintf('', $this->getVersion());
+ return \sprintf('%s by Justin Hileman ', $this->getVersion());
}
/**
* Get the current version of Psy Shell.
*
* @deprecated call self::getVersionHeader instead
- *
- * @return string
*/
- public function getVersion()
+ public function getVersion(): string
{
return self::getVersionHeader($this->config->useUnicode());
}
@@ -1436,10 +1527,8 @@ class Shell extends Application
* Get a pretty header including the current version of Psy Shell.
*
* @param bool $useUnicode
- *
- * @return string
*/
- public static function getVersionHeader($useUnicode = false)
+ public static function getVersionHeader(bool $useUnicode = false): string
{
$separator = $useUnicode ? '—' : '-';
@@ -1502,7 +1591,6 @@ class Shell extends Application
}
/**
- * @todo Implement self-update
* @todo Implement prompt to start update
*
* @return void|string
@@ -1516,7 +1604,7 @@ class Shell extends Application
try {
$client = $this->config->getChecker();
if (!$client->isLatest()) {
- $this->output->writeln(\sprintf('New version is available (current: %s, latest: %s)', self::VERSION, $client->getLatest()));
+ $this->output->writeln(\sprintf('New version is available at psysh.org/psysh (current: %s, latest: %s) ', self::VERSION, $client->getLatest()));
}
} catch (\InvalidArgumentException $e) {
$this->output->writeln($e->getMessage());
diff --git a/vendor/psy/psysh/src/Sudo.php b/vendor/psy/psysh/src/Sudo.php
index 8c9e5a150..0015cbc76 100644
--- a/vendor/psy/psysh/src/Sudo.php
+++ b/vendor/psy/psysh/src/Sudo.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -25,9 +25,9 @@ class Sudo
*
* @return mixed Value of $object->property
*/
- public static function fetchProperty($object, $property)
+ public static function fetchProperty($object, string $property)
{
- $prop = static::getProperty(new \ReflectionObject($object), $property);
+ $prop = self::getProperty(new \ReflectionObject($object), $property);
return $prop->getValue($object);
}
@@ -41,9 +41,9 @@ class Sudo
*
* @return mixed Value of $object->property
*/
- public static function assignProperty($object, $property, $value)
+ public static function assignProperty($object, string $property, $value)
{
- $prop = static::getProperty(new \ReflectionObject($object), $property);
+ $prop = self::getProperty(new \ReflectionObject($object), $property);
$prop->setValue($object, $value);
return $value;
@@ -58,12 +58,8 @@ class Sudo
*
* @return mixed
*/
- public static function callMethod($object, $method, $args = null)
+ public static function callMethod($object, string $method, ...$args)
{
- $args = \func_get_args();
- $object = \array_shift($args);
- $method = \array_shift($args);
-
$refl = new \ReflectionObject($object);
$reflMethod = $refl->getMethod($method);
$reflMethod->setAccessible(true);
@@ -79,9 +75,9 @@ class Sudo
*
* @return mixed Value of $class::$property
*/
- public static function fetchStaticProperty($class, $property)
+ public static function fetchStaticProperty($class, string $property)
{
- $prop = static::getProperty(new \ReflectionClass($class), $property);
+ $prop = self::getProperty(new \ReflectionClass($class), $property);
$prop->setAccessible(true);
return $prop->getValue();
@@ -96,9 +92,9 @@ class Sudo
*
* @return mixed Value of $class::$property
*/
- public static function assignStaticProperty($class, $property, $value)
+ public static function assignStaticProperty($class, string $property, $value)
{
- $prop = static::getProperty(new \ReflectionClass($class), $property);
+ $prop = self::getProperty(new \ReflectionClass($class), $property);
$prop->setValue($value);
return $value;
@@ -113,12 +109,8 @@ class Sudo
*
* @return mixed
*/
- public static function callStatic($class, $method, $args = null)
+ public static function callStatic($class, string $method, ...$args)
{
- $args = \func_get_args();
- $class = \array_shift($args);
- $method = \array_shift($args);
-
$refl = new \ReflectionClass($class);
$reflMethod = $refl->getMethod($method);
$reflMethod->setAccessible(true);
@@ -134,7 +126,7 @@ class Sudo
*
* @return mixed
*/
- public static function fetchClassConst($class, $const)
+ public static function fetchClassConst($class, string $const)
{
$refl = new \ReflectionClass($class);
@@ -149,6 +141,24 @@ class Sudo
return false;
}
+ /**
+ * Construct an instance of a class, bypassing private constructors.
+ *
+ * @param string $class class name
+ * @param mixed $args...
+ */
+ public static function newInstance(string $class, ...$args)
+ {
+ $refl = new \ReflectionClass($class);
+ $instance = $refl->newInstanceWithoutConstructor();
+
+ $constructor = $refl->getConstructor();
+ $constructor->setAccessible(true);
+ $constructor->invokeArgs($instance, $args);
+
+ return $instance;
+ }
+
/**
* Get a ReflectionProperty from an object (or its parent classes).
*
@@ -159,7 +169,7 @@ class Sudo
*
* @return \ReflectionProperty
*/
- private static function getProperty(\ReflectionClass $refl, $property)
+ private static function getProperty(\ReflectionClass $refl, string $property): \ReflectionProperty
{
$firstException = null;
do {
diff --git a/vendor/psy/psysh/src/Sudo/SudoVisitor.php b/vendor/psy/psysh/src/Sudo/SudoVisitor.php
index 7fbe2012c..151dc527c 100644
--- a/vendor/psy/psysh/src/Sudo/SudoVisitor.php
+++ b/vendor/psy/psysh/src/Sudo/SudoVisitor.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -16,6 +16,7 @@ use PhpParser\Node\Arg;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Expr\MethodCall;
+use PhpParser\Node\Expr\New_;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Expr\StaticPropertyFetch;
@@ -41,9 +42,12 @@ class SudoVisitor extends NodeVisitorAbstract
const STATIC_PROPERTY_ASSIGN = 'assignStaticProperty';
const STATIC_CALL = 'callStatic';
const CLASS_CONST_FETCH = 'fetchClassConst';
+ const NEW_INSTANCE = 'newInstance';
/**
* {@inheritdoc}
+ *
+ * @return int|Node|null Replacement node (or special return value)
*/
public function enterNode(Node $node)
{
@@ -111,10 +115,17 @@ class SudoVisitor extends NodeVisitorAbstract
];
return $this->prepareCall(self::CLASS_CONST_FETCH, $args);
+ } elseif ($node instanceof New_) {
+ $args = $node->args;
+ $class = $node->class instanceof Name ? $node->class->toString() : $node->class;
+ \array_unshift($args, new Arg(\is_string($class) ? new String_($class) : $class));
+
+ // not using prepareCall because the $node->args we started with are already Arg instances
+ return new StaticCall(new FullyQualifiedName(Sudo::class), self::NEW_INSTANCE, $args);
}
}
- private function prepareCall($method, $args)
+ private function prepareCall(string $method, array $args): StaticCall
{
return new StaticCall(new FullyQualifiedName(Sudo::class), $method, \array_map(function ($arg) {
return new Arg($arg);
diff --git a/vendor/psy/psysh/src/SuperglobalsEnv.php b/vendor/psy/psysh/src/SuperglobalsEnv.php
index 7f522f936..d3369c6ab 100644
--- a/vendor/psy/psysh/src/SuperglobalsEnv.php
+++ b/vendor/psy/psysh/src/SuperglobalsEnv.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -21,7 +21,7 @@ class SuperglobalsEnv implements EnvInterface
*
* @return string|null
*/
- public function get($key)
+ public function get(string $key)
{
if (isset($_SERVER[$key]) && $_SERVER[$key]) {
return $_SERVER[$key];
diff --git a/vendor/psy/psysh/src/TabCompletion/AutoCompleter.php b/vendor/psy/psysh/src/TabCompletion/AutoCompleter.php
index 13fcd39ac..400b797ab 100644
--- a/vendor/psy/psysh/src/TabCompletion/AutoCompleter.php
+++ b/vendor/psy/psysh/src/TabCompletion/AutoCompleter.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -50,7 +50,7 @@ class AutoCompleter
*
* @return array
*/
- public function processCallback($input, $index, $info = [])
+ public function processCallback(string $input, int $index, array $info = []): array
{
// Some (Windows?) systems provide incomplete `readline_info`, so let's
// try to work around it.
@@ -68,6 +68,8 @@ class AutoCompleter
$tokens = \array_filter($tokens, function ($token) {
return !AbstractMatcher::tokenIs($token, AbstractMatcher::T_WHITESPACE);
});
+ // reset index from 0 to remove missing index number
+ $tokens = \array_values($tokens);
$matches = [];
foreach ($this->matchers as $matcher) {
@@ -91,7 +93,7 @@ class AutoCompleter
*
* @return array
*/
- public function callback($input, $index)
+ public function callback(string $input, int $index): array
{
return $this->processCallback($input, $index, \readline_info());
}
diff --git a/vendor/psy/psysh/src/TabCompletion/Matcher/AbstractContextAwareMatcher.php b/vendor/psy/psysh/src/TabCompletion/Matcher/AbstractContextAwareMatcher.php
index f7da443b9..bc39e6047 100644
--- a/vendor/psy/psysh/src/TabCompletion/Matcher/AbstractContextAwareMatcher.php
+++ b/vendor/psy/psysh/src/TabCompletion/Matcher/AbstractContextAwareMatcher.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -48,7 +48,7 @@ abstract class AbstractContextAwareMatcher extends AbstractMatcher implements Co
*
* @return mixed
*/
- protected function getVariable($var)
+ protected function getVariable(string $var)
{
return $this->context->get($var);
}
@@ -58,7 +58,7 @@ abstract class AbstractContextAwareMatcher extends AbstractMatcher implements Co
*
* @return array
*/
- protected function getVariables()
+ protected function getVariables(): array
{
return $this->context->getAll();
}
diff --git a/vendor/psy/psysh/src/TabCompletion/Matcher/AbstractDefaultParametersMatcher.php b/vendor/psy/psysh/src/TabCompletion/Matcher/AbstractDefaultParametersMatcher.php
index c80b0068a..0887333a3 100644
--- a/vendor/psy/psysh/src/TabCompletion/Matcher/AbstractDefaultParametersMatcher.php
+++ b/vendor/psy/psysh/src/TabCompletion/Matcher/AbstractDefaultParametersMatcher.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -18,7 +18,7 @@ abstract class AbstractDefaultParametersMatcher extends AbstractContextAwareMatc
*
* @return array
*/
- public function getDefaultParameterCompletion(array $reflectionParameters)
+ public function getDefaultParameterCompletion(array $reflectionParameters): array
{
$parametersProcessed = [];
@@ -29,7 +29,7 @@ abstract class AbstractDefaultParametersMatcher extends AbstractContextAwareMatc
$defaultValue = $this->valueToShortString($parameter->getDefaultValue());
- $parametersProcessed[] = "\${$parameter->getName()} = $defaultValue";
+ $parametersProcessed[] = \sprintf('$%s = %s', $parameter->getName(), $defaultValue);
}
if (empty($parametersProcessed)) {
@@ -45,10 +45,8 @@ abstract class AbstractDefaultParametersMatcher extends AbstractContextAwareMatc
* This is not 100% true to the original (newlines are inlined, for example).
*
* @param mixed $value
- *
- * @return string
*/
- private function valueToShortString($value)
+ private function valueToShortString($value): string
{
if (!\is_array($value)) {
return \json_encode($value);
diff --git a/vendor/psy/psysh/src/TabCompletion/Matcher/AbstractMatcher.php b/vendor/psy/psysh/src/TabCompletion/Matcher/AbstractMatcher.php
index bdb25deed..209cae2f6 100644
--- a/vendor/psy/psysh/src/TabCompletion/Matcher/AbstractMatcher.php
+++ b/vendor/psy/psysh/src/TabCompletion/Matcher/AbstractMatcher.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -48,9 +48,9 @@ abstract class AbstractMatcher
*
* @param array $tokens Tokenized readline input
*
- * @return bool
+ * @return false
*/
- public function hasMatched(array $tokens)
+ public function hasMatched(array $tokens): bool
{
return false;
}
@@ -59,10 +59,8 @@ abstract class AbstractMatcher
* Get current readline input word.
*
* @param array $tokens Tokenized readline input (see token_get_all)
- *
- * @return string
*/
- protected function getInput(array $tokens)
+ protected function getInput(array $tokens): string
{
$var = '';
$firstToken = \array_pop($tokens);
@@ -77,10 +75,8 @@ abstract class AbstractMatcher
* Get current namespace and class (if any) from readline input.
*
* @param array $tokens Tokenized readline input (see token_get_all)
- *
- * @return string
*/
- protected function getNamespaceAndClass($tokens)
+ protected function getNamespaceAndClass(array $tokens): string
{
$class = '';
while (self::hasToken(
@@ -105,17 +101,15 @@ abstract class AbstractMatcher
*
* @return array The matches resulting from the query
*/
- abstract public function getMatches(array $tokens, array $info = []);
+ abstract public function getMatches(array $tokens, array $info = []): array;
/**
* Check whether $word starts with $prefix.
*
* @param string $prefix
* @param string $word
- *
- * @return bool
*/
- public static function startsWith($prefix, $word)
+ public static function startsWith(string $prefix, string $word): bool
{
return \preg_match(\sprintf('#^%s#', $prefix), $word);
}
@@ -125,10 +119,8 @@ abstract class AbstractMatcher
*
* @param mixed $token A PHP token (see token_get_all)
* @param string $syntax A syntax pattern (default: variable pattern)
- *
- * @return bool
*/
- public static function hasSyntax($token, $syntax = self::VAR_SYNTAX)
+ public static function hasSyntax($token, string $syntax = self::VAR_SYNTAX): bool
{
if (!\is_array($token)) {
return false;
@@ -144,10 +136,8 @@ abstract class AbstractMatcher
*
* @param mixed $token A PHP token (see token_get_all)
* @param string $which A PHP token type
- *
- * @return bool
*/
- public static function tokenIs($token, $which)
+ public static function tokenIs($token, string $which): bool
{
if (!\is_array($token)) {
return false;
@@ -160,10 +150,8 @@ abstract class AbstractMatcher
* Check whether $token is an operator.
*
* @param mixed $token A PHP token (see token_get_all)
- *
- * @return bool
*/
- public static function isOperator($token)
+ public static function isOperator($token): bool
{
if (!\is_string($token)) {
return false;
@@ -172,7 +160,7 @@ abstract class AbstractMatcher
return \strpos(self::MISC_OPERATORS, $token) !== false;
}
- public static function needCompleteClass($token)
+ public static function needCompleteClass($token): bool
{
return \in_array($token[1], ['doc', 'ls', 'show']);
}
@@ -182,10 +170,8 @@ abstract class AbstractMatcher
*
* @param array $coll A list of token types
* @param mixed $token A PHP token (see token_get_all)
- *
- * @return bool
*/
- public static function hasToken(array $coll, $token)
+ public static function hasToken(array $coll, $token): bool
{
if (!\is_array($token)) {
return false;
diff --git a/vendor/psy/psysh/src/TabCompletion/Matcher/ClassAttributesMatcher.php b/vendor/psy/psysh/src/TabCompletion/Matcher/ClassAttributesMatcher.php
index 5ecd4cf8b..0503d71db 100644
--- a/vendor/psy/psysh/src/TabCompletion/Matcher/ClassAttributesMatcher.php
+++ b/vendor/psy/psysh/src/TabCompletion/Matcher/ClassAttributesMatcher.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -24,7 +24,7 @@ class ClassAttributesMatcher extends AbstractMatcher
/**
* {@inheritdoc}
*/
- public function getMatches(array $tokens, array $info = [])
+ public function getMatches(array $tokens, array $info = []): array
{
$input = $this->getInput($tokens);
@@ -71,7 +71,7 @@ class ClassAttributesMatcher extends AbstractMatcher
/**
* {@inheritdoc}
*/
- public function hasMatched(array $tokens)
+ public function hasMatched(array $tokens): bool
{
$token = \array_pop($tokens);
$prevToken = \array_pop($tokens);
diff --git a/vendor/psy/psysh/src/TabCompletion/Matcher/ClassMethodDefaultParametersMatcher.php b/vendor/psy/psysh/src/TabCompletion/Matcher/ClassMethodDefaultParametersMatcher.php
index d88cb69b6..118740ef2 100644
--- a/vendor/psy/psysh/src/TabCompletion/Matcher/ClassMethodDefaultParametersMatcher.php
+++ b/vendor/psy/psysh/src/TabCompletion/Matcher/ClassMethodDefaultParametersMatcher.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -13,7 +13,7 @@ namespace Psy\TabCompletion\Matcher;
class ClassMethodDefaultParametersMatcher extends AbstractDefaultParametersMatcher
{
- public function getMatches(array $tokens, array $info = [])
+ public function getMatches(array $tokens, array $info = []): array
{
$openBracket = \array_pop($tokens);
$functionName = \array_pop($tokens);
@@ -39,7 +39,7 @@ class ClassMethodDefaultParametersMatcher extends AbstractDefaultParametersMatch
return [];
}
- public function hasMatched(array $tokens)
+ public function hasMatched(array $tokens): bool
{
$openBracket = \array_pop($tokens);
diff --git a/vendor/psy/psysh/src/TabCompletion/Matcher/ClassMethodsMatcher.php b/vendor/psy/psysh/src/TabCompletion/Matcher/ClassMethodsMatcher.php
index d980766dd..a526e1ec3 100644
--- a/vendor/psy/psysh/src/TabCompletion/Matcher/ClassMethodsMatcher.php
+++ b/vendor/psy/psysh/src/TabCompletion/Matcher/ClassMethodsMatcher.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -24,7 +24,7 @@ class ClassMethodsMatcher extends AbstractMatcher
/**
* {@inheritdoc}
*/
- public function getMatches(array $tokens, array $info = [])
+ public function getMatches(array $tokens, array $info = []): array
{
$input = $this->getInput($tokens);
@@ -68,7 +68,7 @@ class ClassMethodsMatcher extends AbstractMatcher
/**
* {@inheritdoc}
*/
- public function hasMatched(array $tokens)
+ public function hasMatched(array $tokens): bool
{
$token = \array_pop($tokens);
$prevToken = \array_pop($tokens);
diff --git a/vendor/psy/psysh/src/TabCompletion/Matcher/ClassNamesMatcher.php b/vendor/psy/psysh/src/TabCompletion/Matcher/ClassNamesMatcher.php
index 83d6c8a79..ca2515d6c 100644
--- a/vendor/psy/psysh/src/TabCompletion/Matcher/ClassNamesMatcher.php
+++ b/vendor/psy/psysh/src/TabCompletion/Matcher/ClassNamesMatcher.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -23,7 +23,7 @@ class ClassNamesMatcher extends AbstractMatcher
/**
* {@inheritdoc}
*/
- public function getMatches(array $tokens, array $info = [])
+ public function getMatches(array $tokens, array $info = []): array
{
$class = $this->getNamespaceAndClass($tokens);
if ($class !== '' && $class[0] === '\\') {
@@ -36,7 +36,7 @@ class ClassNamesMatcher extends AbstractMatcher
// get the number of namespace separators
$nsPos = \substr_count($class, '\\');
$pieces = \explode('\\', $className);
- //$methods = Mirror::get($class);
+ // $methods = Mirror::get($class);
return \implode('\\', \array_slice($pieces, $nsPos, \count($pieces)));
},
\array_filter(
@@ -51,18 +51,18 @@ class ClassNamesMatcher extends AbstractMatcher
/**
* {@inheritdoc}
*/
- public function hasMatched(array $tokens)
+ public function hasMatched(array $tokens): bool
{
$token = \array_pop($tokens);
$prevToken = \array_pop($tokens);
- $blacklistedTokens = [
+ $ignoredTokens = [
self::T_INCLUDE, self::T_INCLUDE_ONCE, self::T_REQUIRE, self::T_REQUIRE_ONCE,
];
switch (true) {
- case self::hasToken([$blacklistedTokens], $token):
- case self::hasToken([$blacklistedTokens], $prevToken):
+ case self::hasToken([$ignoredTokens], $token):
+ case self::hasToken([$ignoredTokens], $prevToken):
case \is_string($token) && $token === '$':
return false;
case self::hasToken([self::T_NEW, self::T_OPEN_TAG, self::T_NS_SEPARATOR, self::T_STRING], $prevToken):
diff --git a/vendor/psy/psysh/src/TabCompletion/Matcher/CommandsMatcher.php b/vendor/psy/psysh/src/TabCompletion/Matcher/CommandsMatcher.php
index bdeb45d4c..5f712daaa 100644
--- a/vendor/psy/psysh/src/TabCompletion/Matcher/CommandsMatcher.php
+++ b/vendor/psy/psysh/src/TabCompletion/Matcher/CommandsMatcher.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -55,10 +55,8 @@ class CommandsMatcher extends AbstractMatcher
* Check whether a command $name is defined.
*
* @param string $name
- *
- * @return bool
*/
- protected function isCommand($name)
+ protected function isCommand(string $name): bool
{
return \in_array($name, $this->commands);
}
@@ -67,10 +65,8 @@ class CommandsMatcher extends AbstractMatcher
* Check whether input matches a defined command.
*
* @param string $name
- *
- * @return bool
*/
- protected function matchCommand($name)
+ protected function matchCommand(string $name): bool
{
foreach ($this->commands as $cmd) {
if ($this->startsWith($name, $cmd)) {
@@ -84,7 +80,7 @@ class CommandsMatcher extends AbstractMatcher
/**
* {@inheritdoc}
*/
- public function getMatches(array $tokens, array $info = [])
+ public function getMatches(array $tokens, array $info = []): array
{
$input = $this->getInput($tokens);
@@ -96,7 +92,7 @@ class CommandsMatcher extends AbstractMatcher
/**
* {@inheritdoc}
*/
- public function hasMatched(array $tokens)
+ public function hasMatched(array $tokens): bool
{
/* $openTag */ \array_shift($tokens);
$command = \array_shift($tokens);
diff --git a/vendor/psy/psysh/src/TabCompletion/Matcher/ConstantsMatcher.php b/vendor/psy/psysh/src/TabCompletion/Matcher/ConstantsMatcher.php
index 178adf8c2..cad81a53e 100644
--- a/vendor/psy/psysh/src/TabCompletion/Matcher/ConstantsMatcher.php
+++ b/vendor/psy/psysh/src/TabCompletion/Matcher/ConstantsMatcher.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -23,7 +23,7 @@ class ConstantsMatcher extends AbstractMatcher
/**
* {@inheritdoc}
*/
- public function getMatches(array $tokens, array $info = [])
+ public function getMatches(array $tokens, array $info = []): array
{
$const = $this->getInput($tokens);
@@ -35,7 +35,7 @@ class ConstantsMatcher extends AbstractMatcher
/**
* {@inheritdoc}
*/
- public function hasMatched(array $tokens)
+ public function hasMatched(array $tokens): bool
{
$token = \array_pop($tokens);
$prevToken = \array_pop($tokens);
diff --git a/vendor/psy/psysh/src/TabCompletion/Matcher/FunctionDefaultParametersMatcher.php b/vendor/psy/psysh/src/TabCompletion/Matcher/FunctionDefaultParametersMatcher.php
index e1277c2ee..2bbf12627 100644
--- a/vendor/psy/psysh/src/TabCompletion/Matcher/FunctionDefaultParametersMatcher.php
+++ b/vendor/psy/psysh/src/TabCompletion/Matcher/FunctionDefaultParametersMatcher.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -13,7 +13,7 @@ namespace Psy\TabCompletion\Matcher;
class FunctionDefaultParametersMatcher extends AbstractDefaultParametersMatcher
{
- public function getMatches(array $tokens, array $info = [])
+ public function getMatches(array $tokens, array $info = []): array
{
\array_pop($tokens); // open bracket
@@ -30,7 +30,7 @@ class FunctionDefaultParametersMatcher extends AbstractDefaultParametersMatcher
return $this->getDefaultParameterCompletion($parameters);
}
- public function hasMatched(array $tokens)
+ public function hasMatched(array $tokens): bool
{
$openBracket = \array_pop($tokens);
diff --git a/vendor/psy/psysh/src/TabCompletion/Matcher/FunctionsMatcher.php b/vendor/psy/psysh/src/TabCompletion/Matcher/FunctionsMatcher.php
index 1f6e6dbb5..964565997 100644
--- a/vendor/psy/psysh/src/TabCompletion/Matcher/FunctionsMatcher.php
+++ b/vendor/psy/psysh/src/TabCompletion/Matcher/FunctionsMatcher.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -23,7 +23,7 @@ class FunctionsMatcher extends AbstractMatcher
/**
* {@inheritdoc}
*/
- public function getMatches(array $tokens, array $info = [])
+ public function getMatches(array $tokens, array $info = []): array
{
$func = $this->getInput($tokens);
@@ -38,7 +38,7 @@ class FunctionsMatcher extends AbstractMatcher
/**
* {@inheritdoc}
*/
- public function hasMatched(array $tokens)
+ public function hasMatched(array $tokens): bool
{
$token = \array_pop($tokens);
$prevToken = \array_pop($tokens);
diff --git a/vendor/psy/psysh/src/TabCompletion/Matcher/KeywordsMatcher.php b/vendor/psy/psysh/src/TabCompletion/Matcher/KeywordsMatcher.php
index 393674c62..6333269de 100644
--- a/vendor/psy/psysh/src/TabCompletion/Matcher/KeywordsMatcher.php
+++ b/vendor/psy/psysh/src/TabCompletion/Matcher/KeywordsMatcher.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -32,9 +32,9 @@ class KeywordsMatcher extends AbstractMatcher
/**
* Get all (completable) PHP keywords.
*
- * @return array
+ * @return string[]
*/
- public function getKeywords()
+ public function getKeywords(): array
{
return $this->keywords;
}
@@ -43,10 +43,8 @@ class KeywordsMatcher extends AbstractMatcher
* Check whether $keyword is a (completable) PHP keyword.
*
* @param string $keyword
- *
- * @return bool
*/
- public function isKeyword($keyword)
+ public function isKeyword(string $keyword): bool
{
return \in_array($keyword, $this->keywords);
}
@@ -54,7 +52,7 @@ class KeywordsMatcher extends AbstractMatcher
/**
* {@inheritdoc}
*/
- public function getMatches(array $tokens, array $info = [])
+ public function getMatches(array $tokens, array $info = []): array
{
$input = $this->getInput($tokens);
@@ -66,7 +64,7 @@ class KeywordsMatcher extends AbstractMatcher
/**
* {@inheritdoc}
*/
- public function hasMatched(array $tokens)
+ public function hasMatched(array $tokens): bool
{
$token = \array_pop($tokens);
$prevToken = \array_pop($tokens);
diff --git a/vendor/psy/psysh/src/TabCompletion/Matcher/MongoClientMatcher.php b/vendor/psy/psysh/src/TabCompletion/Matcher/MongoClientMatcher.php
index f38836d02..3c70ee095 100644
--- a/vendor/psy/psysh/src/TabCompletion/Matcher/MongoClientMatcher.php
+++ b/vendor/psy/psysh/src/TabCompletion/Matcher/MongoClientMatcher.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -23,7 +23,7 @@ class MongoClientMatcher extends AbstractContextAwareMatcher
/**
* {@inheritdoc}
*/
- public function getMatches(array $tokens, array $info = [])
+ public function getMatches(array $tokens, array $info = []): array
{
$input = $this->getInput($tokens);
@@ -55,7 +55,7 @@ class MongoClientMatcher extends AbstractContextAwareMatcher
/**
* {@inheritdoc}
*/
- public function hasMatched(array $tokens)
+ public function hasMatched(array $tokens): bool
{
$token = \array_pop($tokens);
$prevToken = \array_pop($tokens);
diff --git a/vendor/psy/psysh/src/TabCompletion/Matcher/MongoDatabaseMatcher.php b/vendor/psy/psysh/src/TabCompletion/Matcher/MongoDatabaseMatcher.php
index a0d4d49c7..7cea95f49 100644
--- a/vendor/psy/psysh/src/TabCompletion/Matcher/MongoDatabaseMatcher.php
+++ b/vendor/psy/psysh/src/TabCompletion/Matcher/MongoDatabaseMatcher.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -23,7 +23,7 @@ class MongoDatabaseMatcher extends AbstractContextAwareMatcher
/**
* {@inheritdoc}
*/
- public function getMatches(array $tokens, array $info = [])
+ public function getMatches(array $tokens, array $info = []): array
{
$input = $this->getInput($tokens);
@@ -51,7 +51,7 @@ class MongoDatabaseMatcher extends AbstractContextAwareMatcher
/**
* {@inheritdoc}
*/
- public function hasMatched(array $tokens)
+ public function hasMatched(array $tokens): bool
{
$token = \array_pop($tokens);
$prevToken = \array_pop($tokens);
diff --git a/vendor/psy/psysh/src/TabCompletion/Matcher/ObjectAttributesMatcher.php b/vendor/psy/psysh/src/TabCompletion/Matcher/ObjectAttributesMatcher.php
index 8b3d29057..e0e96679e 100644
--- a/vendor/psy/psysh/src/TabCompletion/Matcher/ObjectAttributesMatcher.php
+++ b/vendor/psy/psysh/src/TabCompletion/Matcher/ObjectAttributesMatcher.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -26,7 +26,7 @@ class ObjectAttributesMatcher extends AbstractContextAwareMatcher
/**
* {@inheritdoc}
*/
- public function getMatches(array $tokens, array $info = [])
+ public function getMatches(array $tokens, array $info = []): array
{
$input = $this->getInput($tokens);
@@ -62,7 +62,7 @@ class ObjectAttributesMatcher extends AbstractContextAwareMatcher
/**
* {@inheritdoc}
*/
- public function hasMatched(array $tokens)
+ public function hasMatched(array $tokens): bool
{
$token = \array_pop($tokens);
$prevToken = \array_pop($tokens);
diff --git a/vendor/psy/psysh/src/TabCompletion/Matcher/ObjectMethodDefaultParametersMatcher.php b/vendor/psy/psysh/src/TabCompletion/Matcher/ObjectMethodDefaultParametersMatcher.php
index 08bab8bc9..73221fd37 100644
--- a/vendor/psy/psysh/src/TabCompletion/Matcher/ObjectMethodDefaultParametersMatcher.php
+++ b/vendor/psy/psysh/src/TabCompletion/Matcher/ObjectMethodDefaultParametersMatcher.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -13,7 +13,7 @@ namespace Psy\TabCompletion\Matcher;
class ObjectMethodDefaultParametersMatcher extends AbstractDefaultParametersMatcher
{
- public function getMatches(array $tokens, array $info = [])
+ public function getMatches(array $tokens, array $info = []): array
{
$openBracket = \array_pop($tokens);
$functionName = \array_pop($tokens);
@@ -46,7 +46,7 @@ class ObjectMethodDefaultParametersMatcher extends AbstractDefaultParametersMatc
return [];
}
- public function hasMatched(array $tokens)
+ public function hasMatched(array $tokens): bool
{
$openBracket = \array_pop($tokens);
diff --git a/vendor/psy/psysh/src/TabCompletion/Matcher/ObjectMethodsMatcher.php b/vendor/psy/psysh/src/TabCompletion/Matcher/ObjectMethodsMatcher.php
index 2a1d22407..4f10b0796 100644
--- a/vendor/psy/psysh/src/TabCompletion/Matcher/ObjectMethodsMatcher.php
+++ b/vendor/psy/psysh/src/TabCompletion/Matcher/ObjectMethodsMatcher.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -26,7 +26,7 @@ class ObjectMethodsMatcher extends AbstractContextAwareMatcher
/**
* {@inheritdoc}
*/
- public function getMatches(array $tokens, array $info = [])
+ public function getMatches(array $tokens, array $info = []): array
{
$input = $this->getInput($tokens);
@@ -64,7 +64,7 @@ class ObjectMethodsMatcher extends AbstractContextAwareMatcher
/**
* {@inheritdoc}
*/
- public function hasMatched(array $tokens)
+ public function hasMatched(array $tokens): bool
{
$token = \array_pop($tokens);
$prevToken = \array_pop($tokens);
diff --git a/vendor/psy/psysh/src/TabCompletion/Matcher/VariablesMatcher.php b/vendor/psy/psysh/src/TabCompletion/Matcher/VariablesMatcher.php
index f2438d3d1..6a5167f7c 100644
--- a/vendor/psy/psysh/src/TabCompletion/Matcher/VariablesMatcher.php
+++ b/vendor/psy/psysh/src/TabCompletion/Matcher/VariablesMatcher.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -23,7 +23,7 @@ class VariablesMatcher extends AbstractContextAwareMatcher
/**
* {@inheritdoc}
*/
- public function getMatches(array $tokens, array $info = [])
+ public function getMatches(array $tokens, array $info = []): array
{
$var = \str_replace('$', '', $this->getInput($tokens));
@@ -35,7 +35,7 @@ class VariablesMatcher extends AbstractContextAwareMatcher
/**
* {@inheritdoc}
*/
- public function hasMatched(array $tokens)
+ public function hasMatched(array $tokens): bool
{
$token = \array_pop($tokens);
diff --git a/vendor/psy/psysh/src/Util/Docblock.php b/vendor/psy/psysh/src/Util/Docblock.php
index 132d15d5f..416be0ee2 100644
--- a/vendor/psy/psysh/src/Util/Docblock.php
+++ b/vendor/psy/psysh/src/Util/Docblock.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -74,7 +74,10 @@ class Docblock
public function __construct(\Reflector $reflector)
{
$this->reflector = $reflector;
- $this->setComment($reflector->getDocComment());
+
+ if ($reflector instanceof \ReflectionClass || $reflector instanceof \ReflectionClassConstant || $reflector instanceof \ReflectionFunctionAbstract || $reflector instanceof \ReflectionProperty) {
+ $this->setComment($reflector->getDocComment());
+ }
}
/**
@@ -82,7 +85,7 @@ class Docblock
*
* @param string $comment The docblock
*/
- protected function setComment($comment)
+ protected function setComment(string $comment)
{
$this->desc = '';
$this->tags = [];
@@ -98,7 +101,7 @@ class Docblock
*
* @return int Prefix length
*/
- protected static function prefixLength(array $lines)
+ protected static function prefixLength(array $lines): int
{
// find only lines with interesting things
$lines = \array_filter($lines, function ($line) {
@@ -132,7 +135,7 @@ class Docblock
*
* @param string $comment The docblock
*/
- protected function parseComment($comment)
+ protected function parseComment(string $comment)
{
// Strip the opening and closing tags of the docblock
$comment = \substr($comment, 3, -2);
@@ -198,10 +201,8 @@ class Docblock
* Whether or not a docblock contains a given @tag.
*
* @param string $tag The name of the @tag to check for
- *
- * @return bool
*/
- public function hasTag($tag)
+ public function hasTag(string $tag): bool
{
return \is_array($this->tags) && \array_key_exists($tag, $this->tags);
}
@@ -211,10 +212,12 @@ class Docblock
*
* @param string $tag
*
- * @return array
+ * @return array|null
*/
- public function tag($tag)
+ public function tag(string $tag)
{
+ // TODO: Add proper null-type return values once the lowest PHP version supported is 7.1
+
return $this->hasTag($tag) ? $this->tags[$tag] : null;
}
@@ -222,10 +225,8 @@ class Docblock
* Whether or not a string begins with a @tag.
*
* @param string $str
- *
- * @return bool
*/
- public static function isTagged($str)
+ public static function isTagged(string $str): bool
{
return isset($str[1]) && $str[0] === '@' && !\preg_match('/[^A-Za-z]/', $str[1]);
}
@@ -237,7 +238,7 @@ class Docblock
*
* @return string|null
*/
- public static function strTag($str)
+ public static function strTag(string $str)
{
if (\preg_match('/^@[a-z0-9_]+/', $str, $matches)) {
return $matches[0];
diff --git a/vendor/psy/psysh/src/Util/Json.php b/vendor/psy/psysh/src/Util/Json.php
index d3884c27c..a7eebca95 100644
--- a/vendor/psy/psysh/src/Util/Json.php
+++ b/vendor/psy/psysh/src/Util/Json.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -21,10 +21,8 @@ class Json
*
* @param mixed $val
* @param int $opt
- *
- * @return string
*/
- public static function encode($val, $opt = 0)
+ public static function encode($val, int $opt = 0): string
{
$opt |= \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE;
diff --git a/vendor/psy/psysh/src/Util/Mirror.php b/vendor/psy/psysh/src/Util/Mirror.php
index 268a28d61..c151c06f2 100644
--- a/vendor/psy/psysh/src/Util/Mirror.php
+++ b/vendor/psy/psysh/src/Util/Mirror.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -43,7 +43,7 @@ class Mirror
*
* @return \Reflector
*/
- public static function get($value, $member = null, $filter = 15)
+ public static function get($value, string $member = null, int $filter = 15): \Reflector
{
if ($member === null && \is_string($value)) {
if (\function_exists($value)) {
@@ -104,7 +104,7 @@ class Mirror
/**
* Check declared namespaces for a given namespace.
*/
- private static function namespaceExists($value)
+ private static function namespaceExists(string $value): bool
{
return \in_array(\strtolower($value), self::getDeclaredNamespaces());
}
@@ -115,7 +115,7 @@ class Mirror
* Note that this relies on at least one function, class, interface, trait
* or constant to have been declared in that namespace.
*/
- private static function getDeclaredNamespaces()
+ private static function getDeclaredNamespaces(): array
{
$functions = \get_defined_functions();
diff --git a/vendor/psy/psysh/src/Util/Str.php b/vendor/psy/psysh/src/Util/Str.php
index 8fc0abc1a..032520dcf 100644
--- a/vendor/psy/psysh/src/Util/Str.php
+++ b/vendor/psy/psysh/src/Util/Str.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -56,12 +56,10 @@ EOS;
* except for the \s sequence (ASCII space).
*
* @param string $input The string to decode
- *
- * @return string
*/
- public static function unvis($input)
+ public static function unvis(string $input): string
{
- $output = \preg_replace_callback(self::UNVIS_RX, 'self::unvisReplace', $input);
+ $output = \preg_replace_callback(self::UNVIS_RX, [self::class, 'unvisReplace'], $input);
// other escapes & octal are handled by stripcslashes
return \stripcslashes($output);
}
@@ -70,10 +68,8 @@ EOS;
* Callback for Str::unvis.
*
* @param array $match The matches passed by preg_replace_callback
- *
- * @return string
*/
- protected static function unvisReplace($match)
+ protected static function unvisReplace(array $match): string
{
// \040, \s
if (!empty($match[1])) {
diff --git a/vendor/psy/psysh/src/VarDumper/Cloner.php b/vendor/psy/psysh/src/VarDumper/Cloner.php
index bbb658f82..e0aaab972 100644
--- a/vendor/psy/psysh/src/VarDumper/Cloner.php
+++ b/vendor/psy/psysh/src/VarDumper/Cloner.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -12,6 +12,7 @@
namespace Psy\VarDumper;
use Symfony\Component\VarDumper\Caster\Caster;
+use Symfony\Component\VarDumper\Cloner\Data;
use Symfony\Component\VarDumper\Cloner\Stub;
use Symfony\Component\VarDumper\Cloner\VarCloner;
@@ -25,7 +26,7 @@ class Cloner extends VarCloner
/**
* {@inheritdoc}
*/
- public function cloneVar($var, $filter = 0)
+ public function cloneVar($var, $filter = 0): Data
{
$this->filter = $filter;
@@ -35,7 +36,7 @@ class Cloner extends VarCloner
/**
* {@inheritdoc}
*/
- protected function castResource(Stub $stub, $isNested)
+ protected function castResource(Stub $stub, $isNested): array
{
return Caster::EXCLUDE_VERBOSE & $this->filter ? [] : parent::castResource($stub, $isNested);
}
diff --git a/vendor/psy/psysh/src/VarDumper/Dumper.php b/vendor/psy/psysh/src/VarDumper/Dumper.php
index 9ee3ef862..96c127e07 100644
--- a/vendor/psy/psysh/src/VarDumper/Dumper.php
+++ b/vendor/psy/psysh/src/VarDumper/Dumper.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -64,7 +64,7 @@ class Dumper extends CliDumper
}
}
- protected function style($style, $value, $attr = [])
+ protected function style($style, $value, $attr = []): string
{
if ('ref' === $style) {
$value = \strtr($value, '@', '#');
diff --git a/vendor/psy/psysh/src/VarDumper/Presenter.php b/vendor/psy/psysh/src/VarDumper/Presenter.php
index 2e294ac1e..7e54dac05 100644
--- a/vendor/psy/psysh/src/VarDumper/Presenter.php
+++ b/vendor/psy/psysh/src/VarDumper/Presenter.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -63,7 +63,7 @@ class Presenter
$this->cloner = new Cloner();
$this->cloner->addCasters(['*' => function ($obj, array $a, Stub $stub, $isNested, $filter = 0) {
if ($filter || $isNested) {
- if ($obj instanceof \Exception) {
+ if ($obj instanceof \Throwable) {
$a = Caster::filter($a, Caster::EXCLUDE_NOT_IMPORTANT | Caster::EXCLUDE_EMPTY, $this->exceptionsImportants);
} else {
$a = Caster::filter($a, Caster::EXCLUDE_PROTECTED | Caster::EXCLUDE_PRIVATE);
@@ -90,10 +90,8 @@ class Presenter
* Present a reference to the value.
*
* @param mixed $value
- *
- * @return string
*/
- public function presentRef($value)
+ public function presentRef($value): string
{
return $this->present($value, 0);
}
@@ -106,10 +104,8 @@ class Presenter
* @param mixed $value
* @param int $depth (default: null)
* @param int $options One of Presenter constants
- *
- * @return string
*/
- public function present($value, $depth = null, $options = 0)
+ public function present($value, int $depth = null, int $options = 0): string
{
$data = $this->cloner->cloneVar($value, !($options & self::VERBOSE) ? Caster::EXCLUDE_VERBOSE : 0);
diff --git a/vendor/psy/psysh/src/VarDumper/PresenterAware.php b/vendor/psy/psysh/src/VarDumper/PresenterAware.php
index d0c02ae33..47590fb3a 100644
--- a/vendor/psy/psysh/src/VarDumper/PresenterAware.php
+++ b/vendor/psy/psysh/src/VarDumper/PresenterAware.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
diff --git a/vendor/psy/psysh/src/VersionUpdater/Checker.php b/vendor/psy/psysh/src/VersionUpdater/Checker.php
index 5278d0217..4de48013f 100644
--- a/vendor/psy/psysh/src/VersionUpdater/Checker.php
+++ b/vendor/psy/psysh/src/VersionUpdater/Checker.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -19,13 +19,7 @@ interface Checker
const MONTHLY = 'monthly';
const NEVER = 'never';
- /**
- * @return bool
- */
- public function isLatest();
+ public function isLatest(): bool;
- /**
- * @return string
- */
- public function getLatest();
+ public function getLatest(): string;
}
diff --git a/vendor/psy/psysh/src/VersionUpdater/Downloader.php b/vendor/psy/psysh/src/VersionUpdater/Downloader.php
new file mode 100644
index 000000000..233db318b
--- /dev/null
+++ b/vendor/psy/psysh/src/VersionUpdater/Downloader.php
@@ -0,0 +1,43 @@
+tempDir = $tempDir;
+ }
+
+ /** {@inheritDoc} */
+ public function download(string $url): bool
+ {
+ $tempDir = $this->tempDir ?: \sys_get_temp_dir();
+ $this->outputFile = \tempnam($tempDir, 'psysh-archive-');
+ $targetName = $this->outputFile.'.tar.gz';
+
+ if (!\rename($this->outputFile, $targetName)) {
+ return false;
+ }
+
+ $this->outputFile = $targetName;
+
+ $outputHandle = \fopen($this->outputFile, 'w');
+ if (!$outputHandle) {
+ return false;
+ }
+ $curl = \curl_init();
+ \curl_setopt_array($curl, [
+ \CURLOPT_FAILONERROR => true,
+ \CURLOPT_HEADER => 0,
+ \CURLOPT_FOLLOWLOCATION => true,
+ \CURLOPT_TIMEOUT => 10,
+ \CURLOPT_FILE => $outputHandle,
+ \CURLOPT_HTTPHEADER => [
+ 'User-Agent' => 'PsySH/'.Shell::VERSION,
+ ],
+ ]);
+ \curl_setopt($curl, \CURLOPT_URL, $url);
+ $result = \curl_exec($curl);
+ $error = \curl_error($curl);
+ \curl_close($curl);
+
+ \fclose($outputHandle);
+
+ if (!$result) {
+ throw new ErrorException('cURL Error: '.$error);
+ }
+
+ return (bool) $result;
+ }
+
+ /** {@inheritDoc} */
+ public function getFilename(): string
+ {
+ return $this->outputFile;
+ }
+
+ /** {@inheritDoc} */
+ public function cleanup()
+ {
+ if (\file_exists($this->outputFile)) {
+ \unlink($this->outputFile);
+ }
+ }
+}
diff --git a/vendor/psy/psysh/src/VersionUpdater/Downloader/Factory.php b/vendor/psy/psysh/src/VersionUpdater/Downloader/Factory.php
new file mode 100644
index 000000000..e1cfd8465
--- /dev/null
+++ b/vendor/psy/psysh/src/VersionUpdater/Downloader/Factory.php
@@ -0,0 +1,31 @@
+tempDir = $tempDir;
+ }
+
+ /** {@inheritDoc} */
+ public function download(string $url): bool
+ {
+ $tempDir = $this->tempDir ?: \sys_get_temp_dir();
+ $this->outputFile = \tempnam($tempDir, 'psysh-archive-');
+ $targetName = $this->outputFile.'.tar.gz';
+
+ if (!\rename($this->outputFile, $targetName)) {
+ return false;
+ }
+
+ $this->outputFile = $targetName;
+
+ return (bool) \file_put_contents($this->outputFile, \file_get_contents($url));
+ }
+
+ /** {@inheritDoc} */
+ public function getFilename(): string
+ {
+ return $this->outputFile;
+ }
+
+ /** {@inheritDoc} */
+ public function cleanup()
+ {
+ if (\file_exists($this->outputFile)) {
+ \unlink($this->outputFile);
+ }
+ }
+}
diff --git a/vendor/psy/psysh/src/VersionUpdater/GitHubChecker.php b/vendor/psy/psysh/src/VersionUpdater/GitHubChecker.php
index 470cecad5..e1fc7cea7 100644
--- a/vendor/psy/psysh/src/VersionUpdater/GitHubChecker.php
+++ b/vendor/psy/psysh/src/VersionUpdater/GitHubChecker.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -19,10 +19,7 @@ class GitHubChecker implements Checker
private $latest;
- /**
- * @return bool
- */
- public function isLatest()
+ public function isLatest(): bool
{
// version_compare doesn't handle semver completely;
// strip pre-release and build metadata before comparing
@@ -31,10 +28,7 @@ class GitHubChecker implements Checker
return \version_compare($version, $this->getLatest(), '>=');
}
- /**
- * @return string
- */
- public function getLatest()
+ public function getLatest(): string
{
if (!isset($this->latest)) {
$this->setLatest($this->getVersionFromTag());
@@ -46,7 +40,7 @@ class GitHubChecker implements Checker
/**
* @param string $version
*/
- public function setLatest($version)
+ public function setLatest(string $version)
{
$this->latest = $version;
}
@@ -75,7 +69,7 @@ class GitHubChecker implements Checker
$context = \stream_context_create([
'http' => [
'user_agent' => 'PsySH/'.Shell::VERSION,
- 'timeout' => 3,
+ 'timeout' => 1.0,
],
]);
diff --git a/vendor/psy/psysh/src/VersionUpdater/Installer.php b/vendor/psy/psysh/src/VersionUpdater/Installer.php
new file mode 100644
index 000000000..eb20cb865
--- /dev/null
+++ b/vendor/psy/psysh/src/VersionUpdater/Installer.php
@@ -0,0 +1,143 @@
+tempDirectory = $tempDirectory ?: \sys_get_temp_dir();
+ $this->installLocation = \Phar::running(false);
+ }
+
+ /**
+ * Public to allow the Downloader to use the temporary directory if it's been set.
+ */
+ public function getTempDirectory(): string
+ {
+ return $this->tempDirectory;
+ }
+
+ /**
+ * Verify the currently installed PsySH phar is writable so it can be replaced.
+ */
+ public function isInstallLocationWritable(): bool
+ {
+ return \is_writable($this->installLocation);
+ }
+
+ /**
+ * Verify the temporary directory is writable so downloads and backups can be saved there.
+ */
+ public function isTempDirectoryWritable(): bool
+ {
+ return \is_writable($this->tempDirectory);
+ }
+
+ /**
+ * Verifies the downloaded archive can be extracted with \PharData.
+ *
+ * @param string $sourceArchive
+ */
+ public function isValidSource(string $sourceArchive): bool
+ {
+ if (!\class_exists('\PharData')) {
+ return false;
+ }
+ $pharArchive = new \PharData($sourceArchive);
+
+ return $pharArchive->valid();
+ }
+
+ /**
+ * Extract the "psysh" phar from the archive and move it, replacing the currently installed phar.
+ *
+ * @param string $sourceArchive
+ */
+ public function install(string $sourceArchive): bool
+ {
+ $pharArchive = new \PharData($sourceArchive);
+ $outputDirectory = \tempnam($this->tempDirectory, 'psysh-');
+
+ // remove the temp file, and replace it with a sub-directory
+ if (!\unlink($outputDirectory) || !\mkdir($outputDirectory, 0700)) {
+ return false;
+ }
+
+ $pharArchive->extractTo($outputDirectory, ['psysh'], true);
+
+ $renamed = \rename($outputDirectory.'/psysh', $this->installLocation);
+
+ // Remove the sub-directory created to extract the psysh binary/phar
+ \rmdir($outputDirectory);
+
+ return $renamed;
+ }
+
+ /**
+ * Create a backup of the currently installed PsySH phar in the temporary directory with a version number postfix.
+ *
+ * @param string $version
+ */
+ public function createBackup(string $version): bool
+ {
+ $backupFilename = $this->getBackupFilename($version);
+
+ if (\file_exists($backupFilename) && !\is_writable($backupFilename)) {
+ return false;
+ }
+
+ return \rename($this->installLocation, $backupFilename);
+ }
+
+ /**
+ * Restore the backup file to the original PsySH install location.
+ *
+ * @param string $version
+ *
+ * @throws ErrorException If the backup file could not be found
+ */
+ public function restoreFromBackup(string $version): bool
+ {
+ $backupFilename = $this->getBackupFilename($version);
+
+ if (!\file_exists($backupFilename)) {
+ throw new ErrorException("Cannot restore from backup. File not found! [{$backupFilename}]");
+ }
+
+ return \rename($backupFilename, $this->installLocation);
+ }
+
+ /**
+ * Get the full path for the backup target file location.
+ *
+ * @param string $version
+ */
+ public function getBackupFilename(string $version): string
+ {
+ $installFilename = \basename($this->installLocation);
+
+ return \sprintf('%s/%s.%s', $this->tempDirectory, $installFilename, $version);
+ }
+}
diff --git a/vendor/psy/psysh/src/VersionUpdater/IntervalChecker.php b/vendor/psy/psysh/src/VersionUpdater/IntervalChecker.php
index 5c43b29d5..06a67775a 100644
--- a/vendor/psy/psysh/src/VersionUpdater/IntervalChecker.php
+++ b/vendor/psy/psysh/src/VersionUpdater/IntervalChecker.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -43,7 +43,10 @@ class IntervalChecker extends GitHubChecker
return $release;
}
- private function getDateInterval()
+ /**
+ * @throws \RuntimeException if interval passed to constructor is not supported
+ */
+ private function getDateInterval(): \DateInterval
{
switch ($this->interval) {
case Checker::DAILY:
@@ -53,6 +56,8 @@ class IntervalChecker extends GitHubChecker
case Checker::MONTHLY:
return new \DateInterval('P1M');
}
+
+ throw new \RuntimeException('Invalid interval configured');
}
private function updateCache($release)
diff --git a/vendor/psy/psysh/src/VersionUpdater/NoopChecker.php b/vendor/psy/psysh/src/VersionUpdater/NoopChecker.php
index 22340f763..2c8240e65 100644
--- a/vendor/psy/psysh/src/VersionUpdater/NoopChecker.php
+++ b/vendor/psy/psysh/src/VersionUpdater/NoopChecker.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -14,22 +14,16 @@ namespace Psy\VersionUpdater;
use Psy\Shell;
/**
- * A version checker stub which always thinks the current verion is up to date.
+ * A version checker stub which always thinks the current version is up to date.
*/
class NoopChecker implements Checker
{
- /**
- * @return bool
- */
- public function isLatest()
+ public function isLatest(): bool
{
return true;
}
- /**
- * @return string
- */
- public function getLatest()
+ public function getLatest(): string
{
return Shell::VERSION;
}
diff --git a/vendor/psy/psysh/src/VersionUpdater/SelfUpdate.php b/vendor/psy/psysh/src/VersionUpdater/SelfUpdate.php
new file mode 100644
index 000000000..dbda8716c
--- /dev/null
+++ b/vendor/psy/psysh/src/VersionUpdater/SelfUpdate.php
@@ -0,0 +1,186 @@
+checker = $checker;
+ $this->installer = $installer;
+ }
+
+ /**
+ * Allow the downloader to be injected for testing.
+ *
+ * @param Downloader $downloader
+ *
+ * @return void
+ */
+ public function setDownloader(Downloader $downloader)
+ {
+ $this->downloader = $downloader;
+ }
+
+ /**
+ * Get the currently set Downloader or create one based on the capabilities of the php environment.
+ *
+ * @throws ErrorException if a downloader cannot be created for the php environment
+ */
+ private function getDownloader(): Downloader
+ {
+ if (!isset($this->downloader)) {
+ return Downloader\Factory::getDownloader();
+ }
+
+ return $this->downloader;
+ }
+
+ /**
+ * Build the download URL for the latest release.
+ *
+ * The file name used in the URL will include the flavour postfix extracted from the current version
+ * if it's present
+ *
+ * @param string $latestVersion
+ */
+ private function getAssetUrl(string $latestVersion): string
+ {
+ $versionPostfix = '';
+ if (\strpos(Shell::VERSION, '+')) {
+ $versionPostfix = '-'.\substr(Shell::VERSION, \strpos(Shell::VERSION, '+') + 1);
+ }
+ $downloadFilename = \sprintf('psysh-%s%s.tar.gz', $latestVersion, $versionPostfix);
+
+ // check if latest release data contains an asset matching the filename?
+
+ return \sprintf('%s/%s/%s', self::URL_PREFIX, $latestVersion, $downloadFilename);
+ }
+
+ /**
+ * Execute the self-update process.
+ *
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ *
+ * @throws ErrorException if the current version is not restored when installation fails
+ */
+ public function run(InputInterface $input, OutputInterface $output): int
+ {
+ $currentVersion = Shell::VERSION;
+
+ // already have the latest version?
+ if ($this->checker->isLatest()) {
+ // current version is latest version...
+ $output->writeln('Current version is up-to-date. ');
+
+ return self::SUCCESS;
+ }
+
+ // can overwrite current version?
+ if (!$this->installer->isInstallLocationWritable()) {
+ $output->writeln('Installed version is not writable. ');
+
+ return self::FAILURE;
+ }
+ // can download to, and create a backup in the temp directory?
+ if (!$this->installer->isTempDirectoryWritable()) {
+ $output->writeln('Temporary directory is not writable. ');
+
+ return self::FAILURE;
+ }
+
+ $latestVersion = $this->checker->getLatest();
+ $downloadUrl = $this->getAssetUrl($latestVersion);
+
+ $output->write("Downloading PsySH $latestVersion ...");
+
+ try {
+ $downloader = $this->getDownloader();
+ $downloader->setTempDir($this->installer->getTempDirectory());
+ $downloaded = $downloader->download($downloadUrl);
+ } catch (ErrorException $e) {
+ $output->write(' Failed. ');
+ $output->writeln(\sprintf('%s ', $e->getMessage()));
+
+ return self::FAILURE;
+ }
+
+ if (!$downloaded) {
+ $output->writeln('Download failed. ');
+ $downloader->cleanup();
+
+ return self::FAILURE;
+ } else {
+ $output->write(' OK '.\PHP_EOL);
+ }
+
+ $downloadedFile = $downloader->getFilename();
+
+ if (!$this->installer->isValidSource($downloadedFile)) {
+ $downloader->cleanup();
+ $output->writeln('Downloaded file is not a valid archive. ');
+
+ return self::FAILURE;
+ }
+
+ // create backup as bin.old-version in the temporary directory
+ $backupCreated = $this->installer->createBackup($currentVersion);
+ if (!$backupCreated) {
+ $downloader->cleanup();
+ $output->writeln('Failed to create a backup of the current version. ');
+
+ return self::FAILURE;
+ } elseif ($input->getOption('verbose')) {
+ $backupFilename = $this->installer->getBackupFilename($currentVersion);
+ $output->writeln('Created backup of current version: '.$backupFilename);
+ }
+
+ if (!$this->installer->install($downloadedFile)) {
+ $this->installer->restoreFromBackup($currentVersion);
+ $downloader->cleanup();
+ $output->writeln("Failed to install new PsySH version $latestVersion. ");
+
+ return self::FAILURE;
+ }
+
+ // Remove the downloaded archive file from the temporary directory
+ $downloader->cleanup();
+
+ $output->writeln("Updated PsySH from $currentVersion to $latestVersion ");
+
+ return self::SUCCESS;
+ }
+}
diff --git a/vendor/psy/psysh/src/functions.php b/vendor/psy/psysh/src/functions.php
index 0f78d04ae..7445bf81c 100644
--- a/vendor/psy/psysh/src/functions.php
+++ b/vendor/psy/psysh/src/functions.php
@@ -3,7 +3,7 @@
/*
* This file is part of Psy Shell.
*
- * (c) 2012-2020 Justin Hileman
+ * (c) 2012-2023 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
@@ -13,6 +13,8 @@ namespace Psy;
use Psy\ExecutionLoop\ProcessForker;
use Psy\VersionUpdater\GitHubChecker;
+use Psy\VersionUpdater\Installer;
+use Psy\VersionUpdater\SelfUpdate;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
@@ -23,10 +25,8 @@ if (!\function_exists('Psy\\sh')) {
* Command to return the eval-able code to startup PsySH.
*
* eval(\Psy\sh());
- *
- * @return string
*/
- function sh()
+ function sh(): string
{
if (\version_compare(\PHP_VERSION, '8.0', '<')) {
return '\extract(\Psy\debug(\get_defined_vars(), isset($this) ? $this : @\get_called_class()));';
@@ -90,7 +90,7 @@ if (!\function_exists('Psy\\debug')) {
*
* @return array Scope variables from the debugger session
*/
- function debug(array $vars = [], $bindTo = null)
+ function debug(array $vars = [], $bindTo = null): array
{
echo \PHP_EOL;
@@ -183,7 +183,7 @@ if (!\function_exists('Psy\\info')) {
try {
$updateAvailable = !$checker->isLatest();
$latest = $checker->getLatest();
- } catch (\Exception $e) {
+ } catch (\Throwable $e) {
}
$updates = [
@@ -225,6 +225,7 @@ if (!\function_exists('Psy\\info')) {
'color mode' => $config->colorMode(),
'output decorated' => $config->getOutputDecorated(),
'output verbosity' => $config->verbosity(),
+ 'output pager' => $config->getPager(),
];
$pcntl = [
@@ -327,27 +328,17 @@ if (!\function_exists('Psy\\bin')) {
*
* @return \Closure
*/
- function bin()
+ function bin(): \Closure
{
return function () {
if (!isset($_SERVER['PSYSH_IGNORE_ENV']) || !$_SERVER['PSYSH_IGNORE_ENV']) {
- if (\defined('HHVM_VERSION_ID') && HHVM_VERSION_ID < 31800) {
- \fwrite(\STDERR, 'HHVM 3.18 or higher is required. You can set the environment variable PSYSH_IGNORE_ENV=1 to override this restriction and proceed anyway.'.\PHP_EOL);
+ if (\defined('HHVM_VERSION_ID')) {
+ \fwrite(\STDERR, 'PsySH v0.11 and higher does not support HHVM. Install an older version, or set the environment variable PSYSH_IGNORE_ENV=1 to override this restriction and proceed anyway.'.\PHP_EOL);
exit(1);
}
- if (\defined('HHVM_VERSION_ID') && HHVM_VERSION_ID > 39999) {
- \fwrite(\STDERR, 'HHVM 4 or higher is not supported. You can set the environment variable PSYSH_IGNORE_ENV=1 to override this restriction and proceed anyway.'.\PHP_EOL);
- exit(1);
- }
-
- if (\PHP_VERSION_ID < 50509) {
- \fwrite(\STDERR, 'PHP 5.5.9 or higher is required. You can set the environment variable PSYSH_IGNORE_ENV=1 to override this restriction and proceed anyway.'.\PHP_EOL);
- exit(1);
- }
-
- if (\PHP_VERSION_ID < 50600 && \Phar::running()) {
- \fwrite(\STDERR, 'PHP 5.6.0 or higher is required. You can set the environment variable PSYSH_IGNORE_ENV=1 to override this restriction and proceed anyway.'.\PHP_EOL);
+ if (\PHP_VERSION_ID < 70000) {
+ \fwrite(\STDERR, 'PHP 7.0.0 or higher is required. You can set the environment variable PSYSH_IGNORE_ENV=1 to override this restriction and proceed anyway.'.\PHP_EOL);
exit(1);
}
@@ -368,12 +359,14 @@ if (!\function_exists('Psy\\bin')) {
}
$usageException = null;
+ $shellIsPhar = Shell::isPhar();
$input = new ArgvInput();
try {
$input->bind(new InputDefinition(\array_merge(Configuration::getInputOptions(), [
new InputOption('help', 'h', InputOption::VALUE_NONE),
new InputOption('version', 'V', InputOption::VALUE_NONE),
+ new InputOption('self-update', 'u', InputOption::VALUE_NONE),
new InputArgument('include', InputArgument::IS_ARRAY),
])));
@@ -408,16 +401,27 @@ Options:
-c, --config FILE Use an alternate PsySH config file location.
--cwd PATH Use an alternate working directory.
-V, --version Display the PsySH version.
+
+EOL;
+ if ($shellIsPhar) {
+ echo <<getOption('self-update')) {
+ if (!$shellIsPhar) {
+ \fwrite(\STDERR, 'The --self-update option can only be used with with a phar based install.'.\PHP_EOL);
+ exit(1);
+ }
+ $selfUpdate = new SelfUpdate(new GitHubChecker(), new Installer());
+ $result = $selfUpdate->run($input, $config->getOutput());
+ exit($result);
+ }
+
$shell = new Shell($config);
// Pass additional arguments to Shell as 'includes'
@@ -435,7 +450,7 @@ EOL;
try {
// And go!
$shell->run();
- } catch (\Exception $e) {
+ } catch (\Throwable $e) {
\fwrite(\STDERR, $e->getMessage().\PHP_EOL);
// @todo this triggers the "exited unexpectedly" logic in the
diff --git a/vendor/ralouphie/getallheaders/LICENSE b/vendor/ralouphie/getallheaders/LICENSE
new file mode 100644
index 000000000..be5540c2a
--- /dev/null
+++ b/vendor/ralouphie/getallheaders/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Ralph Khattar
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/ralouphie/getallheaders/README.md b/vendor/ralouphie/getallheaders/README.md
new file mode 100644
index 000000000..9430d76bb
--- /dev/null
+++ b/vendor/ralouphie/getallheaders/README.md
@@ -0,0 +1,27 @@
+getallheaders
+=============
+
+PHP `getallheaders()` polyfill. Compatible with PHP >= 5.3.
+
+[](https://travis-ci.org/ralouphie/getallheaders)
+[](https://coveralls.io/r/ralouphie/getallheaders?branch=master)
+[](https://packagist.org/packages/ralouphie/getallheaders)
+[](https://packagist.org/packages/ralouphie/getallheaders)
+[](https://packagist.org/packages/ralouphie/getallheaders)
+
+
+This is a simple polyfill for [`getallheaders()`](http://www.php.net/manual/en/function.getallheaders.php).
+
+## Install
+
+For PHP version **`>= 5.6`**:
+
+```
+composer require ralouphie/getallheaders
+```
+
+For PHP version **`< 5.6`**:
+
+```
+composer require ralouphie/getallheaders "^2"
+```
diff --git a/vendor/ralouphie/getallheaders/composer.json b/vendor/ralouphie/getallheaders/composer.json
new file mode 100644
index 000000000..de8ce62e4
--- /dev/null
+++ b/vendor/ralouphie/getallheaders/composer.json
@@ -0,0 +1,26 @@
+{
+ "name": "ralouphie/getallheaders",
+ "description": "A polyfill for getallheaders.",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Ralph Khattar",
+ "email": "ralph.khattar@gmail.com"
+ }
+ ],
+ "require": {
+ "php": ">=5.6"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5 || ^6.5",
+ "php-coveralls/php-coveralls": "^2.1"
+ },
+ "autoload": {
+ "files": ["src/getallheaders.php"]
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "getallheaders\\Tests\\": "tests/"
+ }
+ }
+}
diff --git a/vendor/ralouphie/getallheaders/src/getallheaders.php b/vendor/ralouphie/getallheaders/src/getallheaders.php
new file mode 100644
index 000000000..c7285a5ba
--- /dev/null
+++ b/vendor/ralouphie/getallheaders/src/getallheaders.php
@@ -0,0 +1,46 @@
+ 'Content-Type',
+ 'CONTENT_LENGTH' => 'Content-Length',
+ 'CONTENT_MD5' => 'Content-Md5',
+ );
+
+ foreach ($_SERVER as $key => $value) {
+ if (substr($key, 0, 5) === 'HTTP_') {
+ $key = substr($key, 5);
+ if (!isset($copy_server[$key]) || !isset($_SERVER[$key])) {
+ $key = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', $key))));
+ $headers[$key] = $value;
+ }
+ } elseif (isset($copy_server[$key])) {
+ $headers[$copy_server[$key]] = $value;
+ }
+ }
+
+ if (!isset($headers['Authorization'])) {
+ if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
+ $headers['Authorization'] = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
+ } elseif (isset($_SERVER['PHP_AUTH_USER'])) {
+ $basic_pass = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : '';
+ $headers['Authorization'] = 'Basic ' . base64_encode($_SERVER['PHP_AUTH_USER'] . ':' . $basic_pass);
+ } elseif (isset($_SERVER['PHP_AUTH_DIGEST'])) {
+ $headers['Authorization'] = $_SERVER['PHP_AUTH_DIGEST'];
+ }
+ }
+
+ return $headers;
+ }
+
+}
diff --git a/vendor/ramsey/uuid/README.md b/vendor/ramsey/uuid/README.md
index 544df1aa3..491429df9 100644
--- a/vendor/ramsey/uuid/README.md
+++ b/vendor/ramsey/uuid/README.md
@@ -175,7 +175,7 @@ information.
[badge-upgrade]: https://img.shields.io/packagist/v/ramsey/uuid.svg?style=flat-square&label=upgrade&colorB=darkred
[badge-license]: https://img.shields.io/packagist/l/ramsey/uuid.svg?style=flat-square&colorB=darkcyan
[badge-php]: https://img.shields.io/packagist/php-v/ramsey/uuid/3.x-dev.svg?style=flat-square&colorB=%238892BF
-[badge-build]: https://img.shields.io/github/workflow/status/ramsey/uuid/build/3.x.svg?logo=github&style=flat-square
+[badge-build]: https://img.shields.io/github/actions/workflow/status/ramsey/uuid/continuous-integration.yml?branch=3.x&logo=github&style=flat-square
[badge-coverage]: https://img.shields.io/codecov/c/gh/ramsey/uuid/3.x.svg?style=flat-square&logo=codecov
[source]: https://github.com/ramsey/uuid/tree/3.x
diff --git a/vendor/ramsey/uuid/composer.json b/vendor/ramsey/uuid/composer.json
index a6185952d..8f5505d9f 100644
--- a/vendor/ramsey/uuid/composer.json
+++ b/vendor/ramsey/uuid/composer.json
@@ -51,11 +51,12 @@
"paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter"
},
"config": {
- "sort-packages": true
- },
- "extra": {
- "branch-alias": {
- "dev-master": "3.x-dev"
+ "sort-packages": true,
+ "allow-plugins": {
+ "phpstan/extension-installer": true,
+ "dealerdirect/phpcodesniffer-composer-installer": true,
+ "ergebnis/composer-normalize": true,
+ "captainhook/plugin-composer": true
}
},
"replace": {
diff --git a/vendor/ramsey/uuid/src/Uuid.php b/vendor/ramsey/uuid/src/Uuid.php
index d51e0e1ad..1744d28dd 100644
--- a/vendor/ramsey/uuid/src/Uuid.php
+++ b/vendor/ramsey/uuid/src/Uuid.php
@@ -213,6 +213,7 @@ class Uuid implements UuidInterface
* @return string
* @link http://php.net/manual/en/class.jsonserializable.php
*/
+ #[ReturnTypeWillChange]
public function jsonSerialize()
{
return $this->toString();
diff --git a/vendor/symfony/css-selector/CssSelectorConverter.php b/vendor/symfony/css-selector/CssSelectorConverter.php
index d1aeb7eb1..bbb6afe21 100644
--- a/vendor/symfony/css-selector/CssSelectorConverter.php
+++ b/vendor/symfony/css-selector/CssSelectorConverter.php
@@ -27,6 +27,10 @@ use Symfony\Component\CssSelector\XPath\Translator;
class CssSelectorConverter
{
private $translator;
+ private $cache;
+
+ private static $xmlCache = [];
+ private static $htmlCache = [];
/**
* @param bool $html Whether HTML support should be enabled. Disable it for XML documents
@@ -37,6 +41,9 @@ class CssSelectorConverter
if ($html) {
$this->translator->registerExtension(new HtmlExtension($this->translator));
+ $this->cache = &self::$htmlCache;
+ } else {
+ $this->cache = &self::$xmlCache;
}
$this->translator
@@ -53,13 +60,10 @@ class CssSelectorConverter
* Optionally, a prefix can be added to the resulting XPath
* expression with the $prefix parameter.
*
- * @param string $cssExpr The CSS expression
- * @param string $prefix An optional prefix for the XPath expression
- *
* @return string
*/
- public function toXPath($cssExpr, $prefix = 'descendant-or-self::')
+ public function toXPath(string $cssExpr, string $prefix = 'descendant-or-self::')
{
- return $this->translator->cssToXPath($cssExpr, $prefix);
+ return $this->cache[$prefix][$cssExpr] ?? $this->cache[$prefix][$cssExpr] = $this->translator->cssToXPath($cssExpr, $prefix);
}
}
diff --git a/vendor/symfony/css-selector/Exception/SyntaxErrorException.php b/vendor/symfony/css-selector/Exception/SyntaxErrorException.php
index 1200c979e..7deacf9c5 100644
--- a/vendor/symfony/css-selector/Exception/SyntaxErrorException.php
+++ b/vendor/symfony/css-selector/Exception/SyntaxErrorException.php
@@ -24,32 +24,25 @@ use Symfony\Component\CssSelector\Parser\Token;
class SyntaxErrorException extends ParseException
{
/**
- * @param string $expectedValue
- *
* @return self
*/
- public static function unexpectedToken($expectedValue, Token $foundToken)
+ public static function unexpectedToken(string $expectedValue, Token $foundToken)
{
return new self(sprintf('Expected %s, but %s found.', $expectedValue, $foundToken));
}
/**
- * @param string $pseudoElement
- * @param string $unexpectedLocation
- *
* @return self
*/
- public static function pseudoElementFound($pseudoElement, $unexpectedLocation)
+ public static function pseudoElementFound(string $pseudoElement, string $unexpectedLocation)
{
return new self(sprintf('Unexpected pseudo-element "::%s" found %s.', $pseudoElement, $unexpectedLocation));
}
/**
- * @param int $position
- *
* @return self
*/
- public static function unclosedString($position)
+ public static function unclosedString(int $position)
{
return new self(sprintf('Unclosed/invalid string at %s.', $position));
}
diff --git a/vendor/symfony/css-selector/LICENSE b/vendor/symfony/css-selector/LICENSE
index 88bf75bb4..008370457 100644
--- a/vendor/symfony/css-selector/LICENSE
+++ b/vendor/symfony/css-selector/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2022 Fabien Potencier
+Copyright (c) 2004-2023 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/vendor/symfony/css-selector/Parser/TokenStream.php b/vendor/symfony/css-selector/Parser/TokenStream.php
index f4c2585aa..2085f2dd7 100644
--- a/vendor/symfony/css-selector/Parser/TokenStream.php
+++ b/vendor/symfony/css-selector/Parser/TokenStream.php
@@ -118,9 +118,7 @@ class TokenStream
}
/**
- * Returns nex identifier token.
- *
- * @return string The identifier token value
+ * Returns next identifier token.
*
* @throws SyntaxErrorException If next token is not an identifier
*/
@@ -136,9 +134,7 @@ class TokenStream
}
/**
- * Returns nex identifier or star delimiter token.
- *
- * @return string|null The identifier token value or null if star found
+ * Returns next identifier or null if star delimiter token is found.
*
* @throws SyntaxErrorException If next token is not an identifier or a star delimiter
*/
diff --git a/vendor/symfony/css-selector/Parser/Tokenizer/TokenizerPatterns.php b/vendor/symfony/css-selector/Parser/Tokenizer/TokenizerPatterns.php
index 5f16ac48f..2e78a1c4d 100644
--- a/vendor/symfony/css-selector/Parser/Tokenizer/TokenizerPatterns.php
+++ b/vendor/symfony/css-selector/Parser/Tokenizer/TokenizerPatterns.php
@@ -49,22 +49,22 @@ class TokenizerPatterns
$this->identifierPattern = '-?(?:'.$this->nmStartPattern.')(?:'.$this->nmCharPattern.')*';
$this->hashPattern = '#((?:'.$this->nmCharPattern.')+)';
$this->numberPattern = '[+-]?(?:[0-9]*\.[0-9]+|[0-9]+)';
- $this->quotedStringPattern = '([^\n\r\f%s]|'.$this->stringEscapePattern.')*';
+ $this->quotedStringPattern = '([^\n\r\f\\\\%s]|'.$this->stringEscapePattern.')*';
}
public function getNewLineEscapePattern(): string
{
- return '~^'.$this->newLineEscapePattern.'~';
+ return '~'.$this->newLineEscapePattern.'~';
}
public function getSimpleEscapePattern(): string
{
- return '~^'.$this->simpleEscapePattern.'~';
+ return '~'.$this->simpleEscapePattern.'~';
}
public function getUnicodeEscapePattern(): string
{
- return '~^'.$this->unicodeEscapePattern.'~i';
+ return '~'.$this->unicodeEscapePattern.'~i';
}
public function getIdentifierPattern(): string
diff --git a/vendor/symfony/css-selector/XPath/Translator.php b/vendor/symfony/css-selector/XPath/Translator.php
index 782aef458..8ce473036 100644
--- a/vendor/symfony/css-selector/XPath/Translator.php
+++ b/vendor/symfony/css-selector/XPath/Translator.php
@@ -203,7 +203,7 @@ class Translator implements TranslatorInterface
/**
* @throws ExpressionErrorException
*/
- public function addAttributeMatching(XPathExpr $xpath, string $operator, string $attribute, $value): XPathExpr
+ public function addAttributeMatching(XPathExpr $xpath, string $operator, string $attribute, ?string $value): XPathExpr
{
if (!isset($this->attributeMatchingTranslators[$operator])) {
throw new ExpressionErrorException(sprintf('Attribute matcher operator "%s" not supported.', $operator));
diff --git a/vendor/symfony/css-selector/XPath/XPathExpr.php b/vendor/symfony/css-selector/XPath/XPathExpr.php
index 638cbd0fe..e45ce7d8c 100644
--- a/vendor/symfony/css-selector/XPath/XPathExpr.php
+++ b/vendor/symfony/css-selector/XPath/XPathExpr.php
@@ -43,6 +43,9 @@ class XPathExpr
return $this->element;
}
+ /**
+ * @return $this
+ */
public function addCondition(string $condition): self
{
$this->condition = $this->condition ? sprintf('(%s) and (%s)', $this->condition, $condition) : $condition;
@@ -55,6 +58,9 @@ class XPathExpr
return $this->condition;
}
+ /**
+ * @return $this
+ */
public function addNameTest(): self
{
if ('*' !== $this->element) {
@@ -65,6 +71,9 @@ class XPathExpr
return $this;
}
+ /**
+ * @return $this
+ */
public function addStarPrefix(): self
{
$this->path .= '*/';
diff --git a/vendor/symfony/css-selector/composer.json b/vendor/symfony/css-selector/composer.json
index e8ecfee7a..f0b712495 100644
--- a/vendor/symfony/css-selector/composer.json
+++ b/vendor/symfony/css-selector/composer.json
@@ -20,7 +20,7 @@
}
],
"require": {
- "php": ">=7.1.3",
+ "php": ">=7.2.5",
"symfony/polyfill-php80": "^1.16"
},
"autoload": {
diff --git a/vendor/symfony/deprecation-contracts/.gitignore b/vendor/symfony/deprecation-contracts/.gitignore
new file mode 100644
index 000000000..c49a5d8df
--- /dev/null
+++ b/vendor/symfony/deprecation-contracts/.gitignore
@@ -0,0 +1,3 @@
+vendor/
+composer.lock
+phpunit.xml
diff --git a/vendor/symfony/deprecation-contracts/CHANGELOG.md b/vendor/symfony/deprecation-contracts/CHANGELOG.md
new file mode 100644
index 000000000..7932e2613
--- /dev/null
+++ b/vendor/symfony/deprecation-contracts/CHANGELOG.md
@@ -0,0 +1,5 @@
+CHANGELOG
+=========
+
+The changelog is maintained for all Symfony contracts at the following URL:
+https://github.com/symfony/contracts/blob/main/CHANGELOG.md
diff --git a/vendor/symfony/deprecation-contracts/LICENSE b/vendor/symfony/deprecation-contracts/LICENSE
new file mode 100644
index 000000000..406242ff2
--- /dev/null
+++ b/vendor/symfony/deprecation-contracts/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2020-2022 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/symfony/deprecation-contracts/README.md b/vendor/symfony/deprecation-contracts/README.md
new file mode 100644
index 000000000..4957933a6
--- /dev/null
+++ b/vendor/symfony/deprecation-contracts/README.md
@@ -0,0 +1,26 @@
+Symfony Deprecation Contracts
+=============================
+
+A generic function and convention to trigger deprecation notices.
+
+This package provides a single global function named `trigger_deprecation()` that triggers silenced deprecation notices.
+
+By using a custom PHP error handler such as the one provided by the Symfony ErrorHandler component,
+the triggered deprecations can be caught and logged for later discovery, both on dev and prod environments.
+
+The function requires at least 3 arguments:
+ - the name of the Composer package that is triggering the deprecation
+ - the version of the package that introduced the deprecation
+ - the message of the deprecation
+ - more arguments can be provided: they will be inserted in the message using `printf()` formatting
+
+Example:
+```php
+trigger_deprecation('symfony/blockchain', '8.9', 'Using "%s" is deprecated, use "%s" instead.', 'bitcoin', 'fabcoin');
+```
+
+This will generate the following message:
+`Since symfony/blockchain 8.9: Using "bitcoin" is deprecated, use "fabcoin" instead.`
+
+While not necessarily recommended, the deprecation notices can be completely ignored by declaring an empty
+`function trigger_deprecation() {}` in your application.
diff --git a/vendor/symfony/deprecation-contracts/composer.json b/vendor/symfony/deprecation-contracts/composer.json
new file mode 100644
index 000000000..cc7cc1237
--- /dev/null
+++ b/vendor/symfony/deprecation-contracts/composer.json
@@ -0,0 +1,35 @@
+{
+ "name": "symfony/deprecation-contracts",
+ "type": "library",
+ "description": "A generic function and convention to trigger deprecation notices",
+ "homepage": "https://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=7.1"
+ },
+ "autoload": {
+ "files": [
+ "function.php"
+ ]
+ },
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "2.5-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ }
+}
diff --git a/vendor/symfony/deprecation-contracts/function.php b/vendor/symfony/deprecation-contracts/function.php
new file mode 100644
index 000000000..d4371504a
--- /dev/null
+++ b/vendor/symfony/deprecation-contracts/function.php
@@ -0,0 +1,27 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+if (!function_exists('trigger_deprecation')) {
+ /**
+ * Triggers a silenced deprecation notice.
+ *
+ * @param string $package The name of the Composer package that is triggering the deprecation
+ * @param string $version The version of the package that introduced the deprecation
+ * @param string $message The message of the deprecation
+ * @param mixed ...$args Values to insert in the message using printf() formatting
+ *
+ * @author Nicolas Grekas
+ */
+ function trigger_deprecation(string $package, string $version, string $message, ...$args): void
+ {
+ @trigger_error(($package || $version ? "Since $package $version: " : '').($args ? vsprintf($message, $args) : $message), \E_USER_DEPRECATED);
+ }
+}
diff --git a/vendor/symfony/http-client-contracts/CHANGELOG.md b/vendor/symfony/http-client-contracts/CHANGELOG.md
new file mode 100644
index 000000000..7932e2613
--- /dev/null
+++ b/vendor/symfony/http-client-contracts/CHANGELOG.md
@@ -0,0 +1,5 @@
+CHANGELOG
+=========
+
+The changelog is maintained for all Symfony contracts at the following URL:
+https://github.com/symfony/contracts/blob/main/CHANGELOG.md
diff --git a/vendor/symfony/http-client-contracts/ChunkInterface.php b/vendor/symfony/http-client-contracts/ChunkInterface.php
index ad5efca9e..0800cb366 100644
--- a/vendor/symfony/http-client-contracts/ChunkInterface.php
+++ b/vendor/symfony/http-client-contracts/ChunkInterface.php
@@ -21,8 +21,6 @@ use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
* MUST be thrown by the destructor unless one was already thrown by another method.
*
* @author Nicolas Grekas
- *
- * @experimental in 1.1
*/
interface ChunkInterface
{
diff --git a/vendor/symfony/http-client-contracts/Exception/ClientExceptionInterface.php b/vendor/symfony/http-client-contracts/Exception/ClientExceptionInterface.php
index 5b5fa5084..22d2b456a 100644
--- a/vendor/symfony/http-client-contracts/Exception/ClientExceptionInterface.php
+++ b/vendor/symfony/http-client-contracts/Exception/ClientExceptionInterface.php
@@ -15,8 +15,6 @@ namespace Symfony\Contracts\HttpClient\Exception;
* When a 4xx response is returned.
*
* @author Nicolas Grekas
- *
- * @experimental in 1.1
*/
interface ClientExceptionInterface extends HttpExceptionInterface
{
diff --git a/vendor/symfony/http-client-contracts/Exception/DecodingExceptionInterface.php b/vendor/symfony/http-client-contracts/Exception/DecodingExceptionInterface.php
index 709db2189..971a7a29b 100644
--- a/vendor/symfony/http-client-contracts/Exception/DecodingExceptionInterface.php
+++ b/vendor/symfony/http-client-contracts/Exception/DecodingExceptionInterface.php
@@ -15,8 +15,6 @@ namespace Symfony\Contracts\HttpClient\Exception;
* When a content-type cannot be decoded to the expected representation.
*
* @author Nicolas Grekas
- *
- * @experimental in 1.1
*/
interface DecodingExceptionInterface extends ExceptionInterface
{
diff --git a/vendor/symfony/http-client-contracts/Exception/ExceptionInterface.php b/vendor/symfony/http-client-contracts/Exception/ExceptionInterface.php
index 6d59715f7..e553b47a1 100644
--- a/vendor/symfony/http-client-contracts/Exception/ExceptionInterface.php
+++ b/vendor/symfony/http-client-contracts/Exception/ExceptionInterface.php
@@ -15,8 +15,6 @@ namespace Symfony\Contracts\HttpClient\Exception;
* The base interface for all exceptions in the contract.
*
* @author Nicolas Grekas
- *
- * @experimental in 1.1
*/
interface ExceptionInterface extends \Throwable
{
diff --git a/vendor/symfony/http-client-contracts/Exception/HttpExceptionInterface.php b/vendor/symfony/http-client-contracts/Exception/HttpExceptionInterface.php
index 0e9f39f6e..17865ed36 100644
--- a/vendor/symfony/http-client-contracts/Exception/HttpExceptionInterface.php
+++ b/vendor/symfony/http-client-contracts/Exception/HttpExceptionInterface.php
@@ -17,8 +17,6 @@ use Symfony\Contracts\HttpClient\ResponseInterface;
* Base interface for HTTP-related exceptions.
*
* @author Anton Chernikov
- *
- * @experimental in 1.1
*/
interface HttpExceptionInterface extends ExceptionInterface
{
diff --git a/vendor/symfony/http-client-contracts/Exception/RedirectionExceptionInterface.php b/vendor/symfony/http-client-contracts/Exception/RedirectionExceptionInterface.php
index 8cdd3e70d..edd9b8a9b 100644
--- a/vendor/symfony/http-client-contracts/Exception/RedirectionExceptionInterface.php
+++ b/vendor/symfony/http-client-contracts/Exception/RedirectionExceptionInterface.php
@@ -15,8 +15,6 @@ namespace Symfony\Contracts\HttpClient\Exception;
* When a 3xx response is returned and the "max_redirects" option has been reached.
*
* @author Nicolas Grekas
- *
- * @experimental in 1.1
*/
interface RedirectionExceptionInterface extends HttpExceptionInterface
{
diff --git a/vendor/symfony/http-client-contracts/Exception/ServerExceptionInterface.php b/vendor/symfony/http-client-contracts/Exception/ServerExceptionInterface.php
index f994ba2dd..9bfe1354b 100644
--- a/vendor/symfony/http-client-contracts/Exception/ServerExceptionInterface.php
+++ b/vendor/symfony/http-client-contracts/Exception/ServerExceptionInterface.php
@@ -15,8 +15,6 @@ namespace Symfony\Contracts\HttpClient\Exception;
* When a 5xx response is returned.
*
* @author Nicolas Grekas
- *
- * @experimental in 1.1
*/
interface ServerExceptionInterface extends HttpExceptionInterface
{
diff --git a/vendor/symfony/http-client-contracts/Exception/TimeoutExceptionInterface.php b/vendor/symfony/http-client-contracts/Exception/TimeoutExceptionInterface.php
new file mode 100644
index 000000000..08acf9fb6
--- /dev/null
+++ b/vendor/symfony/http-client-contracts/Exception/TimeoutExceptionInterface.php
@@ -0,0 +1,21 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Contracts\HttpClient\Exception;
+
+/**
+ * When an idle timeout occurs.
+ *
+ * @author Nicolas Grekas
+ */
+interface TimeoutExceptionInterface extends TransportExceptionInterface
+{
+}
diff --git a/vendor/symfony/http-client-contracts/Exception/TransportExceptionInterface.php b/vendor/symfony/http-client-contracts/Exception/TransportExceptionInterface.php
index 1cdc30a2f..0c8d131a0 100644
--- a/vendor/symfony/http-client-contracts/Exception/TransportExceptionInterface.php
+++ b/vendor/symfony/http-client-contracts/Exception/TransportExceptionInterface.php
@@ -15,8 +15,6 @@ namespace Symfony\Contracts\HttpClient\Exception;
* When any error happens at the transport level.
*
* @author Nicolas Grekas
- *
- * @experimental in 1.1
*/
interface TransportExceptionInterface extends ExceptionInterface
{
diff --git a/vendor/symfony/http-client-contracts/HttpClientInterface.php b/vendor/symfony/http-client-contracts/HttpClientInterface.php
index 68afa7811..158c1a7d0 100644
--- a/vendor/symfony/http-client-contracts/HttpClientInterface.php
+++ b/vendor/symfony/http-client-contracts/HttpClientInterface.php
@@ -19,9 +19,9 @@ use Symfony\Contracts\HttpClient\Test\HttpClientTestCase;
*
* @see HttpClientTestCase for a reference test suite
*
- * @author Nicolas Grekas
+ * @method static withOptions(array $options) Returns a new instance of the client with new default options
*
- * @experimental in 1.1
+ * @author Nicolas Grekas
*/
interface HttpClientInterface
{
@@ -88,8 +88,8 @@ interface HttpClientInterface
/**
* Yields responses chunk by chunk as they complete.
*
- * @param ResponseInterface|ResponseInterface[]|iterable $responses One or more responses created by the current HTTP client
- * @param float|null $timeout The idle timeout before yielding timeout chunks
+ * @param ResponseInterface|iterable $responses One or more responses created by the current HTTP client
+ * @param float|null $timeout The idle timeout before yielding timeout chunks
*/
public function stream($responses, float $timeout = null): ResponseStreamInterface;
}
diff --git a/vendor/symfony/http-client-contracts/ResponseInterface.php b/vendor/symfony/http-client-contracts/ResponseInterface.php
index ad4a4687d..df7148816 100644
--- a/vendor/symfony/http-client-contracts/ResponseInterface.php
+++ b/vendor/symfony/http-client-contracts/ResponseInterface.php
@@ -22,8 +22,6 @@ use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
* A (lazily retrieved) HTTP response.
*
* @author Nicolas Grekas
- *
- * @experimental in 1.1
*/
interface ResponseInterface
{
diff --git a/vendor/symfony/http-client-contracts/ResponseStreamInterface.php b/vendor/symfony/http-client-contracts/ResponseStreamInterface.php
index dfff554df..fa3e5db6c 100644
--- a/vendor/symfony/http-client-contracts/ResponseStreamInterface.php
+++ b/vendor/symfony/http-client-contracts/ResponseStreamInterface.php
@@ -16,7 +16,7 @@ namespace Symfony\Contracts\HttpClient;
*
* @author Nicolas Grekas
*
- * @experimental in 1.1
+ * @extends \Iterator
*/
interface ResponseStreamInterface extends \Iterator
{
diff --git a/vendor/symfony/http-client-contracts/Test/HttpClientTestCase.php b/vendor/symfony/http-client-contracts/Test/HttpClientTestCase.php
index bce7a85c1..7acd6b79c 100644
--- a/vendor/symfony/http-client-contracts/Test/HttpClientTestCase.php
+++ b/vendor/symfony/http-client-contracts/Test/HttpClientTestCase.php
@@ -14,13 +14,12 @@ namespace Symfony\Contracts\HttpClient\Test;
use PHPUnit\Framework\TestCase;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
+use Symfony\Contracts\HttpClient\Exception\TimeoutExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
/**
* A reference test suite for HttpClientInterface implementations.
- *
- * @experimental in 1.1
*/
abstract class HttpClientTestCase extends TestCase
{
@@ -746,9 +745,35 @@ abstract class HttpClientTestCase extends TestCase
$response->getHeaders();
}
- public function testTimeoutOnStream()
+ public function testTimeoutIsNotAFatalError()
{
usleep(300000); // wait for the previous test to release the server
+ $client = $this->getHttpClient(__FUNCTION__);
+ $response = $client->request('GET', 'http://localhost:8057/timeout-body', [
+ 'timeout' => 0.25,
+ ]);
+
+ try {
+ $response->getContent();
+ $this->fail(TimeoutExceptionInterface::class.' expected');
+ } catch (TimeoutExceptionInterface $e) {
+ }
+
+ for ($i = 0; $i < 10; ++$i) {
+ try {
+ $this->assertSame('<1><2>', $response->getContent());
+ break;
+ } catch (TimeoutExceptionInterface $e) {
+ }
+ }
+
+ if (10 === $i) {
+ throw $e;
+ }
+ }
+
+ public function testTimeoutOnStream()
+ {
$client = $this->getHttpClient(__FUNCTION__);
$response = $client->request('GET', 'http://localhost:8057/timeout-body');
@@ -1093,4 +1118,20 @@ abstract class HttpClientTestCase extends TestCase
$this->assertLessThan(10, $duration);
}
+
+ public function testWithOptions()
+ {
+ $client = $this->getHttpClient(__FUNCTION__);
+ if (!method_exists($client, 'withOptions')) {
+ $this->markTestSkipped(sprintf('Not implementing "%s::withOptions()" is deprecated.', get_debug_type($client)));
+ }
+
+ $client2 = $client->withOptions(['base_uri' => 'http://localhost:8057/']);
+
+ $this->assertNotSame($client, $client2);
+ $this->assertSame(\get_class($client), \get_class($client2));
+
+ $response = $client2->request('GET', '/');
+ $this->assertSame(200, $response->getStatusCode());
+ }
}
diff --git a/vendor/symfony/http-client-contracts/Test/TestHttpServer.php b/vendor/symfony/http-client-contracts/Test/TestHttpServer.php
index a1fcc593a..55a744aef 100644
--- a/vendor/symfony/http-client-contracts/Test/TestHttpServer.php
+++ b/vendor/symfony/http-client-contracts/Test/TestHttpServer.php
@@ -14,9 +14,6 @@ namespace Symfony\Contracts\HttpClient\Test;
use Symfony\Component\Process\PhpExecutableFinder;
use Symfony\Component\Process\Process;
-/**
- * @experimental in 1.1
- */
class TestHttpServer
{
private static $process = [];
diff --git a/vendor/symfony/http-client-contracts/composer.json b/vendor/symfony/http-client-contracts/composer.json
index 2464d0817..b76cab852 100644
--- a/vendor/symfony/http-client-contracts/composer.json
+++ b/vendor/symfony/http-client-contracts/composer.json
@@ -16,7 +16,7 @@
}
],
"require": {
- "php": ">=7.1.3"
+ "php": ">=7.2.5"
},
"suggest": {
"symfony/http-client-implementation": ""
@@ -27,7 +27,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-main": "1.1-dev"
+ "dev-main": "2.5-dev"
},
"thanks": {
"name": "symfony/contracts",
diff --git a/vendor/symfony/http-kernel/HttpCache/Store.php b/vendor/symfony/http-kernel/HttpCache/Store.php
index eeb7a6ef9..43bd7c808 100644
--- a/vendor/symfony/http-kernel/HttpCache/Store.php
+++ b/vendor/symfony/http-kernel/HttpCache/Store.php
@@ -26,19 +26,29 @@ class Store implements StoreInterface
{
protected $root;
private $keyCache;
- private $locks;
+ private $locks = [];
+ private $options;
/**
+ * Constructor.
+ *
+ * The available options are:
+ *
+ * * private_headers Set of response headers that should not be stored
+ * when a response is cached. (default: Set-Cookie)
+ *
* @throws \RuntimeException
*/
- public function __construct(string $root)
+ public function __construct(string $root, array $options = [])
{
$this->root = $root;
if (!file_exists($this->root) && !@mkdir($this->root, 0777, true) && !is_dir($this->root)) {
throw new \RuntimeException(sprintf('Unable to create the store directory (%s).', $this->root));
}
$this->keyCache = new \SplObjectStorage();
- $this->locks = [];
+ $this->options = array_merge([
+ 'private_headers' => ['Set-Cookie'],
+ ], $options);
}
/**
@@ -215,6 +225,10 @@ class Store implements StoreInterface
$headers = $this->persistResponse($response);
unset($headers['age']);
+ foreach ($this->options['private_headers'] as $h) {
+ unset($headers[strtolower($h)]);
+ }
+
array_unshift($entries, [$storedEnv, $headers]);
if (!$this->save($key, serialize($entries))) {
diff --git a/vendor/symfony/http-kernel/Kernel.php b/vendor/symfony/http-kernel/Kernel.php
index be36bc634..7064edefb 100644
--- a/vendor/symfony/http-kernel/Kernel.php
+++ b/vendor/symfony/http-kernel/Kernel.php
@@ -76,11 +76,11 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
private static $freshCache = [];
- public const VERSION = '4.4.49';
- public const VERSION_ID = 40449;
+ public const VERSION = '4.4.50';
+ public const VERSION_ID = 40450;
public const MAJOR_VERSION = 4;
public const MINOR_VERSION = 4;
- public const RELEASE_VERSION = 49;
+ public const RELEASE_VERSION = 50;
public const EXTRA_VERSION = '';
public const END_OF_MAINTENANCE = '11/2022';
diff --git a/vendor/symfony/mime/Address.php b/vendor/symfony/mime/Address.php
index 246846dfe..ae83efd73 100644
--- a/vendor/symfony/mime/Address.php
+++ b/vendor/symfony/mime/Address.php
@@ -98,11 +98,20 @@ final class Address
if ($address instanceof self) {
return $address;
}
- if (\is_string($address)) {
- return self::fromString($address);
+
+ if (!\is_string($address)) {
+ throw new InvalidArgumentException(sprintf('An address can be an instance of Address or a string ("%s" given).', get_debug_type($address)));
}
- throw new InvalidArgumentException(sprintf('An address can be an instance of Address or a string ("%s") given).', \is_object($address) ? \get_class($address) : \gettype($address)));
+ if (false === strpos($address, '<')) {
+ return new self($address);
+ }
+
+ if (!preg_match(self::FROM_STRING_PATTERN, $address, $matches)) {
+ throw new InvalidArgumentException(sprintf('Could not parse "%s" to a "%s" instance.', $address, self::class));
+ }
+
+ return new self($matches['addrSpec'], trim($matches['displayName'], ' \'"'));
}
/**
@@ -120,14 +129,19 @@ final class Address
return $addrs;
}
+ /**
+ * @deprecated since Symfony 5.2, use "create()" instead.
+ */
public static function fromString(string $string): self
{
+ trigger_deprecation('symfony/mime', '5.2', '"%s()" is deprecated, use "%s::create()" instead.', __METHOD__, __CLASS__);
+
if (!str_contains($string, '<')) {
return new self($string, '');
}
if (!preg_match(self::FROM_STRING_PATTERN, $string, $matches)) {
- throw new InvalidArgumentException(sprintf('Could not parse "%s" to a "%s" instance.', $string, static::class));
+ throw new InvalidArgumentException(sprintf('Could not parse "%s" to a "%s" instance.', $string, self::class));
}
return new self($matches['addrSpec'], trim($matches['displayName'], ' \'"'));
diff --git a/vendor/symfony/mime/CHANGELOG.md b/vendor/symfony/mime/CHANGELOG.md
index 6148360dd..f272346c9 100644
--- a/vendor/symfony/mime/CHANGELOG.md
+++ b/vendor/symfony/mime/CHANGELOG.md
@@ -1,6 +1,12 @@
CHANGELOG
=========
+5.2.0
+-----
+
+ * Add support for DKIM
+ * Deprecated `Address::fromString()`, use `Address::create()` instead
+
4.4.0
-----
diff --git a/vendor/symfony/mime/CharacterStream.php b/vendor/symfony/mime/CharacterStream.php
index 6400a4aa6..238debde1 100644
--- a/vendor/symfony/mime/CharacterStream.php
+++ b/vendor/symfony/mime/CharacterStream.php
@@ -97,10 +97,7 @@ final class CharacterStream
}
}
if (\is_resource($input)) {
- $blocks = 512;
- if (stream_get_meta_data($input)['seekable'] ?? false) {
- rewind($input);
- }
+ $blocks = 16372;
while (false !== $read = fread($input, $blocks)) {
$this->write($read);
}
diff --git a/vendor/symfony/mime/Crypto/DkimOptions.php b/vendor/symfony/mime/Crypto/DkimOptions.php
new file mode 100644
index 000000000..171bb2583
--- /dev/null
+++ b/vendor/symfony/mime/Crypto/DkimOptions.php
@@ -0,0 +1,97 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Mime\Crypto;
+
+/**
+ * A helper providing autocompletion for available DkimSigner options.
+ *
+ * @author Fabien Potencier
+ */
+final class DkimOptions
+{
+ private $options = [];
+
+ public function toArray(): array
+ {
+ return $this->options;
+ }
+
+ /**
+ * @return $this
+ */
+ public function algorithm(string $algo): self
+ {
+ $this->options['algorithm'] = $algo;
+
+ return $this;
+ }
+
+ /**
+ * @return $this
+ */
+ public function signatureExpirationDelay(int $show): self
+ {
+ $this->options['signature_expiration_delay'] = $show;
+
+ return $this;
+ }
+
+ /**
+ * @return $this
+ */
+ public function bodyMaxLength(int $max): self
+ {
+ $this->options['body_max_length'] = $max;
+
+ return $this;
+ }
+
+ /**
+ * @return $this
+ */
+ public function bodyShowLength(bool $show): self
+ {
+ $this->options['body_show_length'] = $show;
+
+ return $this;
+ }
+
+ /**
+ * @return $this
+ */
+ public function headerCanon(string $canon): self
+ {
+ $this->options['header_canon'] = $canon;
+
+ return $this;
+ }
+
+ /**
+ * @return $this
+ */
+ public function bodyCanon(string $canon): self
+ {
+ $this->options['body_canon'] = $canon;
+
+ return $this;
+ }
+
+ /**
+ * @return $this
+ */
+ public function headersToIgnore(array $headers): self
+ {
+ $this->options['headers_to_ignore'] = $headers;
+
+ return $this;
+ }
+}
diff --git a/vendor/symfony/mime/Crypto/DkimSigner.php b/vendor/symfony/mime/Crypto/DkimSigner.php
new file mode 100644
index 000000000..f0f7091ed
--- /dev/null
+++ b/vendor/symfony/mime/Crypto/DkimSigner.php
@@ -0,0 +1,220 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Mime\Crypto;
+
+use Symfony\Component\Mime\Exception\InvalidArgumentException;
+use Symfony\Component\Mime\Exception\RuntimeException;
+use Symfony\Component\Mime\Header\UnstructuredHeader;
+use Symfony\Component\Mime\Message;
+use Symfony\Component\Mime\Part\AbstractPart;
+
+/**
+ * @author Fabien Potencier
+ *
+ * RFC 6376 and 8301
+ */
+final class DkimSigner
+{
+ public const CANON_SIMPLE = 'simple';
+ public const CANON_RELAXED = 'relaxed';
+
+ public const ALGO_SHA256 = 'rsa-sha256';
+ public const ALGO_ED25519 = 'ed25519-sha256'; // RFC 8463
+
+ private $key;
+ private $domainName;
+ private $selector;
+ private $defaultOptions;
+
+ /**
+ * @param string $pk The private key as a string or the path to the file containing the private key, should be prefixed with file:// (in PEM format)
+ * @param string $passphrase A passphrase of the private key (if any)
+ */
+ public function __construct(string $pk, string $domainName, string $selector, array $defaultOptions = [], string $passphrase = '')
+ {
+ if (!\extension_loaded('openssl')) {
+ throw new \LogicException('PHP extension "openssl" is required to use DKIM.');
+ }
+ if (!$this->key = openssl_pkey_get_private($pk, $passphrase)) {
+ throw new InvalidArgumentException('Unable to load DKIM private key: '.openssl_error_string());
+ }
+
+ $this->domainName = $domainName;
+ $this->selector = $selector;
+ $this->defaultOptions = $defaultOptions + [
+ 'algorithm' => self::ALGO_SHA256,
+ 'signature_expiration_delay' => 0,
+ 'body_max_length' => \PHP_INT_MAX,
+ 'body_show_length' => false,
+ 'header_canon' => self::CANON_RELAXED,
+ 'body_canon' => self::CANON_RELAXED,
+ 'headers_to_ignore' => [],
+ ];
+ }
+
+ public function sign(Message $message, array $options = []): Message
+ {
+ $options += $this->defaultOptions;
+ if (!\in_array($options['algorithm'], [self::ALGO_SHA256, self::ALGO_ED25519], true)) {
+ throw new InvalidArgumentException(sprintf('Invalid DKIM signing algorithm "%s".', $options['algorithm']));
+ }
+ $headersToIgnore['return-path'] = true;
+ $headersToIgnore['x-transport'] = true;
+ foreach ($options['headers_to_ignore'] as $name) {
+ $headersToIgnore[strtolower($name)] = true;
+ }
+ unset($headersToIgnore['from']);
+ $signedHeaderNames = [];
+ $headerCanonData = '';
+ $headers = $message->getPreparedHeaders();
+ foreach ($headers->getNames() as $name) {
+ foreach ($headers->all($name) as $header) {
+ if (isset($headersToIgnore[strtolower($header->getName())])) {
+ continue;
+ }
+
+ if ('' !== $header->getBodyAsString()) {
+ $headerCanonData .= $this->canonicalizeHeader($header->toString(), $options['header_canon']);
+ $signedHeaderNames[] = $header->getName();
+ }
+ }
+ }
+
+ [$bodyHash, $bodyLength] = $this->hashBody($message->getBody(), $options['body_canon'], $options['body_max_length']);
+
+ $params = [
+ 'v' => '1',
+ 'q' => 'dns/txt',
+ 'a' => $options['algorithm'],
+ 'bh' => base64_encode($bodyHash),
+ 'd' => $this->domainName,
+ 'h' => implode(': ', $signedHeaderNames),
+ 'i' => '@'.$this->domainName,
+ 's' => $this->selector,
+ 't' => time(),
+ 'c' => $options['header_canon'].'/'.$options['body_canon'],
+ ];
+
+ if ($options['body_show_length']) {
+ $params['l'] = $bodyLength;
+ }
+ if ($options['signature_expiration_delay']) {
+ $params['x'] = $params['t'] + $options['signature_expiration_delay'];
+ }
+ $value = '';
+ foreach ($params as $k => $v) {
+ $value .= $k.'='.$v.'; ';
+ }
+ $value = trim($value);
+ $header = new UnstructuredHeader('DKIM-Signature', $value);
+ $headerCanonData .= rtrim($this->canonicalizeHeader($header->toString()."\r\n b=", $options['header_canon']));
+ if (self::ALGO_SHA256 === $options['algorithm']) {
+ if (!openssl_sign($headerCanonData, $signature, $this->key, \OPENSSL_ALGO_SHA256)) {
+ throw new RuntimeException('Unable to sign DKIM hash: '.openssl_error_string());
+ }
+ } else {
+ throw new \RuntimeException(sprintf('The "%s" DKIM signing algorithm is not supported yet.', self::ALGO_ED25519));
+ }
+ $header->setValue($value.' b='.trim(chunk_split(base64_encode($signature), 73, ' ')));
+ $headers->add($header);
+
+ return new Message($headers, $message->getBody());
+ }
+
+ private function canonicalizeHeader(string $header, string $headerCanon): string
+ {
+ if (self::CANON_RELAXED !== $headerCanon) {
+ return $header."\r\n";
+ }
+
+ $exploded = explode(':', $header, 2);
+ $name = strtolower(trim($exploded[0]));
+ $value = str_replace("\r\n", '', $exploded[1]);
+ $value = trim(preg_replace("/[ \t][ \t]+/", ' ', $value));
+
+ return $name.':'.$value."\r\n";
+ }
+
+ private function hashBody(AbstractPart $body, string $bodyCanon, int $maxLength): array
+ {
+ $hash = hash_init('sha256');
+ $relaxed = self::CANON_RELAXED === $bodyCanon;
+ $currentLine = '';
+ $emptyCounter = 0;
+ $isSpaceSequence = false;
+ $length = 0;
+ foreach ($body->bodyToIterable() as $chunk) {
+ $canon = '';
+ for ($i = 0, $len = \strlen($chunk); $i < $len; ++$i) {
+ switch ($chunk[$i]) {
+ case "\r":
+ break;
+ case "\n":
+ // previous char is always \r
+ if ($relaxed) {
+ $isSpaceSequence = false;
+ }
+ if ('' === $currentLine) {
+ ++$emptyCounter;
+ } else {
+ $currentLine = '';
+ $canon .= "\r\n";
+ }
+ break;
+ case ' ':
+ case "\t":
+ if ($relaxed) {
+ $isSpaceSequence = true;
+ break;
+ }
+ // no break
+ default:
+ if ($emptyCounter > 0) {
+ $canon .= str_repeat("\r\n", $emptyCounter);
+ $emptyCounter = 0;
+ }
+ if ($isSpaceSequence) {
+ $currentLine .= ' ';
+ $canon .= ' ';
+ $isSpaceSequence = false;
+ }
+ $currentLine .= $chunk[$i];
+ $canon .= $chunk[$i];
+ }
+ }
+
+ if ($length + \strlen($canon) >= $maxLength) {
+ $canon = substr($canon, 0, $maxLength - $length);
+ $length += \strlen($canon);
+ hash_update($hash, $canon);
+
+ break;
+ }
+
+ $length += \strlen($canon);
+ hash_update($hash, $canon);
+ }
+
+ // Add trailing Line return if last line is non empty
+ if ('' !== $currentLine) {
+ hash_update($hash, "\r\n");
+ $length += \strlen("\r\n");
+ }
+
+ if (!$relaxed && 0 === $length) {
+ hash_update($hash, "\r\n");
+ $length = 2;
+ }
+
+ return [hash_final($hash, true), $length];
+ }
+}
diff --git a/vendor/symfony/mime/Crypto/SMime.php b/vendor/symfony/mime/Crypto/SMime.php
index 0f4643806..cba95f210 100644
--- a/vendor/symfony/mime/Crypto/SMime.php
+++ b/vendor/symfony/mime/Crypto/SMime.php
@@ -65,7 +65,7 @@ abstract class SMime
protected function getStreamIterator($stream): iterable
{
while (!feof($stream)) {
- yield fread($stream, 16372);
+ yield str_replace("\n", "\r\n", str_replace("\r\n", "\n", fread($stream, 16372)));
}
}
diff --git a/vendor/symfony/mime/DependencyInjection/AddMimeTypeGuesserPass.php b/vendor/symfony/mime/DependencyInjection/AddMimeTypeGuesserPass.php
index e24beb0da..00eef94ee 100644
--- a/vendor/symfony/mime/DependencyInjection/AddMimeTypeGuesserPass.php
+++ b/vendor/symfony/mime/DependencyInjection/AddMimeTypeGuesserPass.php
@@ -27,6 +27,10 @@ class AddMimeTypeGuesserPass implements CompilerPassInterface
public function __construct(string $mimeTypesService = 'mime_types', string $mimeTypeGuesserTag = 'mime.mime_type_guesser')
{
+ if (0 < \func_num_args()) {
+ trigger_deprecation('symfony/mime', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
+ }
+
$this->mimeTypesService = $mimeTypesService;
$this->mimeTypeGuesserTag = $mimeTypeGuesserTag;
}
diff --git a/vendor/symfony/mime/Email.php b/vendor/symfony/mime/Email.php
index 70ea74578..bd0a476c4 100644
--- a/vendor/symfony/mime/Email.php
+++ b/vendor/symfony/mime/Email.php
@@ -405,7 +405,7 @@ class Email extends Message
}
/**
- * @return DataPart[]
+ * @return array|DataPart[]
*/
public function getAttachments(): array
{
@@ -495,14 +495,8 @@ class Email extends Message
$htmlPart = null;
$html = $this->html;
if (null !== $html) {
- if (\is_resource($html)) {
- if (stream_get_meta_data($html)['seekable'] ?? false) {
- rewind($html);
- }
-
- $html = stream_get_contents($html);
- }
$htmlPart = new TextPart($html, $this->htmlCharset, 'html');
+ $html = $htmlPart->getBody();
preg_match_all('( ]*src\s*=\s*(?:([\'"])cid:(.+?)\\1|cid:([^>\s]+)))i', $html, $names);
$names = array_filter(array_unique(array_merge($names[2], $names[3])));
}
@@ -569,7 +563,7 @@ class Email extends Message
/**
* @return $this
*/
- private function setHeaderBody(string $type, string $name, $body)
+ private function setHeaderBody(string $type, string $name, $body): object
{
$this->getHeaders()->setHeaderBody($type, $name, $body);
@@ -586,6 +580,9 @@ class Email extends Message
return $this;
}
+ /**
+ * @return $this
+ */
private function setListAddressHeaderBody(string $name, array $addresses)
{
$addresses = Address::createArray($addresses);
@@ -605,28 +602,16 @@ class Email extends Message
public function __serialize(): array
{
if (\is_resource($this->text)) {
- if (stream_get_meta_data($this->text)['seekable'] ?? false) {
- rewind($this->text);
- }
-
- $this->text = stream_get_contents($this->text);
+ $this->text = (new TextPart($this->text))->getBody();
}
if (\is_resource($this->html)) {
- if (stream_get_meta_data($this->html)['seekable'] ?? false) {
- rewind($this->html);
- }
-
- $this->html = stream_get_contents($this->html);
+ $this->html = (new TextPart($this->html))->getBody();
}
foreach ($this->attachments as $i => $attachment) {
if (isset($attachment['body']) && \is_resource($attachment['body'])) {
- if (stream_get_meta_data($attachment['body'])['seekable'] ?? false) {
- rewind($attachment['body']);
- }
-
- $this->attachments[$i]['body'] = stream_get_contents($attachment['body']);
+ $this->attachments[$i]['body'] = (new TextPart($attachment['body']))->getBody();
}
}
diff --git a/vendor/symfony/mime/Encoder/Base64ContentEncoder.php b/vendor/symfony/mime/Encoder/Base64ContentEncoder.php
index 338490b3e..440868af7 100644
--- a/vendor/symfony/mime/Encoder/Base64ContentEncoder.php
+++ b/vendor/symfony/mime/Encoder/Base64ContentEncoder.php
@@ -32,11 +32,8 @@ final class Base64ContentEncoder extends Base64Encoder implements ContentEncoder
throw new RuntimeException('Unable to set the base64 content encoder to the filter.');
}
- if (stream_get_meta_data($stream)['seekable'] ?? false) {
- rewind($stream);
- }
while (!feof($stream)) {
- yield fread($stream, 8192);
+ yield fread($stream, 16372);
}
stream_filter_remove($filter);
}
diff --git a/vendor/symfony/mime/Encoder/IdnAddressEncoder.php b/vendor/symfony/mime/Encoder/IdnAddressEncoder.php
index e049fe5e7..b56e7e396 100644
--- a/vendor/symfony/mime/Encoder/IdnAddressEncoder.php
+++ b/vendor/symfony/mime/Encoder/IdnAddressEncoder.php
@@ -11,16 +11,14 @@
namespace Symfony\Component\Mime\Encoder;
-use Symfony\Component\Mime\Exception\AddressEncoderException;
-
/**
* An IDN email address encoder.
*
* Encodes the domain part of an address using IDN. This is compatible will all
* SMTP servers.
*
- * This encoder does not support email addresses with non-ASCII characters in
- * local-part (the substring before @).
+ * Note: It leaves the local part as is. In case there are non-ASCII characters
+ * in the local part then it depends on the SMTP Server if this is supported.
*
* @author Christian Schmidt
*/
@@ -28,8 +26,6 @@ final class IdnAddressEncoder implements AddressEncoderInterface
{
/**
* Encodes the domain part of an address using IDN.
- *
- * @throws AddressEncoderException If local-part contains non-ASCII characters
*/
public function encodeString(string $address): string
{
@@ -38,10 +34,6 @@ final class IdnAddressEncoder implements AddressEncoderInterface
$local = substr($address, 0, $i);
$domain = substr($address, $i + 1);
- if (preg_match('/[^\x00-\x7F]/', $local)) {
- throw new AddressEncoderException(sprintf('Non-ASCII characters not supported in local-part os "%s".', $address));
- }
-
if (preg_match('/[^\x00-\x7F]/', $domain)) {
$address = sprintf('%s@%s', $local, idn_to_ascii($domain, \IDNA_DEFAULT | \IDNA_USE_STD3_RULES | \IDNA_CHECK_BIDI | \IDNA_CHECK_CONTEXTJ | \IDNA_NONTRANSITIONAL_TO_ASCII, \INTL_IDNA_VARIANT_UTS46));
}
diff --git a/vendor/symfony/mime/Encoder/QpContentEncoder.php b/vendor/symfony/mime/Encoder/QpContentEncoder.php
index e0b8605dd..4703cc2e6 100644
--- a/vendor/symfony/mime/Encoder/QpContentEncoder.php
+++ b/vendor/symfony/mime/Encoder/QpContentEncoder.php
@@ -23,10 +23,6 @@ final class QpContentEncoder implements ContentEncoderInterface
}
// we don't use PHP stream filters here as the content should be small enough
- if (stream_get_meta_data($stream)['seekable'] ?? false) {
- rewind($stream);
- }
-
yield $this->encodeString(stream_get_contents($stream), 'utf-8', 0, $maxLineLength);
}
diff --git a/vendor/symfony/mime/Header/Headers.php b/vendor/symfony/mime/Header/Headers.php
index 201a7a5f9..8db912520 100644
--- a/vendor/symfony/mime/Header/Headers.php
+++ b/vendor/symfony/mime/Header/Headers.php
@@ -25,7 +25,23 @@ final class Headers
'date', 'from', 'sender', 'reply-to', 'to', 'cc', 'bcc',
'message-id', 'in-reply-to', 'references', 'subject',
];
+ private const HEADER_CLASS_MAP = [
+ 'date' => DateHeader::class,
+ 'from' => MailboxListHeader::class,
+ 'sender' => MailboxHeader::class,
+ 'reply-to' => MailboxListHeader::class,
+ 'to' => MailboxListHeader::class,
+ 'cc' => MailboxListHeader::class,
+ 'bcc' => MailboxListHeader::class,
+ 'message-id' => IdentificationHeader::class,
+ 'in-reply-to' => UnstructuredHeader::class, // `In-Reply-To` and `References` are less strict than RFC 2822 (3.6.4) to allow users entering the original email's ...
+ 'references' => UnstructuredHeader::class, // ... `Message-ID`, even if that is no valid `msg-id`
+ 'return-path' => PathHeader::class,
+ ];
+ /**
+ * @var HeaderInterface[][]
+ */
private $headers = [];
private $lineLength = 76;
@@ -122,6 +138,22 @@ final class Headers
return $this->add(new ParameterizedHeader($name, $value, $params));
}
+ /**
+ * @return $this
+ */
+ public function addHeader(string $name, $argument, array $more = []): self
+ {
+ $parts = explode('\\', self::HEADER_CLASS_MAP[strtolower($name)] ?? UnstructuredHeader::class);
+ $method = 'add'.ucfirst(array_pop($parts));
+ if ('addUnstructuredHeader' === $method) {
+ $method = 'addTextHeader';
+ } elseif ('addIdentificationHeader' === $method) {
+ $method = 'addIdHeader';
+ }
+
+ return $this->$method($name, $argument, $more);
+ }
+
public function has(string $name): bool
{
return isset($this->headers[strtolower($name)]);
@@ -132,27 +164,11 @@ final class Headers
*/
public function add(HeaderInterface $header): self
{
- static $map = [
- 'date' => DateHeader::class,
- 'from' => MailboxListHeader::class,
- 'sender' => MailboxHeader::class,
- 'reply-to' => MailboxListHeader::class,
- 'to' => MailboxListHeader::class,
- 'cc' => MailboxListHeader::class,
- 'bcc' => MailboxListHeader::class,
- 'message-id' => IdentificationHeader::class,
- 'in-reply-to' => UnstructuredHeader::class, // `In-Reply-To` and `References` are less strict than RFC 2822 (3.6.4) to allow users entering the original email's ...
- 'references' => UnstructuredHeader::class, // ... `Message-ID`, even if that is no valid `msg-id`
- 'return-path' => PathHeader::class,
- ];
+ self::checkHeaderClass($header);
$header->setMaxLineLength($this->lineLength);
$name = strtolower($header->getName());
- if (isset($map[$name]) && !$header instanceof $map[$name]) {
- throw new LogicException(sprintf('The "%s" header must be an instance of "%s" (got "%s").', $header->getName(), $map[$name], \get_class($header)));
- }
-
if (\in_array($name, self::UNIQUE_HEADERS, true) && isset($this->headers[$name]) && \count($this->headers[$name]) > 0) {
throw new LogicException(sprintf('Impossible to set header "%s" as it\'s already defined and must be unique.', $header->getName()));
}
@@ -204,6 +220,18 @@ final class Headers
return \in_array(strtolower($name), self::UNIQUE_HEADERS, true);
}
+ /**
+ * @throws LogicException if the header name and class are not compatible
+ */
+ public static function checkHeaderClass(HeaderInterface $header): void
+ {
+ $name = strtolower($header->getName());
+
+ if (($c = self::HEADER_CLASS_MAP[$name] ?? null) && !$header instanceof $c) {
+ throw new LogicException(sprintf('The "%s" header must be an instance of "%s" (got "%s").', $header->getName(), $c, get_debug_type($header)));
+ }
+ }
+
public function toString(): string
{
$string = '';
@@ -246,9 +274,6 @@ final class Headers
}
}
- /**
- * @internal
- */
public function getHeaderParameter(string $name, string $parameter): ?string
{
if (!$this->has($name)) {
diff --git a/vendor/symfony/mime/LICENSE b/vendor/symfony/mime/LICENSE
index 298be1416..58b42bc8a 100644
--- a/vendor/symfony/mime/LICENSE
+++ b/vendor/symfony/mime/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2010-2022 Fabien Potencier
+Copyright (c) 2010-2023 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/vendor/symfony/mime/Message.php b/vendor/symfony/mime/Message.php
index b7ddb76bc..651ffd452 100644
--- a/vendor/symfony/mime/Message.php
+++ b/vendor/symfony/mime/Message.php
@@ -80,7 +80,9 @@ class Message extends RawMessage
$headers->addMailboxListHeader('From', [$headers->get('Sender')->getAddress()]);
}
- $headers->addTextHeader('MIME-Version', '1.0');
+ if (!$headers->has('MIME-Version')) {
+ $headers->addTextHeader('MIME-Version', '1.0');
+ }
if (!$headers->has('Date')) {
$headers->addDateHeader('Date', new \DateTimeImmutable());
diff --git a/vendor/symfony/mime/MessageConverter.php b/vendor/symfony/mime/MessageConverter.php
index 4163e51cd..0539eac8e 100644
--- a/vendor/symfony/mime/MessageConverter.php
+++ b/vendor/symfony/mime/MessageConverter.php
@@ -55,13 +55,13 @@ final class MessageConverter
} elseif ($parts[0] instanceof TextPart) {
$email = self::createEmailFromTextPart($message, $parts[0]);
} else {
- throw new RuntimeException(sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', \get_class($message)));
+ throw new RuntimeException(sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($message)));
}
return self::attachParts($email, \array_slice($parts, 1));
}
- throw new RuntimeException(sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', \get_class($message)));
+ throw new RuntimeException(sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($message)));
}
private static function createEmailFromTextPart(Message $message, TextPart $part): Email
@@ -73,7 +73,7 @@ final class MessageConverter
return (new Email(clone $message->getHeaders()))->html($part->getBody(), $part->getPreparedHeaders()->getHeaderParameter('Content-Type', 'charset') ?: 'utf-8');
}
- throw new RuntimeException(sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', \get_class($message)));
+ throw new RuntimeException(sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($message)));
}
private static function createEmailFromAlternativePart(Message $message, AlternativePart $part): Email
@@ -90,7 +90,7 @@ final class MessageConverter
;
}
- throw new RuntimeException(sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', \get_class($message)));
+ throw new RuntimeException(sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($message)));
}
private static function createEmailFromRelatedPart(Message $message, RelatedPart $part): Email
@@ -101,7 +101,7 @@ final class MessageConverter
} elseif ($parts[0] instanceof TextPart) {
$email = self::createEmailFromTextPart($message, $parts[0]);
} else {
- throw new RuntimeException(sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', \get_class($message)));
+ throw new RuntimeException(sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($message)));
}
return self::attachParts($email, \array_slice($parts, 1));
@@ -111,7 +111,7 @@ final class MessageConverter
{
foreach ($parts as $part) {
if (!$part instanceof DataPart) {
- throw new RuntimeException(sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', \get_class($email)));
+ throw new RuntimeException(sprintf('Unable to create an Email from an instance of "%s" as the body is too complex.', get_debug_type($email)));
}
$headers = $part->getPreparedHeaders();
diff --git a/vendor/symfony/mime/MimeTypeGuesserInterface.php b/vendor/symfony/mime/MimeTypeGuesserInterface.php
index 6eded54c6..30ee3b64a 100644
--- a/vendor/symfony/mime/MimeTypeGuesserInterface.php
+++ b/vendor/symfony/mime/MimeTypeGuesserInterface.php
@@ -26,8 +26,6 @@ interface MimeTypeGuesserInterface
/**
* Guesses the MIME type of the file with the given path.
*
- * @return string|null The MIME type or null, if none could be guessed
- *
* @throws \LogicException If the guesser is not supported
* @throws \InvalidArgumentException If the file does not exist or is not readable
*/
diff --git a/vendor/symfony/mime/MimeTypes.php b/vendor/symfony/mime/MimeTypes.php
index e2b5bf435..bdea994b5 100644
--- a/vendor/symfony/mime/MimeTypes.php
+++ b/vendor/symfony/mime/MimeTypes.php
@@ -146,7 +146,7 @@ final class MimeTypes implements MimeTypesInterface
/**
* A map of MIME types and their default extensions.
*
- * Updated from upstream on 2019-01-16
+ * Updated from upstream on 2021-09-03
*
* @see Resources/bin/update_mime_types.php
*/
@@ -157,8 +157,16 @@ final class MimeTypes implements MimeTypesInterface
'application/applixware' => ['aw'],
'application/atom+xml' => ['atom'],
'application/atomcat+xml' => ['atomcat'],
+ 'application/atomdeleted+xml' => ['atomdeleted'],
'application/atomsvc+xml' => ['atomsvc'],
+ 'application/atsc-dwd+xml' => ['dwd'],
+ 'application/atsc-held+xml' => ['held'],
+ 'application/atsc-rsat+xml' => ['rsat'],
+ 'application/bdoc' => ['bdoc'],
+ 'application/bzip2' => ['bz2', 'bz'],
+ 'application/calendar+xml' => ['xcs'],
'application/ccxml+xml' => ['ccxml'],
+ 'application/cdfx+xml' => ['cdfx'],
'application/cdmi-capability' => ['cdmia'],
'application/cdmi-container' => ['cdmic'],
'application/cdmi-domain' => ['cdmid'],
@@ -168,6 +176,7 @@ final class MimeTypes implements MimeTypesInterface
'application/coreldraw' => ['cdr'],
'application/csv' => ['csv'],
'application/cu-seeme' => ['cu'],
+ 'application/dash+xml' => ['mpd'],
'application/davmount+xml' => ['davmount'],
'application/dbase' => ['dbf'],
'application/dbf' => ['dbf'],
@@ -178,8 +187,10 @@ final class MimeTypes implements MimeTypesInterface
'application/ecmascript' => ['ecma', 'es'],
'application/emf' => ['emf'],
'application/emma+xml' => ['emma'],
+ 'application/emotionml+xml' => ['emotionml'],
'application/epub+zip' => ['epub'],
'application/exi' => ['exi'],
+ 'application/fdt+xml' => ['fdt'],
'application/font-tdpfr' => ['pfr'],
'application/font-woff' => ['woff'],
'application/futuresplash' => ['swf', 'spl'],
@@ -190,29 +201,34 @@ final class MimeTypes implements MimeTypesInterface
'application/gpx+xml' => ['gpx'],
'application/gxf' => ['gxf'],
'application/gzip' => ['gz'],
+ 'application/hjson' => ['hjson'],
'application/hyperstudio' => ['stk'],
'application/ico' => ['ico'],
'application/ics' => ['vcs', 'ics'],
'application/illustrator' => ['ai'],
'application/inkml+xml' => ['ink', 'inkml'],
'application/ipfix' => ['ipfix'],
+ 'application/its+xml' => ['its'],
'application/java' => ['class'],
- 'application/java-archive' => ['jar'],
+ 'application/java-archive' => ['jar', 'war', 'ear'],
'application/java-byte-code' => ['class'],
'application/java-serialized-object' => ['ser'],
'application/java-vm' => ['class'],
- 'application/javascript' => ['js', 'jsm', 'mjs'],
+ 'application/javascript' => ['js', 'mjs', 'jsm'],
'application/jrd+json' => ['jrd'],
- 'application/json' => ['json'],
+ 'application/json' => ['json', 'map'],
'application/json-patch+json' => ['json-patch'],
+ 'application/json5' => ['json5'],
'application/jsonml+json' => ['jsonml'],
'application/ld+json' => ['jsonld'],
+ 'application/lgr+xml' => ['lgr'],
'application/lost+xml' => ['lostxml'],
'application/lotus123' => ['123', 'wk1', 'wk3', 'wk4', 'wks'],
'application/m3u' => ['m3u', 'm3u8', 'vlc'],
'application/mac-binhex40' => ['hqx'],
'application/mac-compactpro' => ['cpt'],
'application/mads+xml' => ['mads'],
+ 'application/manifest+json' => ['webmanifest'],
'application/marc' => ['mrc'],
'application/marcxml+xml' => ['mrcx'],
'application/mathematica' => ['ma', 'nb', 'mb'],
@@ -223,9 +239,13 @@ final class MimeTypes implements MimeTypesInterface
'application/metalink+xml' => ['metalink'],
'application/metalink4+xml' => ['meta4'],
'application/mets+xml' => ['mets'],
+ 'application/mmt-aei+xml' => ['maei'],
+ 'application/mmt-usd+xml' => ['musd'],
'application/mods+xml' => ['mods'],
'application/mp21' => ['m21', 'mp21'],
- 'application/mp4' => ['mp4s'],
+ 'application/mp4' => ['mp4s', 'm4p'],
+ 'application/mrb-consumer+xml' => ['xdf'],
+ 'application/mrb-publish+xml' => ['xdf'],
'application/ms-tnef' => ['tnef', 'tnf'],
'application/msaccess' => ['mdb'],
'application/msexcel' => ['xls', 'xlc', 'xll', 'xlm', 'xlw', 'xla', 'xlt', 'xld'],
@@ -233,21 +253,26 @@ final class MimeTypes implements MimeTypesInterface
'application/msword' => ['doc', 'dot'],
'application/msword-template' => ['dot'],
'application/mxf' => ['mxf'],
+ 'application/n-quads' => ['nq'],
+ 'application/n-triples' => ['nt'],
'application/nappdf' => ['pdf'],
- 'application/octet-stream' => ['bin', 'dms', 'lrf', 'mar', 'so', 'dist', 'distz', 'pkg', 'bpk', 'dump', 'elc', 'deploy'],
+ 'application/node' => ['cjs'],
+ 'application/octet-stream' => ['bin', 'dms', 'lrf', 'mar', 'so', 'dist', 'distz', 'pkg', 'bpk', 'dump', 'elc', 'deploy', 'exe', 'dll', 'deb', 'dmg', 'iso', 'img', 'msi', 'msp', 'msm', 'buffer'],
'application/oda' => ['oda'],
'application/oebps-package+xml' => ['opf'],
'application/ogg' => ['ogx'],
'application/omdoc+xml' => ['omdoc'],
'application/onenote' => ['onetoc', 'onetoc2', 'onetmp', 'onepkg'],
+ 'application/ovf' => ['ova'],
'application/owl+xml' => ['owx'],
- 'application/oxps' => ['oxps', 'xps'],
+ 'application/oxps' => ['oxps'],
+ 'application/p2p-overlay+xml' => ['relo'],
'application/patch-ops-error+xml' => ['xer'],
'application/pcap' => ['pcap', 'cap', 'dmp'],
'application/pdf' => ['pdf'],
'application/pgp' => ['pgp', 'gpg', 'asc'],
'application/pgp-encrypted' => ['pgp', 'gpg', 'asc'],
- 'application/pgp-keys' => ['skr', 'pkr', 'asc', 'pgp', 'gpg'],
+ 'application/pgp-keys' => ['skr', 'pkr', 'asc', 'pgp', 'gpg', 'key'],
'application/pgp-signature' => ['asc', 'sig', 'pgp', 'gpg'],
'application/photoshop' => ['psd'],
'application/pics-rules' => ['prf'],
@@ -266,16 +291,20 @@ final class MimeTypes implements MimeTypesInterface
'application/pls+xml' => ['pls'],
'application/postscript' => ['ai', 'eps', 'ps'],
'application/powerpoint' => ['ppz', 'ppt', 'pps', 'pot'],
+ 'application/provenance+xml' => ['provx'],
'application/prs.cww' => ['cww'],
'application/pskc+xml' => ['pskcxml'],
'application/ram' => ['ram'],
'application/raml+yaml' => ['raml'],
- 'application/rdf+xml' => ['rdf', 'rdfs', 'owl'],
+ 'application/rdf+xml' => ['rdf', 'owl', 'rdfs'],
'application/reginfo+xml' => ['rif'],
'application/relax-ng-compact-syntax' => ['rnc'],
'application/resource-lists+xml' => ['rl'],
'application/resource-lists-diff+xml' => ['rld'],
'application/rls-services+xml' => ['rs'],
+ 'application/route-apd+xml' => ['rapd'],
+ 'application/route-s-tsid+xml' => ['sls'],
+ 'application/route-usd+xml' => ['rusd'],
'application/rpki-ghostbusters' => ['gbr'],
'application/rpki-manifest' => ['mft'],
'application/rpki-roa' => ['roa'],
@@ -283,15 +312,18 @@ final class MimeTypes implements MimeTypesInterface
'application/rss+xml' => ['rss'],
'application/rtf' => ['rtf'],
'application/sbml+xml' => ['sbml'],
+ 'application/schema+json' => ['json'],
'application/scvp-cv-request' => ['scq'],
'application/scvp-cv-response' => ['scs'],
'application/scvp-vp-request' => ['spq'],
'application/scvp-vp-response' => ['spp'],
'application/sdp' => ['sdp'],
+ 'application/senml+xml' => ['senmlx'],
+ 'application/sensml+xml' => ['sensmlx'],
'application/set-payment-initiation' => ['setpay'],
'application/set-registration-initiation' => ['setreg'],
'application/shf+xml' => ['shf'],
- 'application/sieve' => ['siv'],
+ 'application/sieve' => ['siv', 'sieve'],
'application/smil' => ['smil', 'smi', 'sml', 'kino'],
'application/smil+xml' => ['smi', 'smil', 'sml', 'kino'],
'application/sparql-query' => ['rq'],
@@ -302,11 +334,19 @@ final class MimeTypes implements MimeTypesInterface
'application/sru+xml' => ['sru'],
'application/ssdl+xml' => ['ssdl'],
'application/ssml+xml' => ['ssml'],
- 'application/stuffit' => ['sit'],
+ 'application/stuffit' => ['sit', 'hqx'],
+ 'application/swid+xml' => ['swidtag'],
'application/tei+xml' => ['tei', 'teicorpus'],
+ 'application/tga' => ['tga', 'icb', 'tpic', 'vda', 'vst'],
'application/thraud+xml' => ['tfi'],
'application/timestamped-data' => ['tsd'],
+ 'application/toml' => ['toml'],
'application/trig' => ['trig'],
+ 'application/ttml+xml' => ['ttml'],
+ 'application/ubjson' => ['ubj'],
+ 'application/urc-ressheet+xml' => ['rsheet'],
+ 'application/urc-targetdesc+xml' => ['td'],
+ 'application/vnd.1000minds.decision-model+xml' => ['1km'],
'application/vnd.3gpp.pic-bw-large' => ['plb'],
'application/vnd.3gpp.pic-bw-small' => ['psb'],
'application/vnd.3gpp.pic-bw-var' => ['pvb'],
@@ -327,6 +367,7 @@ final class MimeTypes implements MimeTypesInterface
'application/vnd.airzip.filesecure.azf' => ['azf'],
'application/vnd.airzip.filesecure.azs' => ['azs'],
'application/vnd.amazon.ebook' => ['azw'],
+ 'application/vnd.amazon.mobi8-ebook' => ['azw3', 'kfx'],
'application/vnd.americandynamics.acc' => ['acc'],
'application/vnd.amiga.ami' => ['ami'],
'application/vnd.android.package-archive' => ['apk'],
@@ -335,11 +376,15 @@ final class MimeTypes implements MimeTypesInterface
'application/vnd.antix.game-component' => ['atx'],
'application/vnd.appimage' => ['appimage'],
'application/vnd.apple.installer+xml' => ['mpkg'],
- 'application/vnd.apple.keynote' => ['key'],
+ 'application/vnd.apple.keynote' => ['key', 'keynote'],
'application/vnd.apple.mpegurl' => ['m3u8', 'm3u'],
+ 'application/vnd.apple.numbers' => ['numbers'],
+ 'application/vnd.apple.pages' => ['pages'],
+ 'application/vnd.apple.pkpass' => ['pkpass'],
'application/vnd.aristanetworks.swi' => ['swi'],
'application/vnd.astraea-software.iota' => ['iota'],
'application/vnd.audiograph' => ['aep'],
+ 'application/vnd.balsamiq.bmml+xml' => ['bmml'],
'application/vnd.blueice.multipass' => ['mpm'],
'application/vnd.bmi' => ['bmi'],
'application/vnd.businessobjects' => ['rep'],
@@ -347,6 +392,7 @@ final class MimeTypes implements MimeTypesInterface
'application/vnd.chess-pgn' => ['pgn'],
'application/vnd.chipnuts.karaoke-mmd' => ['mmd'],
'application/vnd.cinderella' => ['cdy'],
+ 'application/vnd.citationstyles.style+xml' => ['csl'],
'application/vnd.claymore' => ['cla'],
'application/vnd.cloanto.rp9' => ['rp9'],
'application/vnd.clonk.c4group' => ['c4g', 'c4d', 'c4f', 'c4p', 'c4u'],
@@ -371,6 +417,7 @@ final class MimeTypes implements MimeTypesInterface
'application/vnd.curl.pcurl' => ['pcurl'],
'application/vnd.dart' => ['dart'],
'application/vnd.data-vision.rdz' => ['rdz'],
+ 'application/vnd.dbf' => ['dbf'],
'application/vnd.debian.binary-package' => ['deb', 'udeb'],
'application/vnd.dece.data' => ['uvf', 'uvvf', 'uvd', 'uvvd'],
'application/vnd.dece.ttml+xml' => ['uvt', 'uvvt'],
@@ -394,6 +441,7 @@ final class MimeTypes implements MimeTypesInterface
'application/vnd.epson.salt' => ['slt'],
'application/vnd.epson.ssf' => ['ssf'],
'application/vnd.eszigno3+xml' => ['es3', 'et3'],
+ 'application/vnd.etsi.asic-e+zip' => ['asice'],
'application/vnd.ezpix-album' => ['ez2'],
'application/vnd.ezpix-package' => ['ez3'],
'application/vnd.fdf' => ['fdf'],
@@ -426,6 +474,9 @@ final class MimeTypes implements MimeTypesInterface
'application/vnd.geoplan' => ['g2w'],
'application/vnd.geospace' => ['g3w'],
'application/vnd.gmx' => ['gmx'],
+ 'application/vnd.google-apps.document' => ['gdoc'],
+ 'application/vnd.google-apps.presentation' => ['gslides'],
+ 'application/vnd.google-apps.spreadsheet' => ['gsheet'],
'application/vnd.google-earth.kml+xml' => ['kml'],
'application/vnd.google-earth.kmz' => ['kmz'],
'application/vnd.grafeq' => ['gqf', 'gqs'],
@@ -495,6 +546,7 @@ final class MimeTypes implements MimeTypesInterface
'application/vnd.lotus-screencam' => ['scm'],
'application/vnd.lotus-wordpro' => ['lwp'],
'application/vnd.macports.portpkg' => ['portpkg'],
+ 'application/vnd.mapbox-vector-tile' => ['mvt'],
'application/vnd.mcd' => ['mcd'],
'application/vnd.medcalcdata' => ['mc1'],
'application/vnd.mediastation.cdkey' => ['cdkey'],
@@ -527,6 +579,7 @@ final class MimeTypes implements MimeTypesInterface
'application/vnd.ms-ims' => ['ims'],
'application/vnd.ms-lrm' => ['lrm'],
'application/vnd.ms-officetheme' => ['thmx'],
+ 'application/vnd.ms-outlook' => ['msg'],
'application/vnd.ms-pki.seccat' => ['cat'],
'application/vnd.ms-pki.stl' => ['stl'],
'application/vnd.ms-powerpoint' => ['ppt', 'pps', 'pot', 'ppz'],
@@ -549,7 +602,7 @@ final class MimeTypes implements MimeTypesInterface
'application/vnd.ms-word.template.macroenabled.12' => ['dotm'],
'application/vnd.ms-works' => ['wps', 'wks', 'wcm', 'wdb', 'xlr'],
'application/vnd.ms-wpl' => ['wpl'],
- 'application/vnd.ms-xpsdocument' => ['xps', 'oxps'],
+ 'application/vnd.ms-xpsdocument' => ['xps'],
'application/vnd.msaccess' => ['mdb'],
'application/vnd.mseq' => ['mseq'],
'application/vnd.musician' => ['mus'],
@@ -561,6 +614,7 @@ final class MimeTypes implements MimeTypesInterface
'application/vnd.noblenet-directory' => ['nnd'],
'application/vnd.noblenet-sealer' => ['nns'],
'application/vnd.noblenet-web' => ['nnw'],
+ 'application/vnd.nokia.n-gage.ac+xml' => ['ac'],
'application/vnd.nokia.n-gage.data' => ['ngdat'],
'application/vnd.nokia.n-gage.symbian.install' => ['n-gage'],
'application/vnd.nokia.radio-preset' => ['rpst'],
@@ -592,7 +646,9 @@ final class MimeTypes implements MimeTypesInterface
'application/vnd.oasis.opendocument.text-web' => ['oth'],
'application/vnd.olpc-sugar' => ['xo'],
'application/vnd.oma.dd2+xml' => ['dd2'],
+ 'application/vnd.openblox.game+xml' => ['obgx'],
'application/vnd.openofficeorg.extension' => ['oxt'],
+ 'application/vnd.openstreetmap.data+xml' => ['osm'],
'application/vnd.openxmlformats-officedocument.presentationml.presentation' => ['pptx'],
'application/vnd.openxmlformats-officedocument.presentationml.slide' => ['sldx'],
'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => ['ppsx'],
@@ -640,6 +696,7 @@ final class MimeTypes implements MimeTypesInterface
'application/vnd.smaf' => ['mmf', 'smaf'],
'application/vnd.smart.teacher' => ['teacher'],
'application/vnd.snap' => ['snap'],
+ 'application/vnd.software602.filler.form+xml' => ['fo'],
'application/vnd.solent.sdkm+xml' => ['sdkm', 'sdkd'],
'application/vnd.spotfire.dxp' => ['dxp'],
'application/vnd.spotfire.sfs' => ['sfs'],
@@ -655,6 +712,7 @@ final class MimeTypes implements MimeTypesInterface
'application/vnd.stardivision.writer-global' => ['sgl', 'sdw', 'vor'],
'application/vnd.stepmania.package' => ['smzip'],
'application/vnd.stepmania.stepchart' => ['sm'],
+ 'application/vnd.sun.wadl+xml' => ['wadl'],
'application/vnd.sun.xml.base' => ['odb'],
'application/vnd.sun.xml.calc' => ['sxc'],
'application/vnd.sun.xml.calc.template' => ['stc'],
@@ -672,6 +730,7 @@ final class MimeTypes implements MimeTypesInterface
'application/vnd.syncml+xml' => ['xsm'],
'application/vnd.syncml.dm+wbxml' => ['bdm'],
'application/vnd.syncml.dm+xml' => ['xdm'],
+ 'application/vnd.syncml.dmddf+xml' => ['ddf'],
'application/vnd.tao.intent-module-archive' => ['tao'],
'application/vnd.tcpdump.pcap' => ['pcap', 'cap', 'dmp'],
'application/vnd.tmobile-livetv' => ['tmo'],
@@ -710,6 +769,7 @@ final class MimeTypes implements MimeTypesInterface
'application/vnd.zul' => ['zir', 'zirz'],
'application/vnd.zzazz.deck+xml' => ['zaz'],
'application/voicexml+xml' => ['vxml'],
+ 'application/wasm' => ['wasm'],
'application/widget' => ['wgt'],
'application/winhlp' => ['hlp'],
'application/wk1' => ['123', 'wk1', 'wk3', 'wk4', 'wks'],
@@ -719,7 +779,7 @@ final class MimeTypes implements MimeTypesInterface
'application/wspolicy+xml' => ['wspolicy'],
'application/wwf' => ['wwf'],
'application/x-123' => ['123', 'wk1', 'wk3', 'wk4', 'wks'],
- 'application/x-7z-compressed' => ['7z'],
+ 'application/x-7z-compressed' => ['7z', '7z.001'],
'application/x-abiword' => ['abw', 'abw.CRASHED', 'abw.gz', 'zabw'],
'application/x-ace' => ['ace'],
'application/x-ace-compressed' => ['ace'],
@@ -729,6 +789,8 @@ final class MimeTypes implements MimeTypesInterface
'application/x-annodex' => ['anx'],
'application/x-aportisdoc' => ['pdb', 'pdc'],
'application/x-apple-diskimage' => ['dmg'],
+ 'application/x-apple-systemprofiler+xml' => ['spx'],
+ 'application/x-appleworks-document' => ['cwk'],
'application/x-applix-spreadsheet' => ['as'],
'application/x-applix-word' => ['aw'],
'application/x-archive' => ['a', 'ar'],
@@ -742,10 +804,13 @@ final class MimeTypes implements MimeTypesInterface
'application/x-authorware-seg' => ['aas'],
'application/x-awk' => ['awk'],
'application/x-bcpio' => ['bcpio'],
+ 'application/x-bdoc' => ['bdoc'],
'application/x-bittorrent' => ['torrent'],
'application/x-blender' => ['blender', 'blend', 'BLEND'],
'application/x-blorb' => ['blb', 'blorb'],
+ 'application/x-bps-patch' => ['bps'],
'application/x-bsdiff' => ['bsdiff'],
+ 'application/x-bz2' => ['bz2'],
'application/x-bzdvi' => ['dvi.bz2'],
'application/x-bzip' => ['bz', 'bz2'],
'application/x-bzip-compressed-tar' => ['tar.bz2', 'tar.bz', 'tbz2', 'tbz', 'tb2'],
@@ -765,8 +830,11 @@ final class MimeTypes implements MimeTypesInterface
'application/x-chat' => ['chat'],
'application/x-chess-pgn' => ['pgn'],
'application/x-chm' => ['chm'],
+ 'application/x-chrome-extension' => ['crx'],
'application/x-cisco-vpn-settings' => ['pcf'],
+ 'application/x-cocoa' => ['cco'],
'application/x-compress' => ['Z'],
+ 'application/x-compressed-iso' => ['cso'],
'application/x-compressed-tar' => ['tar.gz', 'tgz'],
'application/x-conference' => ['nsc'],
'application/x-coreldraw' => ['cdr'],
@@ -786,9 +854,11 @@ final class MimeTypes implements MimeTypesInterface
'application/x-dia-diagram' => ['dia'],
'application/x-dia-shape' => ['shape'],
'application/x-director' => ['dir', 'dcr', 'dxr', 'cst', 'cct', 'cxt', 'w3d', 'fgd', 'swa'],
+ 'application/x-discjuggler-cd-image' => ['cdi'],
'application/x-docbook+xml' => ['dbk', 'docbook'],
'application/x-doom' => ['wad'],
'application/x-doom-wad' => ['wad'],
+ 'application/x-dreamcast-rom' => ['iso'],
'application/x-dtbncx+xml' => ['ncx'],
'application/x-dtbook+xml' => ['dtb'],
'application/x-dtbresource+xml' => ['res'],
@@ -812,6 +882,7 @@ final class MimeTypes implements MimeTypesInterface
'application/x-font-pcf' => ['pcf', 'pcf.Z', 'pcf.gz'],
'application/x-font-snf' => ['snf'],
'application/x-font-speedo' => ['spd'],
+ 'application/x-font-truetype' => ['ttf'],
'application/x-font-ttf' => ['ttf'],
'application/x-font-ttx' => ['ttx'],
'application/x-font-type1' => ['pfa', 'pfb', 'pfm', 'afm', 'gsf'],
@@ -826,9 +897,10 @@ final class MimeTypes implements MimeTypesInterface
'application/x-gamegear-rom' => ['gg'],
'application/x-gba-rom' => ['gba', 'agb'],
'application/x-gca-compressed' => ['gca'],
+ 'application/x-gd-rom-cue' => ['gdi'],
'application/x-gedcom' => ['ged', 'gedcom'],
'application/x-genesis-32x-rom' => ['32x', 'mdx'],
- 'application/x-genesis-rom' => ['gen', 'smd'],
+ 'application/x-genesis-rom' => ['gen', 'smd', 'sgd'],
'application/x-gettext' => ['po'],
'application/x-gettext-translation' => ['gmo', 'mo'],
'application/x-glade' => ['glade'],
@@ -852,18 +924,23 @@ final class MimeTypes implements MimeTypesInterface
'application/x-hdf' => ['hdf', 'hdf4', 'h4', 'hdf5', 'h5'],
'application/x-hfe-file' => ['hfe'],
'application/x-hfe-floppy-image' => ['hfe'],
+ 'application/x-httpd-php' => ['php'],
'application/x-hwp' => ['hwp'],
'application/x-hwt' => ['hwt'],
'application/x-ica' => ['ica'],
'application/x-install-instructions' => ['install'],
+ 'application/x-ips-patch' => ['ips'],
'application/x-ipynb+json' => ['ipynb'],
'application/x-iso9660-appimage' => ['appimage'],
'application/x-iso9660-image' => ['iso', 'iso9660'],
'application/x-it87' => ['it87'],
'application/x-iwork-keynote-sffkey' => ['key'],
+ 'application/x-iwork-numbers-sffnumbers' => ['numbers'],
+ 'application/x-iwork-pages-sffpages' => ['pages'],
'application/x-jar' => ['jar'],
'application/x-java' => ['class'],
'application/x-java-archive' => ['jar'],
+ 'application/x-java-archive-diff' => ['jardiff'],
'application/x-java-class' => ['class'],
'application/x-java-jce-keystore' => ['jceks'],
'application/x-java-jnlp-file' => ['jnlp'],
@@ -874,6 +951,7 @@ final class MimeTypes implements MimeTypesInterface
'application/x-jbuilder-project' => ['jpr', 'jpx'],
'application/x-karbon' => ['karbon'],
'application/x-kchart' => ['chrt'],
+ 'application/x-keepass2' => ['kdbx'],
'application/x-kexi-connectiondata' => ['kexic'],
'application/x-kexiproject-shortcut' => ['kexis'],
'application/x-kexiproject-sqlite' => ['kexi'],
@@ -885,7 +963,7 @@ final class MimeTypes implements MimeTypesInterface
'application/x-kontour' => ['kon'],
'application/x-kpovmodeler' => ['kpm'],
'application/x-kpresenter' => ['kpr', 'kpt'],
- 'application/x-krita' => ['kra'],
+ 'application/x-krita' => ['kra', 'krz'],
'application/x-kspread' => ['ksp'],
'application/x-kugar' => ['kud'],
'application/x-kword' => ['kwd', 'kwt'],
@@ -896,6 +974,7 @@ final class MimeTypes implements MimeTypesInterface
'application/x-lotus123' => ['123', 'wk1', 'wk3', 'wk4', 'wks'],
'application/x-lrzip' => ['lrz'],
'application/x-lrzip-compressed-tar' => ['tar.lrz', 'tlrz'],
+ 'application/x-lua-bytecode' => ['luac'],
'application/x-lyx' => ['lyx'],
'application/x-lz4' => ['lz4'],
'application/x-lz4-compressed-tar' => ['tar.lz4'],
@@ -908,12 +987,15 @@ final class MimeTypes implements MimeTypesInterface
'application/x-lzpdf' => ['pdf.lz'],
'application/x-m4' => ['m4'],
'application/x-magicpoint' => ['mgp'],
+ 'application/x-makeself' => ['run'],
+ 'application/x-mame-chd' => ['chd'],
'application/x-markaby' => ['mab'],
'application/x-mathematica' => ['nb'],
'application/x-mdb' => ['mdb'],
'application/x-mie' => ['mie'],
'application/x-mif' => ['mif'],
'application/x-mimearchive' => ['mhtml', 'mht'],
+ 'application/x-mobi8-ebook' => ['azw3', 'kfx'],
'application/x-mobipocket-ebook' => ['prc', 'mobi'],
'application/x-ms-application' => ['application'],
'application/x-ms-asx' => ['asx', 'wax', 'wvx', 'wmx'],
@@ -927,6 +1009,7 @@ final class MimeTypes implements MimeTypesInterface
'application/x-msbinder' => ['obd'],
'application/x-mscardfile' => ['crd'],
'application/x-msclip' => ['clp'],
+ 'application/x-msdos-program' => ['exe'],
'application/x-msdownload' => ['exe', 'dll', 'com', 'bat', 'msi'],
'application/x-msexcel' => ['xls', 'xlc', 'xll', 'xlm', 'xlw', 'xla', 'xlt', 'xld'],
'application/x-msi' => ['msi'],
@@ -948,9 +1031,12 @@ final class MimeTypes implements MimeTypesInterface
'application/x-nes-rom' => ['nes', 'nez', 'unf', 'unif'],
'application/x-netcdf' => ['nc', 'cdf'],
'application/x-netshow-channel' => ['nsc'],
+ 'application/x-nintendo-3ds-executable' => ['3dsx'],
+ 'application/x-nintendo-3ds-rom' => ['3ds', 'cci'],
'application/x-nintendo-ds-rom' => ['nds'],
+ 'application/x-ns-proxy-autoconfig' => ['pac'],
'application/x-nzb' => ['nzb'],
- 'application/x-object' => ['o'],
+ 'application/x-object' => ['o', 'mod'],
'application/x-ogg' => ['ogx'],
'application/x-oleo' => ['oleo'],
'application/x-pagemaker' => ['p65', 'pm', 'pm6', 'pmd'],
@@ -961,16 +1047,21 @@ final class MimeTypes implements MimeTypesInterface
'application/x-pc-engine-rom' => ['pce'],
'application/x-pcap' => ['pcap', 'cap', 'dmp'],
'application/x-pdf' => ['pdf'],
- 'application/x-perl' => ['pl', 'PL', 'pm', 'al', 'perl', 'pod', 't'],
+ 'application/x-perl' => ['pl', 'pm', 'PL', 'al', 'perl', 'pod', 't'],
'application/x-photoshop' => ['psd'],
'application/x-php' => ['php', 'php3', 'php4', 'php5', 'phps'],
+ 'application/x-pilot' => ['prc', 'pdb'],
'application/x-pkcs12' => ['p12', 'pfx'],
'application/x-pkcs7-certificates' => ['p7b', 'spc'],
'application/x-pkcs7-certreqresp' => ['p7r'],
'application/x-planperfect' => ['pln'],
'application/x-pocket-word' => ['psw'],
'application/x-pw' => ['pw'],
+ 'application/x-pyspread-bz-spreadsheet' => ['pys'],
+ 'application/x-pyspread-spreadsheet' => ['pysu'],
'application/x-python-bytecode' => ['pyc', 'pyo'],
+ 'application/x-qed-disk' => ['qed'],
+ 'application/x-qemu-disk' => ['qcow2', 'qcow'],
'application/x-qpress' => ['qp'],
'application/x-qtiplot' => ['qti', 'qti.gz'],
'application/x-quattropro' => ['wb1', 'wb2', 'wb3'],
@@ -990,9 +1081,11 @@ final class MimeTypes implements MimeTypesInterface
'application/x-ruby' => ['rb'],
'application/x-sami' => ['smi', 'sami'],
'application/x-sap-file' => ['sap'],
- 'application/x-saturn-rom' => ['bin', 'iso'],
+ 'application/x-saturn-rom' => ['iso'],
'application/x-sdp' => ['sdp'],
- 'application/x-sega-cd-rom' => ['bin', 'iso'],
+ 'application/x-sea' => ['sea'],
+ 'application/x-sega-cd-rom' => ['iso'],
+ 'application/x-sega-pico-rom' => ['iso'],
'application/x-sg1000-rom' => ['sg'],
'application/x-sh' => ['sh'],
'application/x-shar' => ['shar'],
@@ -1024,13 +1117,15 @@ final class MimeTypes implements MimeTypesInterface
'application/x-t602' => ['602'],
'application/x-tads' => ['gam'],
'application/x-tar' => ['tar', 'gtar', 'gem'],
+ 'application/x-targa' => ['tga', 'icb', 'tpic', 'vda', 'vst'],
'application/x-tarz' => ['tar.Z', 'taz'],
- 'application/x-tcl' => ['tcl'],
+ 'application/x-tcl' => ['tcl', 'tk'],
'application/x-tex' => ['tex', 'ltx', 'sty', 'cls', 'dtx', 'ins', 'latex'],
'application/x-tex-gf' => ['gf'],
'application/x-tex-pk' => ['pk'],
'application/x-tex-tfm' => ['tfm'],
'application/x-texinfo' => ['texinfo', 'texi'],
+ 'application/x-tga' => ['tga', 'icb', 'tpic', 'vda', 'vst'],
'application/x-tgif' => ['obj'],
'application/x-theme' => ['theme'],
'application/x-thomson-cartridge-memo7' => ['m7'],
@@ -1043,10 +1138,24 @@ final class MimeTypes implements MimeTypesInterface
'application/x-tzo' => ['tar.lzo', 'tzo'],
'application/x-ufraw' => ['ufraw'],
'application/x-ustar' => ['ustar'],
+ 'application/x-vdi-disk' => ['vdi'],
+ 'application/x-vhd-disk' => ['vhd', 'vpc'],
+ 'application/x-vhdx-disk' => ['vhdx'],
'application/x-virtual-boy-rom' => ['vb'],
+ 'application/x-virtualbox-hdd' => ['hdd'],
+ 'application/x-virtualbox-ova' => ['ova'],
+ 'application/x-virtualbox-ovf' => ['ovf'],
+ 'application/x-virtualbox-vbox' => ['vbox'],
+ 'application/x-virtualbox-vbox-extpack' => ['vbox-extpack'],
+ 'application/x-virtualbox-vdi' => ['vdi'],
+ 'application/x-virtualbox-vhd' => ['vhd', 'vpc'],
+ 'application/x-virtualbox-vhdx' => ['vhdx'],
+ 'application/x-virtualbox-vmdk' => ['vmdk'],
+ 'application/x-vmdk-disk' => ['vmdk'],
'application/x-vnd.kde.kexi' => ['kexi'],
'application/x-wais-source' => ['src'],
'application/x-wbfs' => ['iso'],
+ 'application/x-web-app-manifest+json' => ['webapp'],
'application/x-wia' => ['iso'],
'application/x-wii-iso-image' => ['iso'],
'application/x-wii-rom' => ['iso'],
@@ -1058,7 +1167,7 @@ final class MimeTypes implements MimeTypesInterface
'application/x-wordperfect' => ['wp', 'wp4', 'wp5', 'wp6', 'wpd', 'wpp'],
'application/x-wpg' => ['wpg'],
'application/x-wwf' => ['wwf'],
- 'application/x-x509-ca-cert' => ['der', 'crt', 'cert', 'pem'],
+ 'application/x-x509-ca-cert' => ['der', 'crt', 'pem', 'cert'],
'application/x-xar' => ['xar', 'pkg'],
'application/x-xbel' => ['xbel'],
'application/x-xfig' => ['fig'],
@@ -1075,25 +1184,32 @@ final class MimeTypes implements MimeTypesInterface
'application/x-zip-compressed-fb2' => ['fb2.zip'],
'application/x-zmachine' => ['z1', 'z2', 'z3', 'z4', 'z5', 'z6', 'z7', 'z8'],
'application/x-zoo' => ['zoo'],
+ 'application/x-zstd-compressed-tar' => ['tar.zst', 'tzst'],
'application/xaml+xml' => ['xaml'],
+ 'application/xcap-att+xml' => ['xav'],
+ 'application/xcap-caps+xml' => ['xca'],
'application/xcap-diff+xml' => ['xdf'],
+ 'application/xcap-el+xml' => ['xel'],
+ 'application/xcap-error+xml' => ['xer'],
+ 'application/xcap-ns+xml' => ['xns'],
'application/xenc+xml' => ['xenc'],
- 'application/xhtml+xml' => ['xhtml', 'xht'],
+ 'application/xhtml+xml' => ['xhtml', 'xht', 'html', 'htm'],
'application/xliff+xml' => ['xlf', 'xliff'],
- 'application/xml' => ['xml', 'xsl', 'xbl', 'xsd', 'rng'],
+ 'application/xml' => ['xml', 'xsl', 'xsd', 'rng', 'xbl'],
'application/xml-dtd' => ['dtd'],
'application/xml-external-parsed-entity' => ['ent'],
'application/xop+xml' => ['xop'],
'application/xproc+xml' => ['xpl'],
- 'application/xps' => ['oxps', 'xps'],
- 'application/xslt+xml' => ['xslt', 'xsl'],
+ 'application/xps' => ['xps'],
+ 'application/xslt+xml' => ['xsl', 'xslt'],
'application/xspf+xml' => ['xspf'],
'application/xv+xml' => ['mxml', 'xhvml', 'xvml', 'xvm'],
'application/yang' => ['yang'],
'application/yin+xml' => ['yin'],
'application/zip' => ['zip'],
'application/zlib' => ['zz'],
- 'audio/3gpp' => ['3gp', '3gpp', '3ga'],
+ 'application/zstd' => ['zst'],
+ 'audio/3gpp' => ['3gpp', '3gp', '3ga'],
'audio/3gpp-encrypted' => ['3gp', '3gpp', '3ga'],
'audio/3gpp2' => ['3g2', '3gp2', '3gpp2'],
'audio/aac' => ['aac', 'adts', 'ass'],
@@ -1110,13 +1226,13 @@ final class MimeTypes implements MimeTypesInterface
'audio/m3u' => ['m3u', 'm3u8', 'vlc'],
'audio/m4a' => ['m4a', 'f4a'],
'audio/midi' => ['mid', 'midi', 'kar', 'rmi'],
- 'audio/mobile-xmf' => ['xmf'],
+ 'audio/mobile-xmf' => ['mxmf', 'xmf'],
'audio/mp2' => ['mp2'],
'audio/mp3' => ['mp3', 'mpga'],
'audio/mp4' => ['m4a', 'mp4a', 'f4a'],
'audio/mpeg' => ['mp3', 'mpga', 'mp2', 'mp2a', 'm2a', 'm3a'],
'audio/mpegurl' => ['m3u', 'm3u8', 'vlc'],
- 'audio/ogg' => ['oga', 'ogg', 'spx', 'opus'],
+ 'audio/ogg' => ['ogg', 'oga', 'spx', 'opus'],
'audio/prs.sid' => ['sid', 'psid'],
'audio/s3m' => ['s3m'],
'audio/scpls' => ['pls'],
@@ -1124,7 +1240,7 @@ final class MimeTypes implements MimeTypesInterface
'audio/tta' => ['tta'],
'audio/usac' => ['loas', 'xhe'],
'audio/vnd.audible' => ['aa', 'aax'],
- 'audio/vnd.audible.aax' => ['aa', 'aax'],
+ 'audio/vnd.audible.aax' => ['aax'],
'audio/vnd.dece.audio' => ['uva', 'uvva'],
'audio/vnd.digital-winds' => ['eol'],
'audio/vnd.dra' => ['dra'],
@@ -1141,6 +1257,7 @@ final class MimeTypes implements MimeTypesInterface
'audio/vnd.wave' => ['wav'],
'audio/vorbis' => ['oga', 'ogg'],
'audio/wav' => ['wav'],
+ 'audio/wave' => ['wav'],
'audio/webm' => ['weba'],
'audio/wma' => ['wma'],
'audio/x-aac' => ['aac', 'adts', 'ass'],
@@ -1178,6 +1295,7 @@ final class MimeTypes implements MimeTypesInterface
'audio/x-ms-asx' => ['asx', 'wax', 'wvx', 'wmx'],
'audio/x-ms-wax' => ['wax'],
'audio/x-ms-wma' => ['wma'],
+ 'audio/x-ms-wmv' => ['wmv'],
'audio/x-musepack' => ['mpc', 'mpp', 'mp+'],
'audio/x-ogg' => ['oga', 'ogg', 'opus'],
'audio/x-oggflac' => ['oga', 'ogg'],
@@ -1187,6 +1305,7 @@ final class MimeTypes implements MimeTypesInterface
'audio/x-pn-realaudio-plugin' => ['rmp'],
'audio/x-psf' => ['psf'],
'audio/x-psflib' => ['psflib'],
+ 'audio/x-realaudio' => ['ra'],
'audio/x-rn-3gpp-amr' => ['3gp', '3gpp', '3ga'],
'audio/x-rn-3gpp-amr-encrypted' => ['3gp', '3gpp', '3ga'],
'audio/x-rn-3gpp-amr-wb' => ['3gp', '3gpp', '3ga'],
@@ -1195,7 +1314,7 @@ final class MimeTypes implements MimeTypesInterface
'audio/x-scpls' => ['pls'],
'audio/x-shorten' => ['shn'],
'audio/x-speex' => ['spx'],
- 'audio/x-speex+ogg' => ['oga', 'ogg'],
+ 'audio/x-speex+ogg' => ['oga', 'ogg', 'spx'],
'audio/x-stm' => ['stm'],
'audio/x-tta' => ['tta'],
'audio/x-voc' => ['voc'],
@@ -1219,44 +1338,70 @@ final class MimeTypes implements MimeTypesInterface
'font/collection' => ['ttc'],
'font/otf' => ['otf'],
'font/ttf' => ['ttf'],
- 'font/woff' => ['woff', 'woff2'],
+ 'font/woff' => ['woff'],
'font/woff2' => ['woff2'],
+ 'image/aces' => ['exr'],
+ 'image/apng' => ['apng'],
+ 'image/astc' => ['astc'],
+ 'image/avif' => ['avif', 'avifs'],
+ 'image/avif-sequence' => ['avif', 'avifs'],
'image/bmp' => ['bmp', 'dib'],
'image/cdr' => ['cdr'],
'image/cgm' => ['cgm'],
+ 'image/dicom-rle' => ['drle'],
'image/emf' => ['emf'],
'image/fax-g3' => ['g3'],
'image/fits' => ['fits'],
'image/g3fax' => ['g3'],
'image/gif' => ['gif'],
'image/heic' => ['heic', 'heif'],
- 'image/heic-sequence' => ['heic', 'heif'],
- 'image/heif' => ['heic', 'heif'],
- 'image/heif-sequence' => ['heic', 'heif'],
+ 'image/heic-sequence' => ['heics', 'heic', 'heif'],
+ 'image/heif' => ['heif', 'heic'],
+ 'image/heif-sequence' => ['heifs', 'heic', 'heif'],
+ 'image/hej2k' => ['hej2'],
+ 'image/hsj2' => ['hsj2'],
'image/ico' => ['ico'],
'image/icon' => ['ico'],
'image/ief' => ['ief'],
+ 'image/jls' => ['jls'],
'image/jp2' => ['jp2', 'jpg2'],
- 'image/jpeg' => ['jpeg', 'jpg', 'jpe'],
+ 'image/jpeg' => ['jpg', 'jpeg', 'jpe'],
'image/jpeg2000' => ['jp2', 'jpg2'],
'image/jpeg2000-image' => ['jp2', 'jpg2'],
+ 'image/jph' => ['jph'],
+ 'image/jphc' => ['jhc'],
'image/jpm' => ['jpm', 'jpgm'],
- 'image/jpx' => ['jpf', 'jpx'],
+ 'image/jpx' => ['jpx', 'jpf'],
+ 'image/jxl' => ['jxl'],
+ 'image/jxr' => ['jxr'],
+ 'image/jxra' => ['jxra'],
+ 'image/jxrs' => ['jxrs'],
+ 'image/jxs' => ['jxs'],
+ 'image/jxsc' => ['jxsc'],
+ 'image/jxsi' => ['jxsi'],
+ 'image/jxss' => ['jxss'],
'image/ktx' => ['ktx'],
+ 'image/ktx2' => ['ktx2'],
'image/openraster' => ['ora'],
'image/pdf' => ['pdf'],
'image/photoshop' => ['psd'],
- 'image/pjpeg' => ['jpeg', 'jpg', 'jpe'],
+ 'image/pjpeg' => ['jpg', 'jpeg', 'jpe'],
'image/png' => ['png'],
'image/prs.btif' => ['btif'],
+ 'image/prs.pti' => ['pti'],
'image/psd' => ['psd'],
'image/rle' => ['rle'],
'image/sgi' => ['sgi'],
'image/svg' => ['svg'],
'image/svg+xml' => ['svg', 'svgz'],
'image/svg+xml-compressed' => ['svgz'],
- 'image/tiff' => ['tiff', 'tif'],
+ 'image/t38' => ['t38'],
+ 'image/targa' => ['tga', 'icb', 'tpic', 'vda', 'vst'],
+ 'image/tga' => ['tga', 'icb', 'tpic', 'vda', 'vst'],
+ 'image/tiff' => ['tif', 'tiff'],
+ 'image/tiff-fx' => ['tfx'],
'image/vnd.adobe.photoshop' => ['psd'],
+ 'image/vnd.airzip.accelerator.azv' => ['azv'],
'image/vnd.dece.graphic' => ['uvi', 'uvvi', 'uvg', 'uvvg'],
'image/vnd.djvu' => ['djvu', 'djv'],
'image/vnd.djvu+multipage' => ['djvu', 'djv'],
@@ -1269,10 +1414,14 @@ final class MimeTypes implements MimeTypesInterface
'image/vnd.fujixerox.edmics-mmr' => ['mmr'],
'image/vnd.fujixerox.edmics-rlc' => ['rlc'],
'image/vnd.microsoft.icon' => ['ico'],
+ 'image/vnd.ms-dds' => ['dds'],
'image/vnd.ms-modi' => ['mdi'],
'image/vnd.ms-photo' => ['wdp'],
'image/vnd.net-fpx' => ['npx'],
+ 'image/vnd.pco.b16' => ['b16'],
'image/vnd.rn-realpix' => ['rp'],
+ 'image/vnd.tencent.tap' => ['tap'],
+ 'image/vnd.valve.source.texture' => ['vtf'],
'image/vnd.wap.wbmp' => ['wbmp'],
'image/vnd.xiff' => ['xif'],
'image/vnd.zbrush.pcx' => ['pcx'],
@@ -1284,6 +1433,7 @@ final class MimeTypes implements MimeTypesInterface
'image/x-bmp' => ['bmp', 'dib'],
'image/x-bzeps' => ['eps.bz2', 'epsi.bz2', 'epsf.bz2'],
'image/x-canon-cr2' => ['cr2'],
+ 'image/x-canon-cr3' => ['cr3'],
'image/x-canon-crw' => ['crw'],
'image/x-cdr' => ['cdr'],
'image/x-cmu-raster' => ['ras'],
@@ -1321,6 +1471,7 @@ final class MimeTypes implements MimeTypesInterface
'image/x-ms-bmp' => ['bmp', 'dib'],
'image/x-msod' => ['msod'],
'image/x-nikon-nef' => ['nef'],
+ 'image/x-nikon-nrw' => ['nrw'],
'image/x-olympus-orf' => ['orf'],
'image/x-panasonic-raw' => ['raw'],
'image/x-panasonic-raw2' => ['rw2'],
@@ -1345,6 +1496,7 @@ final class MimeTypes implements MimeTypesInterface
'image/x-sony-sr2' => ['sr2'],
'image/x-sony-srf' => ['srf'],
'image/x-sun-raster' => ['sun'],
+ 'image/x-targa' => ['tga', 'icb', 'tpic', 'vda', 'vst'],
'image/x-tga' => ['tga', 'icb', 'tpic', 'vda', 'vst'],
'image/x-win-bitmap' => ['cur'],
'image/x-win-metafile' => ['wmf'],
@@ -1356,24 +1508,47 @@ final class MimeTypes implements MimeTypesInterface
'image/x-xpm' => ['xpm'],
'image/x-xwindowdump' => ['xwd'],
'image/x.djvu' => ['djvu', 'djv'],
+ 'message/disposition-notification' => ['disposition-notification'],
+ 'message/global' => ['u8msg'],
+ 'message/global-delivery-status' => ['u8dsn'],
+ 'message/global-disposition-notification' => ['u8mdn'],
+ 'message/global-headers' => ['u8hdr'],
'message/rfc822' => ['eml', 'mime'],
+ 'message/vnd.wfa.wsc' => ['wsc'],
+ 'model/3mf' => ['3mf'],
+ 'model/gltf+json' => ['gltf'],
+ 'model/gltf-binary' => ['glb'],
'model/iges' => ['igs', 'iges'],
'model/mesh' => ['msh', 'mesh', 'silo'],
+ 'model/mtl' => ['mtl'],
+ 'model/obj' => ['obj'],
+ 'model/step+zip' => ['stpz'],
+ 'model/step-xml+zip' => ['stpxz'],
'model/stl' => ['stl'],
'model/vnd.collada+xml' => ['dae'],
'model/vnd.dwf' => ['dwf'],
'model/vnd.gdl' => ['gdl'],
'model/vnd.gtw' => ['gtw'],
'model/vnd.mts' => ['mts'],
+ 'model/vnd.opengex' => ['ogex'],
+ 'model/vnd.parasolid.transmit.binary' => ['x_b'],
+ 'model/vnd.parasolid.transmit.text' => ['x_t'],
+ 'model/vnd.sap.vds' => ['vds'],
+ 'model/vnd.usdz+zip' => ['usdz'],
+ 'model/vnd.valve.source.compiled-map' => ['bsp'],
'model/vnd.vtu' => ['vtu'],
'model/vrml' => ['wrl', 'vrml', 'vrm'],
'model/x.stl-ascii' => ['stl'],
'model/x.stl-binary' => ['stl'],
'model/x3d+binary' => ['x3db', 'x3dbz'],
+ 'model/x3d+fastinfoset' => ['x3db'],
'model/x3d+vrml' => ['x3dv', 'x3dvz'],
'model/x3d+xml' => ['x3d', 'x3dz'],
+ 'model/x3d-vrml' => ['x3dv'],
'text/cache-manifest' => ['appcache', 'manifest'],
'text/calendar' => ['ics', 'ifb', 'vcs'],
+ 'text/coffeescript' => ['coffee', 'litcoffee'],
+ 'text/crystal' => ['cr'],
'text/css' => ['css'],
'text/csv' => ['csv'],
'text/csv-schema' => ['csvs'],
@@ -1381,13 +1556,18 @@ final class MimeTypes implements MimeTypesInterface
'text/ecmascript' => ['es'],
'text/gedcom' => ['ged', 'gedcom'],
'text/google-video-pointer' => ['gvp'],
- 'text/html' => ['html', 'htm'],
+ 'text/html' => ['html', 'htm', 'shtml'],
'text/ico' => ['ico'],
+ 'text/jade' => ['jade'],
'text/javascript' => ['js', 'jsm', 'mjs'],
- 'text/markdown' => ['md', 'mkd', 'markdown'],
+ 'text/jsx' => ['jsx'],
+ 'text/less' => ['less'],
+ 'text/markdown' => ['md', 'markdown', 'mkd'],
'text/mathml' => ['mml'],
+ 'text/mdx' => ['mdx'],
'text/n3' => ['n3'],
- 'text/plain' => ['txt', 'text', 'conf', 'def', 'list', 'log', 'in', 'asc'],
+ 'text/org' => ['org'],
+ 'text/plain' => ['txt', 'text', 'conf', 'def', 'list', 'log', 'in', 'ini', 'asc'],
'text/prs.lines.tag' => ['dsc'],
'text/rdf' => ['rdf', 'rdfs', 'owl'],
'text/richtext' => ['rtx'],
@@ -1395,11 +1575,18 @@ final class MimeTypes implements MimeTypesInterface
'text/rtf' => ['rtf'],
'text/rust' => ['rs'],
'text/sgml' => ['sgml', 'sgm'],
+ 'text/shex' => ['shex'],
+ 'text/slim' => ['slim', 'slm'],
+ 'text/spdx' => ['spdx'],
'text/spreadsheet' => ['sylk', 'slk'],
+ 'text/stylus' => ['stylus', 'styl'],
'text/tab-separated-values' => ['tsv'],
+ 'text/tcl' => ['tcl', 'tk'],
'text/troff' => ['t', 'tr', 'roff', 'man', 'me', 'ms'],
'text/turtle' => ['ttl'],
'text/uri-list' => ['uri', 'uris', 'urls'],
+ 'text/vbs' => ['vbs'],
+ 'text/vbscript' => ['vbs'],
'text/vcard' => ['vcard', 'vcf', 'vct', 'gcrd'],
'text/vnd.curl' => ['curl'],
'text/vnd.curl.dcurl' => ['dcurl'],
@@ -1413,6 +1600,7 @@ final class MimeTypes implements MimeTypesInterface
'text/vnd.in3d.spot' => ['spot'],
'text/vnd.qt.linguist' => ['ts'],
'text/vnd.rn-realtext' => ['rt'],
+ 'text/vnd.senx.warpscript' => ['mc2'],
'text/vnd.sun.j2me.app-descriptor' => ['jad'],
'text/vnd.trolltech.linguist' => ['ts'],
'text/vnd.wap.wml' => ['wml'],
@@ -1428,9 +1616,13 @@ final class MimeTypes implements MimeTypesInterface
'text/x-cmake' => ['cmake'],
'text/x-cobol' => ['cbl', 'cob'],
'text/x-comma-separated-values' => ['csv'],
+ 'text/x-common-lisp' => ['asd', 'fasl', 'lisp', 'ros'],
+ 'text/x-component' => ['htc'],
+ 'text/x-crystal' => ['cr'],
'text/x-csharp' => ['cs'],
'text/x-csrc' => ['c'],
'text/x-csv' => ['csv'],
+ 'text/x-dart' => ['dart'],
'text/x-dbus-service' => ['service'],
'text/x-dcl' => ['dcl'],
'text/x-diff' => ['diff', 'patch'],
@@ -1438,6 +1630,7 @@ final class MimeTypes implements MimeTypesInterface
'text/x-dsrc' => ['d', 'di'],
'text/x-dtd' => ['dtd'],
'text/x-eiffel' => ['e', 'eif'],
+ 'text/x-elixir' => ['ex', 'exs'],
'text/x-emacs-lisp' => ['el'],
'text/x-erlang' => ['erl'],
'text/x-fortran' => ['f', 'for', 'f77', 'f90', 'f95'],
@@ -1447,12 +1640,17 @@ final class MimeTypes implements MimeTypesInterface
'text/x-gherkin' => ['feature'],
'text/x-go' => ['go'],
'text/x-google-video-pointer' => ['gvp'],
+ 'text/x-gradle' => ['gradle'],
+ 'text/x-groovy' => ['groovy', 'gvy', 'gy', 'gsh'],
+ 'text/x-handlebars-template' => ['hbs'],
'text/x-haskell' => ['hs'],
'text/x-idl' => ['idl'],
'text/x-imelody' => ['imy', 'ime'],
'text/x-iptables' => ['iptables'],
'text/x-java' => ['java'],
'text/x-java-source' => ['java'],
+ 'text/x-kaitai-struct' => ['ksy'],
+ 'text/x-kotlin' => ['kt'],
'text/x-ldif' => ['ldif'],
'text/x-lilypond' => ['ly'],
'text/x-literate-haskell' => ['lhs'],
@@ -1479,18 +1677,22 @@ final class MimeTypes implements MimeTypesInterface
'text/x-opencl-src' => ['cl'],
'text/x-opml' => ['opml'],
'text/x-opml+xml' => ['opml'],
+ 'text/x-org' => ['org'],
'text/x-pascal' => ['p', 'pas'],
'text/x-patch' => ['diff', 'patch'],
'text/x-perl' => ['pl', 'PL', 'pm', 'al', 'perl', 'pod', 't'],
'text/x-po' => ['po'],
'text/x-pot' => ['pot'],
+ 'text/x-processing' => ['pde'],
'text/x-python' => ['py', 'pyx', 'wsgi'],
- 'text/x-python3' => ['py', 'py3', 'py3x'],
+ 'text/x-python3' => ['py', 'py3', 'py3x', 'pyi'],
'text/x-qml' => ['qml', 'qmltypes', 'qmlproject'],
'text/x-reject' => ['rej'],
'text/x-rpm-spec' => ['spec'],
+ 'text/x-rst' => ['rst'],
+ 'text/x-sagemath' => ['sage'],
'text/x-sass' => ['sass'],
- 'text/x-scala' => ['scala'],
+ 'text/x-scala' => ['scala', 'sc'],
'text/x-scheme' => ['scm', 'ss'],
'text/x-scss' => ['scss'],
'text/x-setext' => ['etx'],
@@ -1499,6 +1701,7 @@ final class MimeTypes implements MimeTypesInterface
'text/x-sql' => ['sql'],
'text/x-ssa' => ['ssa', 'ass'],
'text/x-subviewer' => ['sub'],
+ 'text/x-suse-ymp' => ['ymp'],
'text/x-svhdr' => ['svh'],
'text/x-svsrc' => ['sv'],
'text/x-systemd-unit' => ['automount', 'device', 'mount', 'path', 'scope', 'service', 'slice', 'socket', 'swap', 'target', 'timer'],
@@ -1538,17 +1741,18 @@ final class MimeTypes implements MimeTypesInterface
'video/h261' => ['h261'],
'video/h263' => ['h263'],
'video/h264' => ['h264'],
+ 'video/iso.segment' => ['m4s'],
'video/jpeg' => ['jpgv'],
'video/jpm' => ['jpm', 'jpgm'],
'video/mj2' => ['mj2', 'mjp2'],
- 'video/mp2t' => ['m2t', 'm2ts', 'ts', 'mts', 'cpi', 'clpi', 'mpl', 'mpls', 'bdm', 'bdmv'],
+ 'video/mp2t' => ['ts', 'm2t', 'm2ts', 'mts', 'cpi', 'clpi', 'mpl', 'mpls', 'bdm', 'bdmv'],
'video/mp4' => ['mp4', 'mp4v', 'mpg4', 'm4v', 'f4v', 'lrv'],
'video/mp4v-es' => ['mp4', 'm4v', 'f4v', 'lrv'],
'video/mpeg' => ['mpeg', 'mpg', 'mpe', 'm1v', 'm2v', 'mp2', 'vob'],
'video/mpeg-system' => ['mpeg', 'mpg', 'mp2', 'mpe', 'vob'],
'video/msvideo' => ['avi', 'avf', 'divx'],
'video/ogg' => ['ogv', 'ogg'],
- 'video/quicktime' => ['qt', 'mov', 'moov', 'qtvr'],
+ 'video/quicktime' => ['mov', 'qt', 'moov', 'qtvr'],
'video/vivo' => ['viv', 'vivo'],
'video/vnd.dece.hd' => ['uvh', 'uvvh'],
'video/vnd.dece.mobile' => ['uvm', 'uvvm'],
@@ -1560,6 +1764,8 @@ final class MimeTypes implements MimeTypesInterface
'video/vnd.fvt' => ['fvt'],
'video/vnd.mpegurl' => ['mxu', 'm4u', 'm1u'],
'video/vnd.ms-playready.media.pyv' => ['pyv'],
+ 'video/vnd.radgamettools.bink' => ['bik', 'bk2'],
+ 'video/vnd.radgamettools.smacker' => ['smk'],
'video/vnd.rn-realvideo' => ['rv', 'rvx'],
'video/vnd.uvvu.mp4' => ['uvu', 'uvvu'],
'video/vnd.vivo' => ['viv', 'vivo'],
@@ -1612,16 +1818,20 @@ final class MimeTypes implements MimeTypesInterface
];
private const REVERSE_MAP = [
+ '1km' => ['application/vnd.1000minds.decision-model+xml'],
'32x' => ['application/x-genesis-32x-rom'],
'3dml' => ['text/vnd.in3d.3dml'],
- '3ds' => ['image/x-3ds'],
+ '3ds' => ['application/x-nintendo-3ds-rom', 'image/x-3ds'],
+ '3dsx' => ['application/x-nintendo-3ds-executable'],
'3g2' => ['audio/3gpp2', 'video/3gpp2'],
'3ga' => ['audio/3gpp', 'audio/3gpp-encrypted', 'audio/x-rn-3gpp-amr', 'audio/x-rn-3gpp-amr-encrypted', 'audio/x-rn-3gpp-amr-wb', 'audio/x-rn-3gpp-amr-wb-encrypted', 'video/3gp', 'video/3gpp', 'video/3gpp-encrypted'],
'3gp' => ['audio/3gpp', 'audio/3gpp-encrypted', 'audio/x-rn-3gpp-amr', 'audio/x-rn-3gpp-amr-encrypted', 'audio/x-rn-3gpp-amr-wb', 'audio/x-rn-3gpp-amr-wb-encrypted', 'video/3gp', 'video/3gpp', 'video/3gpp-encrypted'],
'3gp2' => ['audio/3gpp2', 'video/3gpp2'],
'3gpp' => ['audio/3gpp', 'audio/3gpp-encrypted', 'audio/x-rn-3gpp-amr', 'audio/x-rn-3gpp-amr-encrypted', 'audio/x-rn-3gpp-amr-wb', 'audio/x-rn-3gpp-amr-wb-encrypted', 'video/3gp', 'video/3gpp', 'video/3gpp-encrypted'],
'3gpp2' => ['audio/3gpp2', 'video/3gpp2'],
+ '3mf' => ['model/3mf'],
'7z' => ['application/x-7z-compressed'],
+ '7z.001' => ['application/x-7z-compressed'],
'BLEND' => ['application/x-blender'],
'C' => ['text/x-c++src'],
'PAR2' => ['application/x-par2'],
@@ -1630,7 +1840,7 @@ final class MimeTypes implements MimeTypesInterface
'a' => ['application/x-archive'],
'a26' => ['application/x-atari-2600-rom'],
'a78' => ['application/x-atari-7800-rom'],
- 'aa' => ['audio/vnd.audible', 'audio/vnd.audible.aax', 'audio/x-pn-audibleaudio'],
+ 'aa' => ['audio/vnd.audible', 'audio/x-pn-audibleaudio'],
'aab' => ['application/x-authorware-bin'],
'aac' => ['audio/aac', 'audio/x-aac', 'audio/x-hx-aac-adts'],
'aam' => ['application/x-authorware-map'],
@@ -1639,7 +1849,7 @@ final class MimeTypes implements MimeTypesInterface
'abw' => ['application/x-abiword'],
'abw.CRASHED' => ['application/x-abiword'],
'abw.gz' => ['application/x-abiword'],
- 'ac' => ['application/pkix-attr-cert'],
+ 'ac' => ['application/pkix-attr-cert', 'application/vnd.nokia.n-gage.ac+xml'],
'ac3' => ['audio/ac3'],
'acc' => ['application/vnd.americandynamics.acc'],
'ace' => ['application/x-ace', 'application/x-ace-compressed'],
@@ -1673,32 +1883,38 @@ final class MimeTypes implements MimeTypesInterface
'anx' => ['application/annodex', 'application/x-annodex'],
'ape' => ['audio/x-ape'],
'apk' => ['application/vnd.android.package-archive'],
+ 'apng' => ['image/apng'],
'appcache' => ['text/cache-manifest'],
'appimage' => ['application/vnd.appimage', 'application/x-iso9660-appimage'],
'application' => ['application/x-ms-application'],
'apr' => ['application/vnd.lotus-approach'],
- 'aps' => ['application/postscript'],
'ar' => ['application/x-archive'],
'arc' => ['application/x-freearc'],
'arj' => ['application/x-arj'],
'arw' => ['image/x-sony-arw'],
'as' => ['application/x-applix-spreadsheet'],
'asc' => ['application/pgp', 'application/pgp-encrypted', 'application/pgp-keys', 'application/pgp-signature', 'text/plain'],
+ 'asd' => ['text/x-common-lisp'],
'asf' => ['application/vnd.ms-asf', 'video/x-ms-asf', 'video/x-ms-asf-plugin', 'video/x-ms-wm'],
+ 'asice' => ['application/vnd.etsi.asic-e+zip'],
'asm' => ['text/x-asm'],
'aso' => ['application/vnd.accpac.simply.aso'],
'asp' => ['application/x-asp'],
'ass' => ['audio/aac', 'audio/x-aac', 'audio/x-hx-aac-adts', 'text/x-ssa'],
+ 'astc' => ['image/astc'],
'asx' => ['application/x-ms-asx', 'audio/x-ms-asx', 'video/x-ms-asf', 'video/x-ms-wax', 'video/x-ms-wmx', 'video/x-ms-wvx'],
'atc' => ['application/vnd.acucorp'],
'atom' => ['application/atom+xml'],
'atomcat' => ['application/atomcat+xml'],
+ 'atomdeleted' => ['application/atomdeleted+xml'],
'atomsvc' => ['application/atomsvc+xml'],
'atx' => ['application/vnd.antix.game-component'],
'au' => ['audio/basic'],
'automount' => ['text/x-systemd-unit'],
'avf' => ['video/avi', 'video/divx', 'video/msvideo', 'video/vnd.divx', 'video/x-avi', 'video/x-msvideo'],
'avi' => ['video/avi', 'video/divx', 'video/msvideo', 'video/vnd.divx', 'video/x-avi', 'video/x-msvideo'],
+ 'avif' => ['image/avif', 'image/avif-sequence'],
+ 'avifs' => ['image/avif', 'image/avif-sequence'],
'aw' => ['application/applixware', 'application/x-applix-word'],
'awb' => ['audio/amr-wb', 'audio/amr-wb-encrypted'],
'awk' => ['application/x-awk'],
@@ -1706,31 +1922,39 @@ final class MimeTypes implements MimeTypesInterface
'axv' => ['video/annodex', 'video/x-annodex'],
'azf' => ['application/vnd.airzip.filesecure.azf'],
'azs' => ['application/vnd.airzip.filesecure.azs'],
+ 'azv' => ['image/vnd.airzip.accelerator.azv'],
'azw' => ['application/vnd.amazon.ebook'],
+ 'azw3' => ['application/vnd.amazon.mobi8-ebook', 'application/x-mobi8-ebook'],
+ 'b16' => ['image/vnd.pco.b16'],
'bak' => ['application/x-trash'],
'bat' => ['application/x-msdownload'],
'bcpio' => ['application/x-bcpio'],
'bdf' => ['application/x-font-bdf'],
'bdm' => ['application/vnd.syncml.dm+wbxml', 'video/mp2t'],
'bdmv' => ['video/mp2t'],
+ 'bdoc' => ['application/bdoc', 'application/x-bdoc'],
'bed' => ['application/vnd.realvnc.bed'],
'bh2' => ['application/vnd.fujitsu.oasysprs'],
'bib' => ['text/x-bibtex'],
- 'bin' => ['application/octet-stream', 'application/x-saturn-rom', 'application/x-sega-cd-rom'],
+ 'bik' => ['video/vnd.radgamettools.bink'],
+ 'bin' => ['application/octet-stream'],
+ 'bk2' => ['video/vnd.radgamettools.bink'],
'blb' => ['application/x-blorb'],
'blend' => ['application/x-blender'],
'blender' => ['application/x-blender'],
'blorb' => ['application/x-blorb'],
'bmi' => ['application/vnd.bmi'],
+ 'bmml' => ['application/vnd.balsamiq.bmml+xml'],
'bmp' => ['image/bmp', 'image/x-bmp', 'image/x-ms-bmp'],
'book' => ['application/vnd.framemaker'],
'box' => ['application/vnd.previewsystems.box'],
'boz' => ['application/x-bzip2'],
- 'bpk' => ['application/octet-stream'],
+ 'bps' => ['application/x-bps-patch'],
'bsdiff' => ['application/x-bsdiff'],
+ 'bsp' => ['model/vnd.valve.source.compiled-map'],
'btif' => ['image/prs.btif'],
- 'bz' => ['application/x-bzip', 'application/x-bzip2'],
- 'bz2' => ['application/x-bz2', 'application/x-bzip', 'application/x-bzip2'],
+ 'bz' => ['application/bzip2', 'application/x-bzip', 'application/x-bzip2'],
+ 'bz2' => ['application/x-bz2', 'application/bzip2', 'application/x-bzip', 'application/x-bzip2'],
'c' => ['text/x-c', 'text/x-csrc'],
'c++' => ['text/x-c++src'],
'c11amc' => ['application/vnd.cluetrust.cartomobile-config'],
@@ -1752,11 +1976,15 @@ final class MimeTypes implements MimeTypesInterface
'cbt' => ['application/x-cbr', 'application/x-cbt'],
'cbz' => ['application/vnd.comicbook+zip', 'application/x-cbr', 'application/x-cbz'],
'cc' => ['text/x-c', 'text/x-c++src'],
+ 'cci' => ['application/x-nintendo-3ds-rom'],
'ccmx' => ['application/x-ccmx'],
+ 'cco' => ['application/x-cocoa'],
'cct' => ['application/x-director'],
'ccxml' => ['application/ccxml+xml'],
'cdbcmsg' => ['application/vnd.contact.cmsg'],
'cdf' => ['application/x-netcdf'],
+ 'cdfx' => ['application/cdfx+xml'],
+ 'cdi' => ['application/x-discjuggler-cd-image'],
'cdkey' => ['application/vnd.mediastation.cdkey'],
'cdmia' => ['application/cdmi-capability'],
'cdmic' => ['application/cdmi-container'],
@@ -1773,11 +2001,13 @@ final class MimeTypes implements MimeTypesInterface
'cgb' => ['application/x-gameboy-color-rom'],
'cgm' => ['image/cgm'],
'chat' => ['application/x-chat'],
+ 'chd' => ['application/x-mame-chd'],
'chm' => ['application/vnd.ms-htmlhelp', 'application/x-chm'],
'chrt' => ['application/vnd.kde.kchart', 'application/x-kchart'],
'cif' => ['chemical/x-cif'],
'cii' => ['application/vnd.anser-web-certificate-issue-initiation'],
'cil' => ['application/vnd.ms-artgalry'],
+ 'cjs' => ['application/node'],
'cl' => ['text/x-opencl-src'],
'cla' => ['application/vnd.claymore'],
'class' => ['application/java', 'application/java-byte-code', 'application/java-vm', 'application/x-java', 'application/x-java-class', 'application/x-java-vm'],
@@ -1797,7 +2027,7 @@ final class MimeTypes implements MimeTypesInterface
'cmx' => ['image/x-cmx'],
'cob' => ['text/x-cobol'],
'cod' => ['application/vnd.rim.cod'],
- 'coffee' => ['application/vnd.coffeescript'],
+ 'coffee' => ['application/vnd.coffeescript', 'text/coffeescript'],
'com' => ['application/x-msdownload'],
'conf' => ['text/plain'],
'cpi' => ['video/mp2t'],
@@ -1805,25 +2035,31 @@ final class MimeTypes implements MimeTypesInterface
'cpio.gz' => ['application/x-cpio-compressed'],
'cpp' => ['text/x-c', 'text/x-c++src'],
'cpt' => ['application/mac-compactpro'],
+ 'cr' => ['text/crystal', 'text/x-crystal'],
'cr2' => ['image/x-canon-cr2'],
+ 'cr3' => ['image/x-canon-cr3'],
'crd' => ['application/x-mscardfile'],
'crdownload' => ['application/x-partial-download'],
'crl' => ['application/pkix-crl'],
'crt' => ['application/x-x509-ca-cert'],
'crw' => ['image/x-canon-crw'],
+ 'crx' => ['application/x-chrome-extension'],
'cryptonote' => ['application/vnd.rig.cryptonote'],
'cs' => ['text/x-csharp'],
'csh' => ['application/x-csh'],
+ 'csl' => ['application/vnd.citationstyles.style+xml'],
'csml' => ['chemical/x-csml'],
+ 'cso' => ['application/x-compressed-iso'],
'csp' => ['application/vnd.commonspace'],
'css' => ['text/css'],
'cst' => ['application/x-director'],
- 'csv' => ['text/csv', 'text/x-comma-separated-values', 'text/x-csv', 'application/csv'],
+ 'csv' => ['text/csv', 'application/csv', 'text/x-comma-separated-values', 'text/x-csv'],
'csvs' => ['text/csv-schema'],
'cu' => ['application/cu-seeme'],
'cue' => ['application/x-cue'],
'cur' => ['image/x-win-bitmap'],
'curl' => ['text/vnd.curl'],
+ 'cwk' => ['application/x-appleworks-document'],
'cww' => ['application/prs.cww'],
'cxt' => ['application/x-director'],
'cxx' => ['text/x-c', 'text/x-c++src'],
@@ -1831,10 +2067,10 @@ final class MimeTypes implements MimeTypesInterface
'dae' => ['model/vnd.collada+xml'],
'daf' => ['application/vnd.mobius.daf'],
'dar' => ['application/x-dar'],
- 'dart' => ['application/vnd.dart'],
+ 'dart' => ['application/vnd.dart', 'text/x-dart'],
'dataless' => ['application/vnd.fdsn.seed'],
'davmount' => ['application/davmount+xml'],
- 'dbf' => ['application/dbase', 'application/dbf', 'application/x-dbase', 'application/x-dbf'],
+ 'dbf' => ['application/dbase', 'application/dbf', 'application/vnd.dbf', 'application/x-dbase', 'application/x-dbf'],
'dbk' => ['application/docbook+xml', 'application/vnd.oasis.docbook+xml', 'application/x-docbook+xml'],
'dc' => ['application/x-dc-rom'],
'dcl' => ['text/x-dcl'],
@@ -1843,10 +2079,10 @@ final class MimeTypes implements MimeTypesInterface
'dcurl' => ['text/vnd.curl.dcurl'],
'dd2' => ['application/vnd.oma.dd2+xml'],
'ddd' => ['application/vnd.fujixerox.ddd'],
- 'dds' => ['image/x-dds'],
+ 'ddf' => ['application/vnd.syncml.dmddf+xml'],
+ 'dds' => ['image/vnd.ms-dds', 'image/x-dds'],
'deb' => ['application/vnd.debian.binary-package', 'application/x-deb', 'application/x-debian-package'],
'def' => ['text/plain'],
- 'deploy' => ['application/octet-stream'],
'der' => ['application/x-x509-ca-cert'],
'desktop' => ['application/x-desktop', 'application/x-gnome-app-info'],
'device' => ['text/x-systemd-unit'],
@@ -1859,15 +2095,13 @@ final class MimeTypes implements MimeTypesInterface
'diff' => ['text/x-diff', 'text/x-patch'],
'dir' => ['application/x-director'],
'dis' => ['application/vnd.mobius.dis'],
- 'dist' => ['application/octet-stream'],
- 'distz' => ['application/octet-stream'],
+ 'disposition-notification' => ['message/disposition-notification'],
'divx' => ['video/avi', 'video/divx', 'video/msvideo', 'video/vnd.divx', 'video/x-avi', 'video/x-msvideo'],
'djv' => ['image/vnd.djvu', 'image/vnd.djvu+multipage', 'image/x-djvu', 'image/x.djvu'],
'djvu' => ['image/vnd.djvu', 'image/vnd.djvu+multipage', 'image/x-djvu', 'image/x.djvu'],
'dll' => ['application/x-msdownload'],
'dmg' => ['application/x-apple-diskimage'],
'dmp' => ['application/pcap', 'application/vnd.tcpdump.pcap', 'application/x-pcap'],
- 'dms' => ['application/octet-stream'],
'dna' => ['application/vnd.dna'],
'dng' => ['image/x-adobe-dng'],
'doc' => ['application/msword', 'application/vnd.ms-word', 'application/x-msword', 'zz-application/zz-winassoc-doc'],
@@ -1880,6 +2114,7 @@ final class MimeTypes implements MimeTypesInterface
'dp' => ['application/vnd.osgi.dp'],
'dpg' => ['application/vnd.dpgraph'],
'dra' => ['audio/vnd.dra'],
+ 'drle' => ['image/dicom-rle'],
'dsc' => ['text/prs.lines.tag'],
'dsl' => ['text/x-dsl'],
'dssc' => ['application/dssc+der'],
@@ -1888,18 +2123,19 @@ final class MimeTypes implements MimeTypesInterface
'dts' => ['audio/vnd.dts', 'audio/x-dts'],
'dtshd' => ['audio/vnd.dts.hd', 'audio/x-dtshd'],
'dtx' => ['application/x-tex', 'text/x-tex'],
- 'dump' => ['application/octet-stream'],
'dv' => ['video/dv'],
'dvb' => ['video/vnd.dvb.file'],
'dvi' => ['application/x-dvi'],
'dvi.bz2' => ['application/x-bzdvi'],
'dvi.gz' => ['application/x-gzdvi'],
+ 'dwd' => ['application/atsc-dwd+xml'],
'dwf' => ['model/vnd.dwf'],
'dwg' => ['image/vnd.dwg'],
'dxf' => ['image/vnd.dxf'],
'dxp' => ['application/vnd.spotfire.dxp'],
'dxr' => ['application/x-director'],
'e' => ['text/x-eiffel'],
+ 'ear' => ['application/java-archive'],
'ecelp4800' => ['audio/vnd.nuera.ecelp4800'],
'ecelp7470' => ['audio/vnd.nuera.ecelp7470'],
'ecelp9600' => ['audio/vnd.nuera.ecelp9600'],
@@ -1911,10 +2147,10 @@ final class MimeTypes implements MimeTypesInterface
'ei6' => ['application/vnd.pg.osasli'],
'eif' => ['text/x-eiffel'],
'el' => ['text/x-emacs-lisp'],
- 'elc' => ['application/octet-stream'],
'emf' => ['application/emf', 'application/x-emf', 'application/x-msmetafile', 'image/emf', 'image/x-emf'],
'eml' => ['message/rfc822'],
'emma' => ['application/emma+xml'],
+ 'emotionml' => ['application/emotionml+xml'],
'emp' => ['application/vnd.emusic-emusic_package'],
'emz' => ['application/x-msmetafile'],
'ent' => ['application/xml-external-parsed-entity', 'text/xml-external-parsed-entity'],
@@ -1940,9 +2176,11 @@ final class MimeTypes implements MimeTypesInterface
'etx' => ['text/x-setext'],
'eva' => ['application/x-eva'],
'evy' => ['application/x-envoy'],
- 'exe' => ['application/x-ms-dos-executable', 'application/x-msdownload'],
+ 'ex' => ['text/x-elixir'],
+ 'exe' => ['application/x-ms-dos-executable', 'application/x-msdos-program', 'application/x-msdownload'],
'exi' => ['application/exi'],
- 'exr' => ['image/x-exr'],
+ 'exr' => ['image/aces', 'image/x-exr'],
+ 'exs' => ['text/x-elixir'],
'ext' => ['application/vnd.novadigm.ext'],
'ez' => ['application/andrew-inset'],
'ez2' => ['application/vnd.ezpix-album'],
@@ -1954,6 +2192,7 @@ final class MimeTypes implements MimeTypesInterface
'f77' => ['text/x-fortran'],
'f90' => ['text/x-fortran'],
'f95' => ['text/x-fortran'],
+ 'fasl' => ['text/x-common-lisp'],
'fb2' => ['application/x-fictionbook', 'application/x-fictionbook+xml'],
'fb2.zip' => ['application/x-zip-compressed-fb2'],
'fbs' => ['image/vnd.fastbidsheet'],
@@ -1962,6 +2201,7 @@ final class MimeTypes implements MimeTypesInterface
'fd' => ['application/x-fd-file', 'application/x-raw-floppy-disk-image'],
'fdf' => ['application/vnd.fdf'],
'fds' => ['application/x-fds-disk'],
+ 'fdt' => ['application/fdt+xml'],
'fe_launch' => ['application/vnd.denovo.fcselayout-link'],
'feature' => ['text/x-gherkin'],
'fg5' => ['application/vnd.fujitsu.oasysgp'],
@@ -1987,7 +2227,7 @@ final class MimeTypes implements MimeTypesInterface
'fly' => ['text/vnd.fly'],
'fm' => ['application/vnd.framemaker', 'application/x-frame'],
'fnc' => ['application/vnd.frogans.fnc'],
- 'fo' => ['text/x-xslfo'],
+ 'fo' => ['application/vnd.software602.filler.form+xml', 'text/x-xslfo'],
'fodg' => ['application/vnd.oasis.opendocument.graphics-flat-xml'],
'fodp' => ['application/vnd.oasis.opendocument.presentation-flat-xml'],
'fods' => ['application/vnd.oasis.opendocument.spreadsheet-flat-xml'],
@@ -2016,7 +2256,9 @@ final class MimeTypes implements MimeTypesInterface
'gca' => ['application/x-gca-compressed'],
'gcode' => ['text/x.gcode'],
'gcrd' => ['text/directory', 'text/vcard', 'text/x-vcard'],
+ 'gdi' => ['application/x-gd-rom-cue'],
'gdl' => ['model/vnd.gdl'],
+ 'gdoc' => ['application/vnd.google-apps.document'],
'ged' => ['application/x-gedcom', 'text/gedcom'],
'gedcom' => ['application/x-gedcom', 'text/gedcom'],
'gem' => ['application/x-gtar', 'application/x-tar'],
@@ -2034,6 +2276,8 @@ final class MimeTypes implements MimeTypesInterface
'gih' => ['image/x-gimp-gih'],
'gim' => ['application/vnd.groove-identity-message'],
'glade' => ['application/x-glade'],
+ 'glb' => ['model/gltf-binary'],
+ 'gltf' => ['model/gltf+json'],
'gml' => ['application/gml+xml'],
'gmo' => ['application/x-gettext-translation'],
'gmx' => ['application/vnd.gmx'],
@@ -2051,21 +2295,28 @@ final class MimeTypes implements MimeTypesInterface
'gqf' => ['application/vnd.grafeq'],
'gqs' => ['application/vnd.grafeq'],
'gra' => ['application/x-graphite'],
+ 'gradle' => ['text/x-gradle'],
'gram' => ['application/srgs'],
'gramps' => ['application/x-gramps-xml'],
'gre' => ['application/vnd.geometry-explorer'],
+ 'groovy' => ['text/x-groovy'],
'grv' => ['application/vnd.groove-injector'],
'grxml' => ['application/srgs+xml'],
'gs' => ['text/x-genie'],
'gsf' => ['application/x-font-ghostscript', 'application/x-font-type1'],
+ 'gsh' => ['text/x-groovy'],
+ 'gsheet' => ['application/vnd.google-apps.spreadsheet'],
+ 'gslides' => ['application/vnd.google-apps.presentation'],
'gsm' => ['audio/x-gsm'],
'gtar' => ['application/x-gtar', 'application/x-tar'],
'gtm' => ['application/vnd.groove-tool-message'],
'gtw' => ['model/vnd.gtw'],
'gv' => ['text/vnd.graphviz'],
'gvp' => ['text/google-video-pointer', 'text/x-google-video-pointer'],
+ 'gvy' => ['text/x-groovy'],
'gxf' => ['application/gxf'],
'gxt' => ['application/vnd.geonext'],
+ 'gy' => ['text/x-groovy'],
'gz' => ['application/x-gzip', 'application/gzip'],
'h' => ['text/x-c', 'text/x-chdr'],
'h++' => ['text/x-c++hdr'],
@@ -2076,13 +2327,20 @@ final class MimeTypes implements MimeTypesInterface
'h5' => ['application/x-hdf'],
'hal' => ['application/vnd.hal+xml'],
'hbci' => ['application/vnd.hbci'],
+ 'hbs' => ['text/x-handlebars-template'],
+ 'hdd' => ['application/x-virtualbox-hdd'],
'hdf' => ['application/x-hdf'],
'hdf4' => ['application/x-hdf'],
'hdf5' => ['application/x-hdf'],
'heic' => ['image/heic', 'image/heic-sequence', 'image/heif', 'image/heif-sequence'],
+ 'heics' => ['image/heic-sequence'],
'heif' => ['image/heic', 'image/heic-sequence', 'image/heif', 'image/heif-sequence'],
+ 'heifs' => ['image/heif-sequence'],
+ 'hej2' => ['image/hej2k'],
+ 'held' => ['application/atsc-held+xml'],
'hfe' => ['application/x-hfe-file', 'application/x-hfe-floppy-image'],
'hh' => ['text/x-c', 'text/x-c++hdr'],
+ 'hjson' => ['application/hjson'],
'hlp' => ['application/winhlp', 'zz-application/zz-winassoc-hlp'],
'hp' => ['text/x-c++hdr'],
'hpgl' => ['application/vnd.hp-hpgl'],
@@ -2091,9 +2349,11 @@ final class MimeTypes implements MimeTypesInterface
'hps' => ['application/vnd.hp-hps'],
'hqx' => ['application/stuffit', 'application/mac-binhex40'],
'hs' => ['text/x-haskell'],
+ 'hsj2' => ['image/hsj2'],
+ 'htc' => ['text/x-component'],
'htke' => ['application/vnd.kenameaapp'],
- 'htm' => ['text/html'],
- 'html' => ['text/html'],
+ 'htm' => ['text/html', 'application/xhtml+xml'],
+ 'html' => ['text/html', 'application/xhtml+xml'],
'hvd' => ['application/vnd.yamaha.hv-dic'],
'hvp' => ['application/vnd.yamaha.hv-voice'],
'hvs' => ['application/vnd.yamaha.hv-script'],
@@ -2102,7 +2362,7 @@ final class MimeTypes implements MimeTypesInterface
'hxx' => ['text/x-c++hdr'],
'i2g' => ['application/vnd.intergeo'],
'ica' => ['application/x-ica'],
- 'icb' => ['image/x-icb', 'image/x-tga'],
+ 'icb' => ['application/tga', 'application/x-targa', 'application/x-tga', 'image/targa', 'image/tga', 'image/x-icb', 'image/x-targa', 'image/x-tga'],
'icc' => ['application/vnd.iccprofile'],
'ice' => ['x-conference/x-cooltalk'],
'icm' => ['application/vnd.iccprofile'],
@@ -2128,6 +2388,7 @@ final class MimeTypes implements MimeTypesInterface
'ims' => ['application/vnd.ms-ims'],
'imy' => ['audio/imelody', 'audio/x-imelody', 'text/x-imelody'],
'in' => ['text/plain'],
+ 'ini' => ['text/plain'],
'ink' => ['application/inkml+xml'],
'inkml' => ['application/inkml+xml'],
'ins' => ['application/x-tex', 'text/x-tex'],
@@ -2135,26 +2396,32 @@ final class MimeTypes implements MimeTypesInterface
'iota' => ['application/vnd.astraea-software.iota'],
'ipfix' => ['application/ipfix'],
'ipk' => ['application/vnd.shana.informed.package'],
+ 'ips' => ['application/x-ips-patch'],
'iptables' => ['text/x-iptables'],
'ipynb' => ['application/x-ipynb+json'],
'irm' => ['application/vnd.ibm.rights-management'],
'irp' => ['application/vnd.irepository.package+xml'],
- 'iso' => ['application/x-cd-image', 'application/x-gamecube-iso-image', 'application/x-gamecube-rom', 'application/x-iso9660-image', 'application/x-saturn-rom', 'application/x-sega-cd-rom', 'application/x-wbfs', 'application/x-wia', 'application/x-wii-iso-image', 'application/x-wii-rom'],
+ 'iso' => ['application/x-cd-image', 'application/x-dreamcast-rom', 'application/x-gamecube-iso-image', 'application/x-gamecube-rom', 'application/x-iso9660-image', 'application/x-saturn-rom', 'application/x-sega-cd-rom', 'application/x-sega-pico-rom', 'application/x-wbfs', 'application/x-wia', 'application/x-wii-iso-image', 'application/x-wii-rom'],
'iso9660' => ['application/x-cd-image', 'application/x-iso9660-image'],
'it' => ['audio/x-it'],
'it87' => ['application/x-it87'],
'itp' => ['application/vnd.shana.informed.formtemplate'],
+ 'its' => ['application/its+xml'],
'ivp' => ['application/vnd.immervision-ivp'],
'ivu' => ['application/vnd.immervision-ivu'],
'j2c' => ['image/x-jp2-codestream'],
'j2k' => ['image/x-jp2-codestream'],
'jad' => ['text/vnd.sun.j2me.app-descriptor'],
+ 'jade' => ['text/jade'],
'jam' => ['application/vnd.jam'],
'jar' => ['application/x-java-archive', 'application/java-archive', 'application/x-jar'],
+ 'jardiff' => ['application/x-java-archive-diff'],
'java' => ['text/x-java', 'text/x-java-source'],
'jceks' => ['application/x-java-jce-keystore'],
+ 'jhc' => ['image/jphc'],
'jisp' => ['application/vnd.jisp'],
'jks' => ['application/x-java-keystore'],
+ 'jls' => ['image/jls'],
'jlt' => ['application/vnd.hp-jlyt'],
'jng' => ['image/x-jng'],
'jnlp' => ['application/x-java-jnlp-file'],
@@ -2168,27 +2435,41 @@ final class MimeTypes implements MimeTypesInterface
'jpg2' => ['image/jp2', 'image/jpeg2000', 'image/jpeg2000-image', 'image/x-jpeg2000-image'],
'jpgm' => ['image/jpm', 'video/jpm'],
'jpgv' => ['video/jpeg'],
+ 'jph' => ['image/jph'],
'jpm' => ['image/jpm', 'video/jpm'],
'jpr' => ['application/x-jbuilder-project'],
'jpx' => ['application/x-jbuilder-project', 'image/jpx'],
'jrd' => ['application/jrd+json'],
'js' => ['text/javascript', 'application/javascript', 'application/x-javascript'],
'jsm' => ['application/javascript', 'application/x-javascript', 'text/javascript'],
- 'json' => ['application/json'],
+ 'json' => ['application/json', 'application/schema+json'],
'json-patch' => ['application/json-patch+json'],
+ 'json5' => ['application/json5'],
'jsonld' => ['application/ld+json'],
'jsonml' => ['application/jsonml+json'],
+ 'jsx' => ['text/jsx'],
+ 'jxl' => ['image/jxl'],
+ 'jxr' => ['image/jxr'],
+ 'jxra' => ['image/jxra'],
+ 'jxrs' => ['image/jxrs'],
+ 'jxs' => ['image/jxs'],
+ 'jxsc' => ['image/jxsc'],
+ 'jxsi' => ['image/jxsi'],
+ 'jxss' => ['image/jxss'],
'k25' => ['image/x-kodak-k25'],
'k7' => ['application/x-thomson-cassette'],
'kar' => ['audio/midi', 'audio/x-midi'],
'karbon' => ['application/vnd.kde.karbon', 'application/x-karbon'],
+ 'kdbx' => ['application/x-keepass2'],
'kdc' => ['image/x-kodak-kdc'],
'kdelnk' => ['application/x-desktop', 'application/x-gnome-app-info'],
'kexi' => ['application/x-kexiproject-sqlite', 'application/x-kexiproject-sqlite2', 'application/x-kexiproject-sqlite3', 'application/x-vnd.kde.kexi'],
'kexic' => ['application/x-kexi-connectiondata'],
'kexis' => ['application/x-kexiproject-shortcut'],
- 'key' => ['application/vnd.apple.keynote', 'application/x-iwork-keynote-sffkey'],
+ 'key' => ['application/vnd.apple.keynote', 'application/pgp-keys', 'application/x-iwork-keynote-sffkey'],
+ 'keynote' => ['application/vnd.apple.keynote'],
'kfo' => ['application/vnd.kde.kformula', 'application/x-kformula'],
+ 'kfx' => ['application/vnd.amazon.mobi8-ebook', 'application/x-mobi8-ebook'],
'kia' => ['application/vnd.kidspiration'],
'kil' => ['application/x-killustrator'],
'kino' => ['application/smil', 'application/smil+xml'],
@@ -2202,10 +2483,14 @@ final class MimeTypes implements MimeTypesInterface
'kpt' => ['application/vnd.kde.kpresenter', 'application/x-kpresenter'],
'kpxx' => ['application/vnd.ds-keypoint'],
'kra' => ['application/x-krita'],
+ 'krz' => ['application/x-krita'],
'ks' => ['application/x-java-keystore'],
'ksp' => ['application/vnd.kde.kspread', 'application/x-kspread'],
+ 'ksy' => ['text/x-kaitai-struct'],
+ 'kt' => ['text/x-kotlin'],
'ktr' => ['application/vnd.kahootz'],
'ktx' => ['image/ktx'],
+ 'ktx2' => ['image/ktx2'],
'ktz' => ['application/vnd.kahootz'],
'kud' => ['application/x-kugar'],
'kwd' => ['application/vnd.kde.kword', 'application/x-kword'],
@@ -2218,25 +2503,29 @@ final class MimeTypes implements MimeTypesInterface
'lbm' => ['image/x-iff', 'image/x-ilbm'],
'ldif' => ['text/x-ldif'],
'les' => ['application/vnd.hhe.lesson-player'],
+ 'less' => ['text/less'],
+ 'lgr' => ['application/lgr+xml'],
'lha' => ['application/x-lha', 'application/x-lzh-compressed'],
'lhs' => ['text/x-literate-haskell'],
'lhz' => ['application/x-lhz'],
'link66' => ['application/vnd.route66.link66+xml'],
+ 'lisp' => ['text/x-common-lisp'],
'list' => ['text/plain'],
'list3820' => ['application/vnd.ibm.modcap'],
'listafp' => ['application/vnd.ibm.modcap'],
+ 'litcoffee' => ['text/coffeescript'],
'lnk' => ['application/x-ms-shortcut'],
'lnx' => ['application/x-atari-lynx-rom'],
'loas' => ['audio/usac'],
'log' => ['text/plain', 'text/x-log'],
'lostxml' => ['application/lost+xml'],
- 'lrf' => ['application/octet-stream'],
'lrm' => ['application/vnd.ms-lrm'],
'lrv' => ['video/mp4', 'video/mp4v-es', 'video/x-m4v'],
'lrz' => ['application/x-lrzip'],
'ltf' => ['application/vnd.frogans.ltf'],
'ltx' => ['application/x-tex', 'text/x-tex'],
'lua' => ['text/x-lua'],
+ 'luac' => ['application/x-lua-bytecode'],
'lvp' => ['audio/vnd.lucent.voice'],
'lwo' => ['image/x-lwo'],
'lwob' => ['image/x-lwo'],
@@ -2266,31 +2555,35 @@ final class MimeTypes implements MimeTypesInterface
'm4' => ['application/x-m4'],
'm4a' => ['audio/mp4', 'audio/m4a', 'audio/x-m4a'],
'm4b' => ['audio/x-m4b'],
+ 'm4p' => ['application/mp4'],
'm4r' => ['audio/x-m4r'],
+ 'm4s' => ['video/iso.segment'],
'm4u' => ['video/vnd.mpegurl', 'video/x-mpegurl'],
'm4v' => ['video/mp4', 'video/mp4v-es', 'video/x-m4v'],
'm7' => ['application/x-thomson-cartridge-memo7'],
'ma' => ['application/mathematica'],
'mab' => ['application/x-markaby'],
'mads' => ['application/mads+xml'],
+ 'maei' => ['application/mmt-aei+xml'],
'mag' => ['application/vnd.ecowin.chart'],
'mak' => ['text/x-makefile'],
'maker' => ['application/vnd.framemaker'],
'man' => ['application/x-troff-man', 'text/troff'],
'manifest' => ['text/cache-manifest'],
- 'mar' => ['application/octet-stream'],
+ 'map' => ['application/json'],
'markdown' => ['text/markdown', 'text/x-markdown'],
'mathml' => ['application/mathml+xml'],
'mb' => ['application/mathematica'],
'mbk' => ['application/vnd.mobius.mbk'],
'mbox' => ['application/mbox'],
'mc1' => ['application/vnd.medcalcdata'],
+ 'mc2' => ['text/vnd.senx.warpscript'],
'mcd' => ['application/vnd.mcd'],
'mcurl' => ['text/vnd.curl.mcurl'],
'md' => ['text/markdown', 'text/x-markdown'],
'mdb' => ['application/x-msaccess', 'application/mdb', 'application/msaccess', 'application/vnd.ms-access', 'application/vnd.msaccess', 'application/x-mdb', 'zz-application/zz-winassoc-mdb'],
'mdi' => ['image/vnd.ms-modi'],
- 'mdx' => ['application/x-genesis-32x-rom'],
+ 'mdx' => ['application/x-genesis-32x-rom', 'text/mdx'],
'me' => ['text/troff', 'text/x-troff-me'],
'med' => ['audio/x-mod'],
'mesh' => ['model/mesh'],
@@ -2334,7 +2627,7 @@ final class MimeTypes implements MimeTypesInterface
'mo3' => ['audio/x-mo3'],
'mobi' => ['application/x-mobipocket-ebook'],
'moc' => ['text/x-moc'],
- 'mod' => ['audio/x-mod'],
+ 'mod' => ['application/x-object', 'audio/x-mod'],
'mods' => ['application/mods+xml'],
'mof' => ['text/x-mof'],
'moov' => ['video/quicktime'],
@@ -2351,6 +2644,7 @@ final class MimeTypes implements MimeTypesInterface
'mp4s' => ['application/mp4'],
'mp4v' => ['video/mp4'],
'mpc' => ['application/vnd.mophun.certificate', 'audio/x-musepack'],
+ 'mpd' => ['application/dash+xml'],
'mpe' => ['video/mpeg', 'video/mpeg-system', 'video/x-mpeg', 'video/x-mpeg-system', 'video/x-mpeg2'],
'mpeg' => ['video/mpeg', 'video/mpeg-system', 'video/x-mpeg', 'video/x-mpeg-system', 'video/x-mpeg2'],
'mpg' => ['video/mpeg', 'video/mpeg-system', 'video/x-mpeg', 'video/x-mpeg-system', 'video/x-mpeg2'],
@@ -2375,21 +2669,26 @@ final class MimeTypes implements MimeTypesInterface
'mseed' => ['application/vnd.fdsn.mseed'],
'mseq' => ['application/vnd.mseq'],
'msf' => ['application/vnd.epson.msf'],
+ 'msg' => ['application/vnd.ms-outlook'],
'msh' => ['model/mesh'],
'msi' => ['application/x-msdownload', 'application/x-msi'],
'msl' => ['application/vnd.mobius.msl'],
'msod' => ['image/x-msod'],
'msty' => ['application/vnd.muvee.style'],
'msx' => ['application/x-msx-rom'],
+ 'mtl' => ['model/mtl'],
'mtm' => ['audio/x-mod'],
'mts' => ['model/vnd.mts', 'video/mp2t'],
'mup' => ['text/x-mup'],
'mus' => ['application/vnd.musician'],
+ 'musd' => ['application/mmt-usd+xml'],
'musicxml' => ['application/vnd.recordare.musicxml+xml'],
'mvb' => ['application/x-msmediaview'],
+ 'mvt' => ['application/vnd.mapbox-vector-tile'],
'mwf' => ['application/vnd.mfer'],
'mxf' => ['application/mxf'],
'mxl' => ['application/vnd.recordare.musicxml'],
+ 'mxmf' => ['audio/mobile-xmf'],
'mxml' => ['application/xv+xml'],
'mxs' => ['application/vnd.triscape.mxs'],
'mxu' => ['video/vnd.mpegurl', 'video/x-mpegurl'],
@@ -2416,17 +2715,22 @@ final class MimeTypes implements MimeTypesInterface
'nnw' => ['application/vnd.noblenet-web'],
'not' => ['text/x-mup'],
'npx' => ['image/vnd.net-fpx'],
+ 'nq' => ['application/n-quads'],
+ 'nrw' => ['image/x-nikon-nrw'],
'nsc' => ['application/x-conference', 'application/x-netshow-channel'],
'nsf' => ['application/vnd.lotus-notes'],
'nsv' => ['video/x-nsv'],
+ 'nt' => ['application/n-triples'],
'ntf' => ['application/vnd.nitf'],
+ 'numbers' => ['application/vnd.apple.numbers', 'application/x-iwork-numbers-sffnumbers'],
'nzb' => ['application/x-nzb'],
'o' => ['application/x-object'],
'oa2' => ['application/vnd.fujitsu.oasys2'],
'oa3' => ['application/vnd.fujitsu.oasys3'],
'oas' => ['application/vnd.fujitsu.oasys'],
'obd' => ['application/x-msbinder'],
- 'obj' => ['application/x-tgif'],
+ 'obgx' => ['application/vnd.openblox.game+xml'],
+ 'obj' => ['application/x-tgif', 'model/obj'],
'ocl' => ['text/x-ocl'],
'oda' => ['application/oda'],
'odb' => ['application/vnd.oasis.opendocument.database', 'application/vnd.sun.xml.base'],
@@ -2440,6 +2744,7 @@ final class MimeTypes implements MimeTypesInterface
'ods' => ['application/vnd.oasis.opendocument.spreadsheet'],
'odt' => ['application/vnd.oasis.opendocument.text'],
'oga' => ['audio/ogg', 'audio/vorbis', 'audio/x-flac+ogg', 'audio/x-ogg', 'audio/x-oggflac', 'audio/x-speex+ogg', 'audio/x-vorbis', 'audio/x-vorbis+ogg'],
+ 'ogex' => ['model/vnd.opengex'],
'ogg' => ['audio/ogg', 'audio/vorbis', 'audio/x-flac+ogg', 'audio/x-ogg', 'audio/x-oggflac', 'audio/x-speex+ogg', 'audio/x-vorbis', 'audio/x-vorbis+ogg', 'video/ogg', 'video/x-ogg', 'video/x-theora', 'video/x-theora+ogg'],
'ogm' => ['video/x-ogm', 'video/x-ogm+ogg'],
'ogv' => ['video/ogg', 'video/x-ogg'],
@@ -2458,9 +2763,10 @@ final class MimeTypes implements MimeTypesInterface
'opus' => ['audio/ogg', 'audio/x-ogg', 'audio/x-opus+ogg'],
'ora' => ['image/openraster'],
'orf' => ['image/x-olympus-orf'],
- 'org' => ['application/vnd.lotus-organizer'],
+ 'org' => ['application/vnd.lotus-organizer', 'text/org', 'text/x-org'],
'osf' => ['application/vnd.yamaha.openscoreformat'],
'osfpvg' => ['application/vnd.yamaha.openscoreformat.osfpvg+xml'],
+ 'osm' => ['application/vnd.openstreetmap.data+xml'],
'otc' => ['application/vnd.oasis.opendocument.chart-template'],
'otf' => ['application/vnd.oasis.opendocument.formula-template', 'application/x-font-otf', 'font/otf'],
'otg' => ['application/vnd.oasis.opendocument.graphics-template'],
@@ -2469,9 +2775,11 @@ final class MimeTypes implements MimeTypesInterface
'otp' => ['application/vnd.oasis.opendocument.presentation-template'],
'ots' => ['application/vnd.oasis.opendocument.spreadsheet-template'],
'ott' => ['application/vnd.oasis.opendocument.text-template'],
+ 'ova' => ['application/ovf', 'application/x-virtualbox-ova'],
+ 'ovf' => ['application/x-virtualbox-ovf'],
'owl' => ['application/rdf+xml', 'text/rdf'],
'owx' => ['application/owl+xml'],
- 'oxps' => ['application/oxps', 'application/vnd.ms-xpsdocument', 'application/xps'],
+ 'oxps' => ['application/oxps'],
'oxt' => ['application/vnd.openofficeorg.extension'],
'p' => ['text/x-pascal'],
'p10' => ['application/pkcs10'],
@@ -2484,7 +2792,9 @@ final class MimeTypes implements MimeTypesInterface
'p7s' => ['application/pkcs7-signature'],
'p8' => ['application/pkcs8'],
'p8e' => ['application/pkcs8-encrypted'],
+ 'pac' => ['application/x-ns-proxy-autoconfig'],
'pack' => ['application/x-java-pack200'],
+ 'pages' => ['application/vnd.apple.pages', 'application/x-iwork-pages-sffpages'],
'pak' => ['application/x-pak'],
'par2' => ['application/x-par2'],
'part' => ['application/x-partial-download'],
@@ -2506,8 +2816,9 @@ final class MimeTypes implements MimeTypesInterface
'pct' => ['image/x-pict'],
'pcurl' => ['application/vnd.curl.pcurl'],
'pcx' => ['image/vnd.zbrush.pcx', 'image/x-pcx'],
- 'pdb' => ['application/vnd.palm', 'application/x-aportisdoc', 'application/x-palm-database'],
+ 'pdb' => ['application/vnd.palm', 'application/x-aportisdoc', 'application/x-palm-database', 'application/x-pilot'],
'pdc' => ['application/x-aportisdoc'],
+ 'pde' => ['text/x-processing'],
'pdf' => ['application/pdf', 'application/acrobat', 'application/nappdf', 'application/x-pdf', 'image/pdf'],
'pdf.bz2' => ['application/x-bzpdf'],
'pdf.gz' => ['application/x-gzpdf'],
@@ -2524,7 +2835,7 @@ final class MimeTypes implements MimeTypesInterface
'pgm' => ['image/x-portable-graymap'],
'pgn' => ['application/vnd.chess-pgn', 'application/x-chess-pgn'],
'pgp' => ['application/pgp', 'application/pgp-encrypted', 'application/pgp-keys', 'application/pgp-signature'],
- 'php' => ['application/x-php'],
+ 'php' => ['application/x-php', 'application/x-httpd-php'],
'php3' => ['application/x-php'],
'php4' => ['application/x-php'],
'php5' => ['application/x-php'],
@@ -2534,9 +2845,10 @@ final class MimeTypes implements MimeTypesInterface
'pict1' => ['image/x-pict'],
'pict2' => ['image/x-pict'],
'pk' => ['application/x-tex-pk'],
- 'pkg' => ['application/octet-stream', 'application/x-xar'],
+ 'pkg' => ['application/x-xar'],
'pki' => ['application/pkixcmp'],
'pkipath' => ['application/pkix-pkipath'],
+ 'pkpass' => ['application/vnd.apple.pkpass'],
'pkr' => ['application/pgp-keys'],
'pl' => ['application/x-perl', 'text/x-perl'],
'pla' => ['audio/x-iriver-pla'],
@@ -2570,9 +2882,10 @@ final class MimeTypes implements MimeTypesInterface
'pptx' => ['application/vnd.openxmlformats-officedocument.presentationml.presentation'],
'ppz' => ['application/mspowerpoint', 'application/powerpoint', 'application/vnd.ms-powerpoint', 'application/x-mspowerpoint'],
'pqa' => ['application/vnd.palm', 'application/x-palm-database'],
- 'prc' => ['application/vnd.palm', 'application/x-mobipocket-ebook', 'application/x-palm-database'],
+ 'prc' => ['application/vnd.palm', 'application/x-mobipocket-ebook', 'application/x-palm-database', 'application/x-pilot'],
'pre' => ['application/vnd.lotus-freelance'],
'prf' => ['application/pics-rules'],
+ 'provx' => ['application/provenance+xml'],
'ps' => ['application/postscript'],
'ps.bz2' => ['application/x-bzpostscript'],
'ps.gz' => ['application/x-gzpostscript'],
@@ -2584,6 +2897,7 @@ final class MimeTypes implements MimeTypesInterface
'psid' => ['audio/prs.sid'],
'pskcxml' => ['application/pskc+xml'],
'psw' => ['application/x-pocket-word'],
+ 'pti' => ['image/prs.pti'],
'ptid' => ['application/vnd.pvi.ptid1'],
'pub' => ['application/vnd.ms-publisher', 'application/x-mspublisher'],
'pvb' => ['application/vnd.3gpp.pic-bw-var'],
@@ -2594,12 +2908,18 @@ final class MimeTypes implements MimeTypesInterface
'py3x' => ['text/x-python3'],
'pya' => ['audio/vnd.ms-playready.media.pya'],
'pyc' => ['application/x-python-bytecode'],
+ 'pyi' => ['text/x-python3'],
'pyo' => ['application/x-python-bytecode'],
+ 'pys' => ['application/x-pyspread-bz-spreadsheet'],
+ 'pysu' => ['application/x-pyspread-spreadsheet'],
'pyv' => ['video/vnd.ms-playready.media.pyv'],
'pyx' => ['text/x-python'],
'qam' => ['application/vnd.epson.quickanime'],
'qbo' => ['application/vnd.intu.qbo'],
+ 'qcow' => ['application/x-qemu-disk'],
+ 'qcow2' => ['application/x-qemu-disk'],
'qd' => ['application/x-fd-file', 'application/x-raw-floppy-disk-image'],
+ 'qed' => ['application/x-qed-disk'],
'qfx' => ['application/vnd.intu.qfx'],
'qif' => ['application/x-qw', 'image/x-quicktime'],
'qml' => ['text/x-qml'],
@@ -2619,10 +2939,11 @@ final class MimeTypes implements MimeTypesInterface
'qxd' => ['application/vnd.quark.quarkxpress'],
'qxl' => ['application/vnd.quark.quarkxpress'],
'qxt' => ['application/vnd.quark.quarkxpress'],
- 'ra' => ['audio/vnd.m-realaudio', 'audio/vnd.rn-realaudio', 'audio/x-pn-realaudio'],
+ 'ra' => ['audio/vnd.m-realaudio', 'audio/vnd.rn-realaudio', 'audio/x-pn-realaudio', 'audio/x-realaudio'],
'raf' => ['image/x-fuji-raf'],
'ram' => ['application/ram', 'audio/x-pn-realaudio'],
'raml' => ['application/raml+yaml'],
+ 'rapd' => ['application/route-apd+xml'],
'rar' => ['application/x-rar-compressed', 'application/vnd.rar', 'application/x-rar'],
'ras' => ['image/x-cmu-raster'],
'raw' => ['image/x-panasonic-raw', 'image/x-panasonic-rw'],
@@ -2636,6 +2957,7 @@ final class MimeTypes implements MimeTypesInterface
'rdz' => ['application/vnd.data-vision.rdz'],
'reg' => ['text/x-ms-regedit'],
'rej' => ['application/x-reject', 'text/x-reject'],
+ 'relo' => ['application/p2p-overlay+xml'],
'rep' => ['application/vnd.businessobjects'],
'res' => ['application/x-dtbresource+xml'],
'rgb' => ['image/x-rgb'],
@@ -2658,6 +2980,7 @@ final class MimeTypes implements MimeTypesInterface
'rng' => ['application/xml', 'text/xml'],
'roa' => ['application/rpki-roa'],
'roff' => ['application/x-troff', 'text/troff', 'text/x-troff'],
+ 'ros' => ['text/x-common-lisp'],
'rp' => ['image/vnd.rn-realpix'],
'rp9' => ['application/vnd.cloanto.rp9'],
'rpm' => ['application/x-redhat-package-manager', 'application/x-rpm'],
@@ -2665,24 +2988,30 @@ final class MimeTypes implements MimeTypesInterface
'rpst' => ['application/vnd.nokia.radio-preset'],
'rq' => ['application/sparql-query'],
'rs' => ['application/rls-services+xml', 'text/rust'],
+ 'rsat' => ['application/atsc-rsat+xml'],
'rsd' => ['application/rsd+xml'],
+ 'rsheet' => ['application/urc-ressheet+xml'],
'rss' => ['application/rss+xml', 'text/rss'],
+ 'rst' => ['text/x-rst'],
'rt' => ['text/vnd.rn-realtext'],
'rtf' => ['application/rtf', 'text/rtf'],
'rtx' => ['text/richtext'],
+ 'run' => ['application/x-makeself'],
+ 'rusd' => ['application/route-usd+xml'],
'rv' => ['video/vnd.rn-realvideo', 'video/x-real-video'],
'rvx' => ['video/vnd.rn-realvideo', 'video/x-real-video'],
'rw2' => ['image/x-panasonic-raw2', 'image/x-panasonic-rw2'],
's' => ['text/x-asm'],
's3m' => ['audio/s3m', 'audio/x-s3m'],
'saf' => ['application/vnd.yamaha.smaf-audio'],
+ 'sage' => ['text/x-sagemath'],
'sam' => ['application/x-amipro'],
'sami' => ['application/x-sami'],
'sap' => ['application/x-sap-file', 'application/x-thomson-sap-image'],
'sass' => ['text/x-sass'],
'sav' => ['application/x-spss-sav', 'application/x-spss-savefile'],
'sbml' => ['application/sbml+xml'],
- 'sc' => ['application/vnd.ibm.secure-container'],
+ 'sc' => ['application/vnd.ibm.secure-container', 'text/x-scala'],
'scala' => ['text/x-scala'],
'scd' => ['application/x-msschedule'],
'scm' => ['application/vnd.lotus-screencam', 'text/x-scheme'],
@@ -2699,11 +3028,14 @@ final class MimeTypes implements MimeTypesInterface
'sdp' => ['application/sdp', 'application/vnd.sdp', 'application/vnd.stardivision.impress', 'application/x-sdp'],
'sds' => ['application/vnd.stardivision.chart'],
'sdw' => ['application/vnd.stardivision.writer', 'application/vnd.stardivision.writer-global'],
+ 'sea' => ['application/x-sea'],
'see' => ['application/vnd.seemail'],
'seed' => ['application/vnd.fdsn.seed'],
'sema' => ['application/vnd.sema'],
'semd' => ['application/vnd.semd'],
'semf' => ['application/vnd.semf'],
+ 'senmlx' => ['application/senml+xml'],
+ 'sensmlx' => ['application/sensml+xml'],
'ser' => ['application/java-serialized-object'],
'service' => ['text/x-dbus-service', 'text/x-systemd-unit'],
'setpay' => ['application/set-payment-initiation'],
@@ -2714,6 +3046,7 @@ final class MimeTypes implements MimeTypesInterface
'sfv' => ['text/x-sfv'],
'sg' => ['application/x-sg1000-rom'],
'sgb' => ['application/x-gameboy-rom'],
+ 'sgd' => ['application/x-genesis-rom'],
'sgf' => ['application/x-go-sgf'],
'sgi' => ['image/sgi', 'image/x-sgi'],
'sgl' => ['application/vnd.stardivision.writer', 'application/vnd.stardivision.writer-global'],
@@ -2722,10 +3055,13 @@ final class MimeTypes implements MimeTypesInterface
'sh' => ['application/x-sh', 'application/x-shellscript', 'text/x-sh'],
'shape' => ['application/x-dia-shape'],
'shar' => ['application/x-shar'],
+ 'shex' => ['text/shex'],
'shf' => ['application/shf+xml'],
'shn' => ['application/x-shorten', 'audio/x-shorten'],
+ 'shtml' => ['text/html'],
'siag' => ['application/x-siag'],
'sid' => ['audio/prs.sid', 'image/x-mrsid-image'],
+ 'sieve' => ['application/sieve'],
'sig' => ['application/pgp-signature'],
'sik' => ['application/x-trash'],
'sil' => ['audio/silk'],
@@ -2745,7 +3081,10 @@ final class MimeTypes implements MimeTypesInterface
'sldm' => ['application/vnd.ms-powerpoint.slide.macroenabled.12'],
'sldx' => ['application/vnd.openxmlformats-officedocument.presentationml.slide'],
'slice' => ['text/x-systemd-unit'],
+ 'slim' => ['text/slim'],
'slk' => ['text/spreadsheet'],
+ 'slm' => ['text/slim'],
+ 'sls' => ['application/route-s-tsid+xml'],
'slt' => ['application/vnd.epson.salt'],
'sm' => ['application/vnd.stepmania.stepchart'],
'smaf' => ['application/vnd.smaf', 'application/x-smaf'],
@@ -2754,6 +3093,7 @@ final class MimeTypes implements MimeTypesInterface
'smf' => ['application/vnd.stardivision.math'],
'smi' => ['application/smil', 'application/smil+xml', 'application/x-sami'],
'smil' => ['application/smil', 'application/smil+xml'],
+ 'smk' => ['video/vnd.radgamettools.smacker'],
'sml' => ['application/smil', 'application/smil+xml'],
'sms' => ['application/x-sms-rom'],
'smv' => ['video/x-smv'],
@@ -2761,10 +3101,11 @@ final class MimeTypes implements MimeTypesInterface
'snap' => ['application/vnd.snap'],
'snd' => ['audio/basic'],
'snf' => ['application/x-font-snf'],
- 'so' => ['application/octet-stream', 'application/x-sharedlib'],
+ 'so' => ['application/x-sharedlib'],
'socket' => ['text/x-systemd-unit'],
'spc' => ['application/x-pkcs7-certificates'],
'spd' => ['application/x-font-speedo'],
+ 'spdx' => ['text/spdx'],
'spec' => ['text/x-rpm-spec'],
'spf' => ['application/vnd.yamaha.smaf-phrase'],
'spl' => ['application/futuresplash', 'application/vnd.adobe.flash.movie', 'application/x-futuresplash', 'application/x-shockwave-flash'],
@@ -2772,7 +3113,7 @@ final class MimeTypes implements MimeTypesInterface
'spot' => ['text/vnd.in3d.spot'],
'spp' => ['application/scvp-vp-response'],
'spq' => ['application/scvp-vp-request'],
- 'spx' => ['audio/ogg', 'audio/x-speex'],
+ 'spx' => ['application/x-apple-systemprofiler+xml', 'audio/ogg', 'audio/x-speex', 'audio/x-speex+ogg'],
'sql' => ['application/sql', 'application/x-sql', 'text/x-sql'],
'sqlite2' => ['application/x-sqlite2'],
'sqlite3' => ['application/vnd.sqlite3', 'application/x-sqlite3'],
@@ -2798,9 +3139,13 @@ final class MimeTypes implements MimeTypesInterface
'stk' => ['application/hyperstudio'],
'stl' => ['application/vnd.ms-pki.stl', 'model/stl', 'model/x.stl-ascii', 'model/x.stl-binary'],
'stm' => ['audio/x-stm'],
+ 'stpxz' => ['model/step-xml+zip'],
+ 'stpz' => ['model/step+zip'],
'str' => ['application/vnd.pg.format'],
'stw' => ['application/vnd.sun.xml.writer.template'],
'sty' => ['application/x-tex', 'text/x-tex'],
+ 'styl' => ['text/stylus'],
+ 'stylus' => ['text/stylus'],
'sub' => ['image/vnd.dvb.subtitle', 'text/vnd.dvb.subtitle', 'text/x-microdvd', 'text/x-mpsub', 'text/x-subviewer'],
'sun' => ['image/x-sun-raster'],
'sus' => ['application/vnd.sus-calendar'],
@@ -2817,6 +3162,7 @@ final class MimeTypes implements MimeTypesInterface
'swap' => ['text/x-systemd-unit'],
'swf' => ['application/futuresplash', 'application/vnd.adobe.flash.movie', 'application/x-shockwave-flash'],
'swi' => ['application/vnd.aristanetworks.swi'],
+ 'swidtag' => ['application/swid+xml'],
'swm' => ['application/x-ms-wim'],
'sxc' => ['application/vnd.sun.xml.calc'],
'sxd' => ['application/vnd.sun.xml.draw'],
@@ -2828,8 +3174,10 @@ final class MimeTypes implements MimeTypesInterface
't' => ['application/x-perl', 'application/x-troff', 'text/troff', 'text/x-perl', 'text/x-troff'],
't2t' => ['text/x-txt2tags'],
't3' => ['application/x-t3vm-image'],
+ 't38' => ['image/t38'],
'taglet' => ['application/vnd.mynfc'],
'tao' => ['application/vnd.tao.intent-module-archive'],
+ 'tap' => ['image/vnd.tencent.tap'],
'tar' => ['application/x-tar', 'application/x-gtar'],
'tar.Z' => ['application/x-tarz'],
'tar.bz' => ['application/x-bzip-compressed-tar'],
@@ -2841,13 +3189,15 @@ final class MimeTypes implements MimeTypesInterface
'tar.lzma' => ['application/x-lzma-compressed-tar'],
'tar.lzo' => ['application/x-tzo'],
'tar.xz' => ['application/x-xz-compressed-tar'],
+ 'tar.zst' => ['application/x-zstd-compressed-tar'],
'target' => ['text/x-systemd-unit'],
'taz' => ['application/x-tarz'],
'tb2' => ['application/x-bzip-compressed-tar'],
'tbz' => ['application/x-bzip-compressed-tar'],
'tbz2' => ['application/x-bzip-compressed-tar'],
'tcap' => ['application/vnd.3gpp2.tcap'],
- 'tcl' => ['application/x-tcl', 'text/x-tcl'],
+ 'tcl' => ['application/x-tcl', 'text/tcl', 'text/x-tcl'],
+ 'td' => ['application/urc-targetdesc+xml'],
'teacher' => ['application/vnd.smart.teacher'],
'tei' => ['application/tei+xml'],
'teicorpus' => ['application/tei+xml'],
@@ -2857,7 +3207,8 @@ final class MimeTypes implements MimeTypesInterface
'text' => ['text/plain'],
'tfi' => ['application/thraud+xml'],
'tfm' => ['application/x-tex-tfm'],
- 'tga' => ['image/x-icb', 'image/x-tga'],
+ 'tfx' => ['image/tiff-fx'],
+ 'tga' => ['application/tga', 'application/x-targa', 'application/x-tga', 'image/targa', 'image/tga', 'image/x-icb', 'image/x-targa', 'image/x-tga'],
'tgz' => ['application/x-compressed-tar'],
'theme' => ['application/x-theme'],
'themepack' => ['application/x-windows-themepack'],
@@ -2865,15 +3216,16 @@ final class MimeTypes implements MimeTypesInterface
'tif' => ['image/tiff'],
'tiff' => ['image/tiff'],
'timer' => ['text/x-systemd-unit'],
- 'tk' => ['text/x-tcl'],
+ 'tk' => ['application/x-tcl', 'text/tcl', 'text/x-tcl'],
'tlrz' => ['application/x-lrzip-compressed-tar'],
'tlz' => ['application/x-lzma-compressed-tar'],
'tmo' => ['application/vnd.tmobile-livetv'],
'tnef' => ['application/ms-tnef', 'application/vnd.ms-tnef'],
'tnf' => ['application/ms-tnef', 'application/vnd.ms-tnef'],
'toc' => ['application/x-cdrdao-toc'],
+ 'toml' => ['application/toml'],
'torrent' => ['application/x-bittorrent'],
- 'tpic' => ['image/x-icb', 'image/x-tga'],
+ 'tpic' => ['application/tga', 'application/x-targa', 'application/x-tga', 'image/targa', 'image/tga', 'image/x-icb', 'image/x-targa', 'image/x-tga'],
'tpl' => ['application/vnd.groove-tool-template'],
'tpt' => ['application/vnd.trid.tpt'],
'tr' => ['application/x-troff', 'text/troff', 'text/x-troff'],
@@ -2887,6 +3239,7 @@ final class MimeTypes implements MimeTypesInterface
'ttc' => ['font/collection'],
'ttf' => ['application/x-font-truetype', 'application/x-font-ttf', 'font/ttf'],
'ttl' => ['text/turtle'],
+ 'ttml' => ['application/ttml+xml'],
'ttx' => ['application/x-font-ttx'],
'twd' => ['application/vnd.simtech-mindmapper'],
'twds' => ['application/vnd.simtech-mindmapper'],
@@ -2896,7 +3249,13 @@ final class MimeTypes implements MimeTypesInterface
'txt' => ['text/plain'],
'txz' => ['application/x-xz-compressed-tar'],
'tzo' => ['application/x-tzo'],
+ 'tzst' => ['application/x-zstd-compressed-tar'],
'u32' => ['application/x-authorware-bin'],
+ 'u8dsn' => ['message/global-delivery-status'],
+ 'u8hdr' => ['message/global-headers'],
+ 'u8mdn' => ['message/global-disposition-notification'],
+ 'u8msg' => ['message/global'],
+ 'ubj' => ['application/ubjson'],
'udeb' => ['application/vnd.debian.binary-package', 'application/x-deb', 'application/x-debian-package'],
'ufd' => ['application/vnd.ufdl'],
'ufdl' => ['application/vnd.ufdl'],
@@ -2915,6 +3274,7 @@ final class MimeTypes implements MimeTypesInterface
'uris' => ['text/uri-list'],
'url' => ['application/x-mswinurl'],
'urls' => ['text/uri-list'],
+ 'usdz' => ['model/vnd.usdz+zip'],
'ustar' => ['application/x-ustar'],
'utz' => ['application/vnd.uiq.theme'],
'uu' => ['text/x-uuencode'],
@@ -2952,6 +3312,9 @@ final class MimeTypes implements MimeTypesInterface
'vala' => ['text/x-vala'],
'vapi' => ['text/x-vala'],
'vb' => ['application/x-virtual-boy-rom'],
+ 'vbox' => ['application/x-virtualbox-vbox'],
+ 'vbox-extpack' => ['application/x-virtualbox-vbox-extpack'],
+ 'vbs' => ['text/vbs', 'text/vbscript'],
'vcard' => ['text/directory', 'text/vcard', 'text/x-vcard'],
'vcd' => ['application/x-cdlink'],
'vcf' => ['text/x-vcard', 'text/directory', 'text/vcard'],
@@ -2959,17 +3322,22 @@ final class MimeTypes implements MimeTypesInterface
'vcs' => ['application/ics', 'text/calendar', 'text/x-vcalendar'],
'vct' => ['text/directory', 'text/vcard', 'text/x-vcard'],
'vcx' => ['application/vnd.vcx'],
- 'vda' => ['image/x-icb', 'image/x-tga'],
- 'vhd' => ['text/x-vhdl'],
+ 'vda' => ['application/tga', 'application/x-targa', 'application/x-tga', 'image/targa', 'image/tga', 'image/x-icb', 'image/x-targa', 'image/x-tga'],
+ 'vdi' => ['application/x-vdi-disk', 'application/x-virtualbox-vdi'],
+ 'vds' => ['model/vnd.sap.vds'],
+ 'vhd' => ['application/x-vhd-disk', 'application/x-virtualbox-vhd', 'text/x-vhdl'],
'vhdl' => ['text/x-vhdl'],
+ 'vhdx' => ['application/x-vhdx-disk', 'application/x-virtualbox-vhdx'],
'vis' => ['application/vnd.visionary'],
'viv' => ['video/vivo', 'video/vnd.vivo'],
'vivo' => ['video/vivo', 'video/vnd.vivo'],
'vlc' => ['application/m3u', 'audio/m3u', 'audio/mpegurl', 'audio/x-m3u', 'audio/x-mp3-playlist', 'audio/x-mpegurl'],
+ 'vmdk' => ['application/x-virtualbox-vmdk', 'application/x-vmdk-disk'],
'vob' => ['video/mpeg', 'video/mpeg-system', 'video/x-mpeg', 'video/x-mpeg-system', 'video/x-mpeg2', 'video/x-ms-vob'],
'voc' => ['audio/x-voc'],
'vor' => ['application/vnd.stardivision.writer', 'application/vnd.stardivision.writer-global'],
'vox' => ['application/x-authorware-bin'],
+ 'vpc' => ['application/x-vhd-disk', 'application/x-virtualbox-vhd'],
'vrm' => ['model/vrml'],
'vrml' => ['model/vrml'],
'vsd' => ['application/vnd.visio'],
@@ -2979,16 +3347,20 @@ final class MimeTypes implements MimeTypesInterface
'vss' => ['application/vnd.visio'],
'vssm' => ['application/vnd.ms-visio.stencil.macroenabled.main+xml'],
'vssx' => ['application/vnd.ms-visio.stencil.main+xml'],
- 'vst' => ['application/vnd.visio', 'image/x-icb', 'image/x-tga'],
+ 'vst' => ['application/tga', 'application/vnd.visio', 'application/x-targa', 'application/x-tga', 'image/targa', 'image/tga', 'image/x-icb', 'image/x-targa', 'image/x-tga'],
'vstm' => ['application/vnd.ms-visio.template.macroenabled.main+xml'],
'vstx' => ['application/vnd.ms-visio.template.main+xml'],
'vsw' => ['application/vnd.visio'],
+ 'vtf' => ['image/vnd.valve.source.texture'],
'vtt' => ['text/vtt'],
'vtu' => ['model/vnd.vtu'],
'vxml' => ['application/voicexml+xml'],
'w3d' => ['application/x-director'],
'wad' => ['application/x-doom', 'application/x-doom-wad', 'application/x-wii-wad'],
- 'wav' => ['audio/wav', 'audio/vnd.wave', 'audio/x-wav'],
+ 'wadl' => ['application/vnd.sun.wadl+xml'],
+ 'war' => ['application/java-archive'],
+ 'wasm' => ['application/wasm'],
+ 'wav' => ['audio/wav', 'audio/vnd.wave', 'audio/wave', 'audio/x-wav'],
'wax' => ['application/x-ms-asx', 'audio/x-ms-asx', 'audio/x-ms-wax', 'video/x-ms-wax', 'video/x-ms-wmx', 'video/x-ms-wvx'],
'wb1' => ['application/x-quattropro'],
'wb2' => ['application/x-quattropro'],
@@ -3000,7 +3372,9 @@ final class MimeTypes implements MimeTypesInterface
'wdb' => ['application/vnd.ms-works'],
'wdp' => ['image/vnd.ms-photo'],
'weba' => ['audio/webm'],
+ 'webapp' => ['application/x-web-app-manifest+json'],
'webm' => ['video/webm'],
+ 'webmanifest' => ['application/manifest+json'],
'webp' => ['image/webp'],
'wg' => ['application/vnd.pmi.widget'],
'wgt' => ['application/widget'],
@@ -3022,7 +3396,7 @@ final class MimeTypes implements MimeTypesInterface
'wmx' => ['application/x-ms-asx', 'audio/x-ms-asx', 'video/x-ms-wax', 'video/x-ms-wmx', 'video/x-ms-wvx'],
'wmz' => ['application/x-ms-wmz', 'application/x-msmetafile'],
'woff' => ['application/font-woff', 'application/x-font-woff', 'font/woff'],
- 'woff2' => ['font/woff', 'font/woff2'],
+ 'woff2' => ['font/woff2'],
'wp' => ['application/vnd.wordperfect', 'application/wordperfect', 'application/x-wordperfect'],
'wp4' => ['application/vnd.wordperfect', 'application/wordperfect', 'application/x-wordperfect'],
'wp5' => ['application/vnd.wordperfect', 'application/wordperfect', 'application/x-wordperfect'],
@@ -3036,7 +3410,7 @@ final class MimeTypes implements MimeTypesInterface
'wri' => ['application/x-mswrite'],
'wrl' => ['model/vrml'],
'ws' => ['application/x-wonderswan-rom'],
- 'wsc' => ['application/x-wonderswan-color-rom'],
+ 'wsc' => ['application/x-wonderswan-color-rom', 'message/vnd.wfa.wsc'],
'wsdl' => ['application/wsdl+xml'],
'wsgi' => ['text/x-python'],
'wspolicy' => ['application/wspolicy+xml'],
@@ -3048,32 +3422,38 @@ final class MimeTypes implements MimeTypesInterface
'wwf' => ['application/wwf', 'application/x-wwf'],
'x32' => ['application/x-authorware-bin'],
'x3d' => ['model/x3d+xml'],
- 'x3db' => ['model/x3d+binary'],
+ 'x3db' => ['model/x3d+binary', 'model/x3d+fastinfoset'],
'x3dbz' => ['model/x3d+binary'],
- 'x3dv' => ['model/x3d+vrml'],
+ 'x3dv' => ['model/x3d+vrml', 'model/x3d-vrml'],
'x3dvz' => ['model/x3d+vrml'],
'x3dz' => ['model/x3d+xml'],
'x3f' => ['image/x-sigma-x3f'],
+ 'x_b' => ['model/vnd.parasolid.transmit.binary'],
+ 'x_t' => ['model/vnd.parasolid.transmit.text'],
'xac' => ['application/x-gnucash'],
'xaml' => ['application/xaml+xml'],
'xap' => ['application/x-silverlight-app'],
'xar' => ['application/vnd.xara', 'application/x-xar'],
+ 'xav' => ['application/xcap-att+xml'],
'xbap' => ['application/x-ms-xbap'],
'xbd' => ['application/vnd.fujixerox.docuworks.binder'],
'xbel' => ['application/x-xbel'],
'xbl' => ['application/xml', 'text/xml'],
'xbm' => ['image/x-xbitmap'],
+ 'xca' => ['application/xcap-caps+xml'],
'xcf' => ['image/x-xcf'],
'xcf.bz2' => ['image/x-compressed-xcf'],
'xcf.gz' => ['image/x-compressed-xcf'],
- 'xdf' => ['application/xcap-diff+xml'],
+ 'xcs' => ['application/calendar+xml'],
+ 'xdf' => ['application/mrb-consumer+xml', 'application/mrb-publish+xml', 'application/xcap-diff+xml'],
'xdgapp' => ['application/vnd.flatpak', 'application/vnd.xdgapp'],
'xdm' => ['application/vnd.syncml.dm+xml'],
'xdp' => ['application/vnd.adobe.xdp+xml'],
'xdssc' => ['application/dssc+xml'],
'xdw' => ['application/vnd.fujixerox.docuworks'],
+ 'xel' => ['application/xcap-el+xml'],
'xenc' => ['application/xenc+xml'],
- 'xer' => ['application/patch-ops-error+xml'],
+ 'xer' => ['application/patch-ops-error+xml', 'application/xcap-error+xml'],
'xfdf' => ['application/vnd.adobe.xfdf'],
'xfdl' => ['application/vnd.xfdl'],
'xhe' => ['audio/usac'],
@@ -3103,13 +3483,14 @@ final class MimeTypes implements MimeTypesInterface
'xmf' => ['audio/mobile-xmf', 'audio/x-xmf', 'audio/xmf'],
'xmi' => ['text/x-xmi'],
'xml' => ['application/xml', 'text/xml'],
+ 'xns' => ['application/xcap-ns+xml'],
'xo' => ['application/vnd.olpc-sugar'],
'xop' => ['application/xop+xml'],
'xpi' => ['application/x-xpinstall'],
'xpl' => ['application/xproc+xml'],
'xpm' => ['image/x-xpixmap', 'image/x-xpm'],
'xpr' => ['application/vnd.is-xpr'],
- 'xps' => ['application/oxps', 'application/vnd.ms-xpsdocument', 'application/xps'],
+ 'xps' => ['application/vnd.ms-xpsdocument', 'application/xps'],
'xpw' => ['application/vnd.intercon.formnet'],
'xpx' => ['application/vnd.intercon.formnet'],
'xsd' => ['application/xml', 'text/xml'],
@@ -3128,6 +3509,7 @@ final class MimeTypes implements MimeTypesInterface
'yang' => ['application/yang'],
'yin' => ['application/yin+xml'],
'yml' => ['application/x-yaml', 'text/x-yaml', 'text/yaml'],
+ 'ymp' => ['text/x-suse-ymp'],
'yt' => ['application/vnd.youtube.yt'],
'z1' => ['application/x-zmachine'],
'z2' => ['application/x-zmachine'],
@@ -3146,6 +3528,7 @@ final class MimeTypes implements MimeTypesInterface
'zmm' => ['application/vnd.handheld-entertainment+xml'],
'zoo' => ['application/x-zoo'],
'zsav' => ['application/x-spss-sav', 'application/x-spss-savefile'],
+ 'zst' => ['application/zstd'],
'zz' => ['application/zlib'],
'123' => ['application/lotus123', 'application/vnd.lotus-1-2-3', 'application/wk1', 'application/x-123', 'application/x-lotus123', 'zz-application/zz-winassoc-123'],
'602' => ['application/x-t602'],
diff --git a/vendor/symfony/mime/MimeTypesInterface.php b/vendor/symfony/mime/MimeTypesInterface.php
index 9fbd2cc2d..17d45ad21 100644
--- a/vendor/symfony/mime/MimeTypesInterface.php
+++ b/vendor/symfony/mime/MimeTypesInterface.php
@@ -17,16 +17,16 @@ namespace Symfony\Component\Mime;
interface MimeTypesInterface extends MimeTypeGuesserInterface
{
/**
- * Gets the extensions for the given MIME type.
+ * Gets the extensions for the given MIME type in decreasing order of preference.
*
- * @return string[] an array of extensions (first one is the preferred one)
+ * @return string[]
*/
public function getExtensions(string $mimeType): array;
/**
- * Gets the MIME types for the given extension.
+ * Gets the MIME types for the given extension in decreasing order of preference.
*
- * @return string[] an array of MIME types (first one is the preferred one)
+ * @return string[]
*/
public function getMimeTypes(string $ext): array;
}
diff --git a/vendor/symfony/mime/Part/MessagePart.php b/vendor/symfony/mime/Part/MessagePart.php
index 1b5c23e2b..00129b475 100644
--- a/vendor/symfony/mime/Part/MessagePart.php
+++ b/vendor/symfony/mime/Part/MessagePart.php
@@ -59,4 +59,17 @@ class MessagePart extends DataPart
{
return $this->message->toIterable();
}
+
+ /**
+ * @return array
+ */
+ public function __sleep()
+ {
+ return ['message'];
+ }
+
+ public function __wakeup()
+ {
+ $this->__construct($this->message);
+ }
}
diff --git a/vendor/symfony/mime/Part/Multipart/FormDataPart.php b/vendor/symfony/mime/Part/Multipart/FormDataPart.php
index 93ae1b910..ff6df818f 100644
--- a/vendor/symfony/mime/Part/Multipart/FormDataPart.php
+++ b/vendor/symfony/mime/Part/Multipart/FormDataPart.php
@@ -34,7 +34,7 @@ final class FormDataPart extends AbstractMultipartPart
foreach ($fields as $name => $value) {
if (!\is_string($value) && !\is_array($value) && !$value instanceof TextPart) {
- throw new InvalidArgumentException(sprintf('A form field value can only be a string, an array, or an instance of TextPart ("%s" given).', \is_object($value) ? \get_class($value) : \gettype($value)));
+ throw new InvalidArgumentException(sprintf('A form field value can only be a string, an array, or an instance of TextPart ("%s" given).', get_debug_type($value)));
}
$this->fields[$name] = $value;
@@ -58,7 +58,16 @@ final class FormDataPart extends AbstractMultipartPart
$values = [];
$prepare = function ($item, $key, $root = null) use (&$values, &$prepare) {
- $fieldName = $root ? sprintf('%s[%s]', $root, $key) : $key;
+ if (\is_int($key) && \is_array($item)) {
+ if (1 !== \count($item)) {
+ throw new InvalidArgumentException(sprintf('Form field values with integer keys can only have one array element, the key being the field name and the value being the field value, %d provided.', \count($item)));
+ }
+
+ $key = key($item);
+ $item = $item[$key];
+ }
+
+ $fieldName = null !== $root ? sprintf('%s[%s]', $root, $key) : $key;
if (\is_array($item)) {
array_walk($item, $prepare, $fieldName);
diff --git a/vendor/symfony/mime/Part/SMimePart.php b/vendor/symfony/mime/Part/SMimePart.php
index b4c932a67..cb619c293 100644
--- a/vendor/symfony/mime/Part/SMimePart.php
+++ b/vendor/symfony/mime/Part/SMimePart.php
@@ -36,7 +36,7 @@ class SMimePart extends AbstractPart
parent::__construct();
if (!\is_string($body) && !is_iterable($body)) {
- throw new \TypeError(sprintf('The body of "%s" must be a string or a iterable (got "%s").', self::class, \is_object($body) ? \get_class($body) : \gettype($body)));
+ throw new \TypeError(sprintf('The body of "%s" must be a string or a iterable (got "%s").', self::class, get_debug_type($body)));
}
$this->body = $body;
diff --git a/vendor/symfony/mime/Part/TextPart.php b/vendor/symfony/mime/Part/TextPart.php
index 013a6dfe5..bfe41c0aa 100644
--- a/vendor/symfony/mime/Part/TextPart.php
+++ b/vendor/symfony/mime/Part/TextPart.php
@@ -31,9 +31,13 @@ class TextPart extends AbstractPart
private $body;
private $charset;
private $subtype;
+ /**
+ * @var ?string
+ */
private $disposition;
private $name;
private $encoding;
+ private $seekable;
/**
* @param resource|string $body
@@ -45,12 +49,13 @@ class TextPart extends AbstractPart
parent::__construct();
if (!\is_string($body) && !\is_resource($body)) {
- throw new \TypeError(sprintf('The body of "%s" must be a string or a resource (got "%s").', self::class, \is_object($body) ? \get_class($body) : \gettype($body)));
+ throw new \TypeError(sprintf('The body of "%s" must be a string or a resource (got "%s").', self::class, get_debug_type($body)));
}
$this->body = $body;
$this->charset = $charset;
$this->subtype = $subtype;
+ $this->seekable = \is_resource($body) ? stream_get_meta_data($body)['seekable'] && 0 === fseek($body, 0, \SEEK_CUR) : null;
if (null === $encoding) {
$this->encoding = $this->chooseEncoding();
@@ -89,7 +94,7 @@ class TextPart extends AbstractPart
*
* @return $this
*/
- public function setName($name)
+ public function setName(string $name)
{
$this->name = $name;
@@ -98,11 +103,11 @@ class TextPart extends AbstractPart
public function getBody(): string
{
- if (!\is_resource($this->body)) {
+ if (null === $this->seekable) {
return $this->body;
}
- if (stream_get_meta_data($this->body)['seekable'] ?? false) {
+ if ($this->seekable) {
rewind($this->body);
}
@@ -116,8 +121,8 @@ class TextPart extends AbstractPart
public function bodyToIterable(): iterable
{
- if (\is_resource($this->body)) {
- if (stream_get_meta_data($this->body)['seekable'] ?? false) {
+ if (null !== $this->seekable) {
+ if ($this->seekable) {
rewind($this->body);
}
yield from $this->getEncoder()->encodeByteStream($this->body);
@@ -190,8 +195,9 @@ class TextPart extends AbstractPart
public function __sleep()
{
// convert resources to strings for serialization
- if (\is_resource($this->body)) {
+ if (null !== $this->seekable) {
$this->body = $this->getBody();
+ $this->seekable = null;
}
$this->_headers = $this->getHeaders();
diff --git a/vendor/symfony/mime/Resources/bin/update_mime_types.php b/vendor/symfony/mime/Resources/bin/update_mime_types.php
index 08c52f7d0..5586f097f 100644
--- a/vendor/symfony/mime/Resources/bin/update_mime_types.php
+++ b/vendor/symfony/mime/Resources/bin/update_mime_types.php
@@ -14,18 +14,16 @@ if ('cli' !== \PHP_SAPI) {
}
// load new map
-$data = file_get_contents('https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types');
+$data = json_decode(file_get_contents('https://cdn.jsdelivr.net/gh/jshttp/mime-db@v1.49.0/db.json'), true);
$new = [];
-foreach (explode("\n", $data) as $line) {
- if (!$line || '#' == $line[0]) {
+foreach ($data as $mimeType => $mimeTypeInformation) {
+ if (!array_key_exists('extensions', $mimeTypeInformation)) {
continue;
}
- $mimeType = substr($line, 0, strpos($line, "\t"));
- $extensions = explode(' ', substr($line, strrpos($line, "\t") + 1));
- $new[$mimeType] = $extensions;
+ $new[$mimeType] = $mimeTypeInformation['extensions'];
}
-$xml = simplexml_load_string(file_get_contents('https://raw.github.com/minad/mimemagic/master/script/freedesktop.org.xml'));
+$xml = simplexml_load_string(file_get_contents('https://gitlab.freedesktop.org/xdg/shared-mime-info/-/raw/master/data/freedesktop.org.xml.in'));
foreach ($xml as $node) {
$exts = [];
foreach ($node->glob as $glob) {
@@ -66,82 +64,79 @@ foreach (explode("\n", $data) as $line) {
$current[$matches[1]] = explode("', '", $matches[2]);
}
-// we merge the 2 maps (we never remove old mime types)
-$map = array_replace_recursive($current, $new);
-ksort($map);
-
$data = $pre;
-foreach ($map as $mimeType => $exts) {
- $data .= sprintf(" '%s' => ['%s'],\n", $mimeType, implode("', '", array_unique($exts)));
-}
-$data .= $post;
// reverse map
// we prefill the extensions with some preferences for content-types
$exts = [
- 'aif' => ['audio/x-aiff'],
- 'aiff' => ['audio/x-aiff'],
- 'aps' => ['application/postscript'],
- 'avi' => ['video/avi'],
- 'bmp' => ['image/bmp'],
+ 'asice' => ['application/vnd.etsi.asic-e+zip'],
'bz2' => ['application/x-bz2'],
- 'css' => ['text/css'],
'csv' => ['text/csv'],
- 'dmg' => ['application/x-apple-diskimage'],
- 'doc' => ['application/msword'],
- 'docx' => ['application/vnd.openxmlformats-officedocument.wordprocessingml.document'],
- 'eml' => ['message/rfc822'],
- 'exe' => ['application/x-ms-dos-executable'],
+ 'ecma' => ['application/ecmascript'],
'flv' => ['video/x-flv'],
'gif' => ['image/gif'],
'gz' => ['application/x-gzip'],
- 'hqx' => ['application/stuffit'],
'htm' => ['text/html'],
'html' => ['text/html'],
'jar' => ['application/x-java-archive'],
- 'jpeg' => ['image/jpeg'],
'jpg' => ['image/jpeg'],
'js' => ['text/javascript'],
+ 'keynote' => ['application/vnd.apple.keynote'],
+ 'key' => ['application/vnd.apple.keynote'],
'm3u' => ['audio/x-mpegurl'],
'm4a' => ['audio/mp4'],
+ 'md' => ['text/markdown', 'text/x-markdown'],
'mdb' => ['application/x-msaccess'],
'mid' => ['audio/midi'],
- 'midi' => ['audio/midi'],
'mov' => ['video/quicktime'],
'mp3' => ['audio/mpeg'],
- 'mp4' => ['video/mp4'],
- 'mpeg' => ['video/mpeg'],
- 'mpg' => ['video/mpeg'],
'ogg' => ['audio/ogg'],
'pdf' => ['application/pdf'],
'php' => ['application/x-php'],
- 'php3' => ['application/x-php'],
- 'php4' => ['application/x-php'],
- 'php5' => ['application/x-php'],
- 'png' => ['image/png'],
'ppt' => ['application/vnd.ms-powerpoint'],
- 'pptx' => ['application/vnd.openxmlformats-officedocument.presentationml.presentation'],
- 'ps' => ['application/postscript'],
'rar' => ['application/x-rar-compressed'],
- 'rtf' => ['application/rtf'],
- 'sit' => ['application/x-stuffit'],
+ 'hqx' => ['application/stuffit'],
+ 'sit' => ['application/x-stuffit', 'application/stuffit'],
'svg' => ['image/svg+xml'],
'tar' => ['application/x-tar'],
'tif' => ['image/tiff'],
- 'tiff' => ['image/tiff'],
'ttf' => ['application/x-font-truetype'],
- 'txt' => ['text/plain'],
'vcf' => ['text/x-vcard'],
'wav' => ['audio/wav'],
'wma' => ['audio/x-ms-wma'],
'wmv' => ['audio/x-ms-wmv'],
'xls' => ['application/vnd.ms-excel'],
- 'xlsx' => ['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'],
- 'xml' => ['application/xml'],
'zip' => ['application/zip'],
];
+
+// we merge the 2 maps (we never remove old mime types)
+$map = array_replace_recursive($current, $new);
+
+foreach ($exts as $ext => $types) {
+ foreach ($types as $mt) {
+ if (!isset($map[$mt])) {
+ $map += [$mt => [$ext]];
+ }
+ }
+}
+ksort($map);
+
+foreach ($map as $mimeType => $extensions) {
+ foreach ($exts as $ext => $types) {
+ if (in_array($mimeType, $types, true)) {
+ array_unshift($extensions, $ext);
+ }
+ }
+ $data .= sprintf(" '%s' => ['%s'],\n", $mimeType, implode("', '", array_unique($extensions)));
+}
+$data .= $post;
+
foreach ($map as $mimeType => $extensions) {
foreach ($extensions as $extension) {
+ if ('application/octet-stream' === $mimeType && 'bin' !== $extension) {
+ continue;
+ }
+
$exts[$extension][] = $mimeType;
}
}
diff --git a/vendor/symfony/mime/composer.json b/vendor/symfony/mime/composer.json
index fa4025cd1..5472deab1 100644
--- a/vendor/symfony/mime/composer.json
+++ b/vendor/symfony/mime/composer.json
@@ -16,18 +16,26 @@
}
],
"require": {
- "php": ">=7.1.3",
+ "php": ">=7.2.5",
+ "symfony/deprecation-contracts": "^2.1|^3",
"symfony/polyfill-intl-idn": "^1.10",
"symfony/polyfill-mbstring": "^1.0",
"symfony/polyfill-php80": "^1.16"
},
"require-dev": {
- "egulias/email-validator": "^2.1.10|^3.1",
- "symfony/dependency-injection": "^3.4|^4.1|^5.0"
+ "egulias/email-validator": "^2.1.10|^3.1|^4",
+ "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
+ "symfony/dependency-injection": "^4.4|^5.0|^6.0",
+ "symfony/property-access": "^4.4|^5.1|^6.0",
+ "symfony/property-info": "^4.4|^5.1|^6.0",
+ "symfony/serializer": "^5.4.14|~6.0.14|^6.1.6"
},
"conflict": {
"egulias/email-validator": "~3.0.0",
- "symfony/mailer": "<4.4"
+ "phpdocumentor/reflection-docblock": "<3.2.2",
+ "phpdocumentor/type-resolver": "<1.4.0",
+ "symfony/mailer": "<4.4",
+ "symfony/serializer": "<5.4.14|>=6.0,<6.0.14|>=6.1,<6.1.6"
},
"autoload": {
"psr-4": { "Symfony\\Component\\Mime\\": "" },
diff --git a/vendor/symfony/options-resolver/CHANGELOG.md b/vendor/symfony/options-resolver/CHANGELOG.md
new file mode 100644
index 000000000..84c45946a
--- /dev/null
+++ b/vendor/symfony/options-resolver/CHANGELOG.md
@@ -0,0 +1,81 @@
+CHANGELOG
+=========
+
+5.3
+---
+
+ * Add prototype definition for nested options
+
+5.1.0
+-----
+
+ * added fluent configuration of options using `OptionResolver::define()`
+ * added `setInfo()` and `getInfo()` methods
+ * updated the signature of method `OptionsResolver::setDeprecated()` to `OptionsResolver::setDeprecation(string $option, string $package, string $version, $message)`
+ * deprecated `OptionsResolverIntrospector::getDeprecationMessage()`, use `OptionsResolverIntrospector::getDeprecation()` instead
+
+5.0.0
+-----
+
+ * added argument `$triggerDeprecation` to `OptionsResolver::offsetGet()`
+
+4.3.0
+-----
+
+ * added `OptionsResolver::addNormalizer` method
+
+4.2.0
+-----
+
+ * added support for nested options definition
+ * added `setDeprecated` and `isDeprecated` methods
+
+3.4.0
+-----
+
+ * added `OptionsResolverIntrospector` to inspect options definitions inside an `OptionsResolver` instance
+ * added array of types support in allowed types (e.g int[])
+
+2.6.0
+-----
+
+ * deprecated OptionsResolverInterface
+ * [BC BREAK] removed "array" type hint from OptionsResolverInterface methods
+ setRequired(), setAllowedValues(), addAllowedValues(), setAllowedTypes() and
+ addAllowedTypes()
+ * added OptionsResolver::setDefault()
+ * added OptionsResolver::hasDefault()
+ * added OptionsResolver::setNormalizer()
+ * added OptionsResolver::isRequired()
+ * added OptionsResolver::getRequiredOptions()
+ * added OptionsResolver::isMissing()
+ * added OptionsResolver::getMissingOptions()
+ * added OptionsResolver::setDefined()
+ * added OptionsResolver::isDefined()
+ * added OptionsResolver::getDefinedOptions()
+ * added OptionsResolver::remove()
+ * added OptionsResolver::clear()
+ * deprecated OptionsResolver::replaceDefaults()
+ * deprecated OptionsResolver::setOptional() in favor of setDefined()
+ * deprecated OptionsResolver::isKnown() in favor of isDefined()
+ * [BC BREAK] OptionsResolver::isRequired() returns true now if a required
+ option has a default value set
+ * [BC BREAK] merged Options into OptionsResolver and turned Options into an
+ interface
+ * deprecated Options::overload() (now in OptionsResolver)
+ * deprecated Options::set() (now in OptionsResolver)
+ * deprecated Options::get() (now in OptionsResolver)
+ * deprecated Options::has() (now in OptionsResolver)
+ * deprecated Options::replace() (now in OptionsResolver)
+ * [BC BREAK] Options::get() (now in OptionsResolver) can only be used within
+ lazy option/normalizer closures now
+ * [BC BREAK] removed Traversable interface from Options since using within
+ lazy option/normalizer closures resulted in exceptions
+ * [BC BREAK] removed Options::all() since using within lazy option/normalizer
+ closures resulted in exceptions
+ * [BC BREAK] OptionDefinitionException now extends LogicException instead of
+ RuntimeException
+ * [BC BREAK] normalizers are not executed anymore for unset options
+ * normalizers are executed after validating the options now
+ * [BC BREAK] an UndefinedOptionsException is now thrown instead of an
+ InvalidOptionsException when non-existing options are passed
diff --git a/vendor/symfony/options-resolver/Debug/OptionsResolverIntrospector.php b/vendor/symfony/options-resolver/Debug/OptionsResolverIntrospector.php
new file mode 100644
index 000000000..95909f32e
--- /dev/null
+++ b/vendor/symfony/options-resolver/Debug/OptionsResolverIntrospector.php
@@ -0,0 +1,120 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\OptionsResolver\Debug;
+
+use Symfony\Component\OptionsResolver\Exception\NoConfigurationException;
+use Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+
+/**
+ * @author Maxime Steinhausser
+ *
+ * @final
+ */
+class OptionsResolverIntrospector
+{
+ private $get;
+
+ public function __construct(OptionsResolver $optionsResolver)
+ {
+ $this->get = \Closure::bind(function ($property, $option, $message) {
+ /** @var OptionsResolver $this */
+ if (!$this->isDefined($option)) {
+ throw new UndefinedOptionsException(sprintf('The option "%s" does not exist.', $option));
+ }
+
+ if (!\array_key_exists($option, $this->{$property})) {
+ throw new NoConfigurationException($message);
+ }
+
+ return $this->{$property}[$option];
+ }, $optionsResolver, $optionsResolver);
+ }
+
+ /**
+ * @return mixed
+ *
+ * @throws NoConfigurationException on no configured value
+ */
+ public function getDefault(string $option)
+ {
+ return ($this->get)('defaults', $option, sprintf('No default value was set for the "%s" option.', $option));
+ }
+
+ /**
+ * @return \Closure[]
+ *
+ * @throws NoConfigurationException on no configured closures
+ */
+ public function getLazyClosures(string $option): array
+ {
+ return ($this->get)('lazy', $option, sprintf('No lazy closures were set for the "%s" option.', $option));
+ }
+
+ /**
+ * @return string[]
+ *
+ * @throws NoConfigurationException on no configured types
+ */
+ public function getAllowedTypes(string $option): array
+ {
+ return ($this->get)('allowedTypes', $option, sprintf('No allowed types were set for the "%s" option.', $option));
+ }
+
+ /**
+ * @return mixed[]
+ *
+ * @throws NoConfigurationException on no configured values
+ */
+ public function getAllowedValues(string $option): array
+ {
+ return ($this->get)('allowedValues', $option, sprintf('No allowed values were set for the "%s" option.', $option));
+ }
+
+ /**
+ * @throws NoConfigurationException on no configured normalizer
+ */
+ public function getNormalizer(string $option): \Closure
+ {
+ return current($this->getNormalizers($option));
+ }
+
+ /**
+ * @throws NoConfigurationException when no normalizer is configured
+ */
+ public function getNormalizers(string $option): array
+ {
+ return ($this->get)('normalizers', $option, sprintf('No normalizer was set for the "%s" option.', $option));
+ }
+
+ /**
+ * @return string|\Closure
+ *
+ * @throws NoConfigurationException on no configured deprecation
+ *
+ * @deprecated since Symfony 5.1, use "getDeprecation()" instead.
+ */
+ public function getDeprecationMessage(string $option)
+ {
+ trigger_deprecation('symfony/options-resolver', '5.1', 'The "%s()" method is deprecated, use "getDeprecation()" instead.', __METHOD__);
+
+ return $this->getDeprecation($option)['message'];
+ }
+
+ /**
+ * @throws NoConfigurationException on no configured deprecation
+ */
+ public function getDeprecation(string $option): array
+ {
+ return ($this->get)('deprecated', $option, sprintf('No deprecation was set for the "%s" option.', $option));
+ }
+}
diff --git a/vendor/symfony/options-resolver/Exception/AccessException.php b/vendor/symfony/options-resolver/Exception/AccessException.php
new file mode 100644
index 000000000..c12b68064
--- /dev/null
+++ b/vendor/symfony/options-resolver/Exception/AccessException.php
@@ -0,0 +1,22 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\OptionsResolver\Exception;
+
+/**
+ * Thrown when trying to read an option outside of or write it inside of
+ * {@link \Symfony\Component\OptionsResolver\Options::resolve()}.
+ *
+ * @author Bernhard Schussek
+ */
+class AccessException extends \LogicException implements ExceptionInterface
+{
+}
diff --git a/vendor/symfony/options-resolver/Exception/ExceptionInterface.php b/vendor/symfony/options-resolver/Exception/ExceptionInterface.php
new file mode 100644
index 000000000..ea99d050e
--- /dev/null
+++ b/vendor/symfony/options-resolver/Exception/ExceptionInterface.php
@@ -0,0 +1,21 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\OptionsResolver\Exception;
+
+/**
+ * Marker interface for all exceptions thrown by the OptionsResolver component.
+ *
+ * @author Bernhard Schussek
+ */
+interface ExceptionInterface extends \Throwable
+{
+}
diff --git a/vendor/symfony/options-resolver/Exception/InvalidArgumentException.php b/vendor/symfony/options-resolver/Exception/InvalidArgumentException.php
new file mode 100644
index 000000000..6d421d68b
--- /dev/null
+++ b/vendor/symfony/options-resolver/Exception/InvalidArgumentException.php
@@ -0,0 +1,21 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\OptionsResolver\Exception;
+
+/**
+ * Thrown when an argument is invalid.
+ *
+ * @author Bernhard Schussek
+ */
+class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
+{
+}
diff --git a/vendor/symfony/options-resolver/Exception/InvalidOptionsException.php b/vendor/symfony/options-resolver/Exception/InvalidOptionsException.php
new file mode 100644
index 000000000..6fd4f125f
--- /dev/null
+++ b/vendor/symfony/options-resolver/Exception/InvalidOptionsException.php
@@ -0,0 +1,23 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\OptionsResolver\Exception;
+
+/**
+ * Thrown when the value of an option does not match its validation rules.
+ *
+ * You should make sure a valid value is passed to the option.
+ *
+ * @author Bernhard Schussek
+ */
+class InvalidOptionsException extends InvalidArgumentException
+{
+}
diff --git a/vendor/symfony/options-resolver/Exception/MissingOptionsException.php b/vendor/symfony/options-resolver/Exception/MissingOptionsException.php
new file mode 100644
index 000000000..faa487f16
--- /dev/null
+++ b/vendor/symfony/options-resolver/Exception/MissingOptionsException.php
@@ -0,0 +1,23 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\OptionsResolver\Exception;
+
+/**
+ * Exception thrown when a required option is missing.
+ *
+ * Add the option to the passed options array.
+ *
+ * @author Bernhard Schussek
+ */
+class MissingOptionsException extends InvalidArgumentException
+{
+}
diff --git a/vendor/symfony/options-resolver/Exception/NoConfigurationException.php b/vendor/symfony/options-resolver/Exception/NoConfigurationException.php
new file mode 100644
index 000000000..6693ec14d
--- /dev/null
+++ b/vendor/symfony/options-resolver/Exception/NoConfigurationException.php
@@ -0,0 +1,26 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\OptionsResolver\Exception;
+
+use Symfony\Component\OptionsResolver\Debug\OptionsResolverIntrospector;
+
+/**
+ * Thrown when trying to introspect an option definition property
+ * for which no value was configured inside the OptionsResolver instance.
+ *
+ * @see OptionsResolverIntrospector
+ *
+ * @author Maxime Steinhausser
+ */
+class NoConfigurationException extends \RuntimeException implements ExceptionInterface
+{
+}
diff --git a/vendor/symfony/options-resolver/Exception/NoSuchOptionException.php b/vendor/symfony/options-resolver/Exception/NoSuchOptionException.php
new file mode 100644
index 000000000..4c3280f4c
--- /dev/null
+++ b/vendor/symfony/options-resolver/Exception/NoSuchOptionException.php
@@ -0,0 +1,26 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\OptionsResolver\Exception;
+
+/**
+ * Thrown when trying to read an option that has no value set.
+ *
+ * When accessing optional options from within a lazy option or normalizer you should first
+ * check whether the optional option is set. You can do this with `isset($options['optional'])`.
+ * In contrast to the {@link UndefinedOptionsException}, this is a runtime exception that can
+ * occur when evaluating lazy options.
+ *
+ * @author Tobias Schultze
+ */
+class NoSuchOptionException extends \OutOfBoundsException implements ExceptionInterface
+{
+}
diff --git a/vendor/symfony/options-resolver/Exception/OptionDefinitionException.php b/vendor/symfony/options-resolver/Exception/OptionDefinitionException.php
new file mode 100644
index 000000000..e8e339d44
--- /dev/null
+++ b/vendor/symfony/options-resolver/Exception/OptionDefinitionException.php
@@ -0,0 +1,21 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\OptionsResolver\Exception;
+
+/**
+ * Thrown when two lazy options have a cyclic dependency.
+ *
+ * @author Bernhard Schussek
+ */
+class OptionDefinitionException extends \LogicException implements ExceptionInterface
+{
+}
diff --git a/vendor/symfony/options-resolver/Exception/UndefinedOptionsException.php b/vendor/symfony/options-resolver/Exception/UndefinedOptionsException.php
new file mode 100644
index 000000000..6ca3fce47
--- /dev/null
+++ b/vendor/symfony/options-resolver/Exception/UndefinedOptionsException.php
@@ -0,0 +1,24 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\OptionsResolver\Exception;
+
+/**
+ * Exception thrown when an undefined option is passed.
+ *
+ * You should remove the options in question from your code or define them
+ * beforehand.
+ *
+ * @author Bernhard Schussek
+ */
+class UndefinedOptionsException extends InvalidArgumentException
+{
+}
diff --git a/vendor/symfony/options-resolver/LICENSE b/vendor/symfony/options-resolver/LICENSE
new file mode 100644
index 000000000..008370457
--- /dev/null
+++ b/vendor/symfony/options-resolver/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2023 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/symfony/options-resolver/OptionConfigurator.php b/vendor/symfony/options-resolver/OptionConfigurator.php
new file mode 100644
index 000000000..62f03d064
--- /dev/null
+++ b/vendor/symfony/options-resolver/OptionConfigurator.php
@@ -0,0 +1,139 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\OptionsResolver;
+
+use Symfony\Component\OptionsResolver\Exception\AccessException;
+
+final class OptionConfigurator
+{
+ private $name;
+ private $resolver;
+
+ public function __construct(string $name, OptionsResolver $resolver)
+ {
+ $this->name = $name;
+ $this->resolver = $resolver;
+ $this->resolver->setDefined($name);
+ }
+
+ /**
+ * Adds allowed types for this option.
+ *
+ * @return $this
+ *
+ * @throws AccessException If called from a lazy option or normalizer
+ */
+ public function allowedTypes(string ...$types): self
+ {
+ $this->resolver->setAllowedTypes($this->name, $types);
+
+ return $this;
+ }
+
+ /**
+ * Sets allowed values for this option.
+ *
+ * @param mixed ...$values One or more acceptable values/closures
+ *
+ * @return $this
+ *
+ * @throws AccessException If called from a lazy option or normalizer
+ */
+ public function allowedValues(...$values): self
+ {
+ $this->resolver->setAllowedValues($this->name, $values);
+
+ return $this;
+ }
+
+ /**
+ * Sets the default value for this option.
+ *
+ * @param mixed $value The default value of the option
+ *
+ * @return $this
+ *
+ * @throws AccessException If called from a lazy option or normalizer
+ */
+ public function default($value): self
+ {
+ $this->resolver->setDefault($this->name, $value);
+
+ return $this;
+ }
+
+ /**
+ * Defines an option configurator with the given name.
+ */
+ public function define(string $option): self
+ {
+ return $this->resolver->define($option);
+ }
+
+ /**
+ * Marks this option as deprecated.
+ *
+ * @param string $package The name of the composer package that is triggering the deprecation
+ * @param string $version The version of the package that introduced the deprecation
+ * @param string|\Closure $message The deprecation message to use
+ *
+ * @return $this
+ */
+ public function deprecated(string $package, string $version, $message = 'The option "%name%" is deprecated.'): self
+ {
+ $this->resolver->setDeprecated($this->name, $package, $version, $message);
+
+ return $this;
+ }
+
+ /**
+ * Sets the normalizer for this option.
+ *
+ * @return $this
+ *
+ * @throws AccessException If called from a lazy option or normalizer
+ */
+ public function normalize(\Closure $normalizer): self
+ {
+ $this->resolver->setNormalizer($this->name, $normalizer);
+
+ return $this;
+ }
+
+ /**
+ * Marks this option as required.
+ *
+ * @return $this
+ *
+ * @throws AccessException If called from a lazy option or normalizer
+ */
+ public function required(): self
+ {
+ $this->resolver->setRequired($this->name);
+
+ return $this;
+ }
+
+ /**
+ * Sets an info message for an option.
+ *
+ * @return $this
+ *
+ * @throws AccessException If called from a lazy option or normalizer
+ */
+ public function info(string $info): self
+ {
+ $this->resolver->setInfo($this->name, $info);
+
+ return $this;
+ }
+}
diff --git a/vendor/symfony/options-resolver/Options.php b/vendor/symfony/options-resolver/Options.php
new file mode 100644
index 000000000..d444ec423
--- /dev/null
+++ b/vendor/symfony/options-resolver/Options.php
@@ -0,0 +1,22 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\OptionsResolver;
+
+/**
+ * Contains resolved option values.
+ *
+ * @author Bernhard Schussek
+ * @author Tobias Schultze
+ */
+interface Options extends \ArrayAccess, \Countable
+{
+}
diff --git a/vendor/symfony/options-resolver/OptionsResolver.php b/vendor/symfony/options-resolver/OptionsResolver.php
new file mode 100644
index 000000000..3db291f99
--- /dev/null
+++ b/vendor/symfony/options-resolver/OptionsResolver.php
@@ -0,0 +1,1347 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\OptionsResolver;
+
+use Symfony\Component\OptionsResolver\Exception\AccessException;
+use Symfony\Component\OptionsResolver\Exception\InvalidArgumentException;
+use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException;
+use Symfony\Component\OptionsResolver\Exception\MissingOptionsException;
+use Symfony\Component\OptionsResolver\Exception\NoSuchOptionException;
+use Symfony\Component\OptionsResolver\Exception\OptionDefinitionException;
+use Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException;
+
+/**
+ * Validates options and merges them with default values.
+ *
+ * @author Bernhard Schussek
+ * @author Tobias Schultze
+ */
+class OptionsResolver implements Options
+{
+ private const VALIDATION_FUNCTIONS = [
+ 'bool' => 'is_bool',
+ 'boolean' => 'is_bool',
+ 'int' => 'is_int',
+ 'integer' => 'is_int',
+ 'long' => 'is_int',
+ 'float' => 'is_float',
+ 'double' => 'is_float',
+ 'real' => 'is_float',
+ 'numeric' => 'is_numeric',
+ 'string' => 'is_string',
+ 'scalar' => 'is_scalar',
+ 'array' => 'is_array',
+ 'iterable' => 'is_iterable',
+ 'countable' => 'is_countable',
+ 'callable' => 'is_callable',
+ 'object' => 'is_object',
+ 'resource' => 'is_resource',
+ ];
+
+ /**
+ * The names of all defined options.
+ */
+ private $defined = [];
+
+ /**
+ * The default option values.
+ */
+ private $defaults = [];
+
+ /**
+ * A list of closure for nested options.
+ *
+ * @var \Closure[][]
+ */
+ private $nested = [];
+
+ /**
+ * The names of required options.
+ */
+ private $required = [];
+
+ /**
+ * The resolved option values.
+ */
+ private $resolved = [];
+
+ /**
+ * A list of normalizer closures.
+ *
+ * @var \Closure[][]
+ */
+ private $normalizers = [];
+
+ /**
+ * A list of accepted values for each option.
+ */
+ private $allowedValues = [];
+
+ /**
+ * A list of accepted types for each option.
+ */
+ private $allowedTypes = [];
+
+ /**
+ * A list of info messages for each option.
+ */
+ private $info = [];
+
+ /**
+ * A list of closures for evaluating lazy options.
+ */
+ private $lazy = [];
+
+ /**
+ * A list of lazy options whose closure is currently being called.
+ *
+ * This list helps detecting circular dependencies between lazy options.
+ */
+ private $calling = [];
+
+ /**
+ * A list of deprecated options.
+ */
+ private $deprecated = [];
+
+ /**
+ * The list of options provided by the user.
+ */
+ private $given = [];
+
+ /**
+ * Whether the instance is locked for reading.
+ *
+ * Once locked, the options cannot be changed anymore. This is
+ * necessary in order to avoid inconsistencies during the resolving
+ * process. If any option is changed after being read, all evaluated
+ * lazy options that depend on this option would become invalid.
+ */
+ private $locked = false;
+
+ private $parentsOptions = [];
+
+ /**
+ * Whether the whole options definition is marked as array prototype.
+ */
+ private $prototype;
+
+ /**
+ * The prototype array's index that is being read.
+ */
+ private $prototypeIndex;
+
+ /**
+ * Sets the default value of a given option.
+ *
+ * If the default value should be set based on other options, you can pass
+ * a closure with the following signature:
+ *
+ * function (Options $options) {
+ * // ...
+ * }
+ *
+ * The closure will be evaluated when {@link resolve()} is called. The
+ * closure has access to the resolved values of other options through the
+ * passed {@link Options} instance:
+ *
+ * function (Options $options) {
+ * if (isset($options['port'])) {
+ * // ...
+ * }
+ * }
+ *
+ * If you want to access the previously set default value, add a second
+ * argument to the closure's signature:
+ *
+ * $options->setDefault('name', 'Default Name');
+ *
+ * $options->setDefault('name', function (Options $options, $previousValue) {
+ * // 'Default Name' === $previousValue
+ * });
+ *
+ * This is mostly useful if the configuration of the {@link Options} object
+ * is spread across different locations of your code, such as base and
+ * sub-classes.
+ *
+ * If you want to define nested options, you can pass a closure with the
+ * following signature:
+ *
+ * $options->setDefault('database', function (OptionsResolver $resolver) {
+ * $resolver->setDefined(['dbname', 'host', 'port', 'user', 'pass']);
+ * }
+ *
+ * To get access to the parent options, add a second argument to the closure's
+ * signature:
+ *
+ * function (OptionsResolver $resolver, Options $parent) {
+ * // 'default' === $parent['connection']
+ * }
+ *
+ * @param string $option The name of the option
+ * @param mixed $value The default value of the option
+ *
+ * @return $this
+ *
+ * @throws AccessException If called from a lazy option or normalizer
+ */
+ public function setDefault(string $option, $value)
+ {
+ // Setting is not possible once resolving starts, because then lazy
+ // options could manipulate the state of the object, leading to
+ // inconsistent results.
+ if ($this->locked) {
+ throw new AccessException('Default values cannot be set from a lazy option or normalizer.');
+ }
+
+ // If an option is a closure that should be evaluated lazily, store it
+ // in the "lazy" property.
+ if ($value instanceof \Closure) {
+ $reflClosure = new \ReflectionFunction($value);
+ $params = $reflClosure->getParameters();
+
+ if (isset($params[0]) && Options::class === $this->getParameterClassName($params[0])) {
+ // Initialize the option if no previous value exists
+ if (!isset($this->defaults[$option])) {
+ $this->defaults[$option] = null;
+ }
+
+ // Ignore previous lazy options if the closure has no second parameter
+ if (!isset($this->lazy[$option]) || !isset($params[1])) {
+ $this->lazy[$option] = [];
+ }
+
+ // Store closure for later evaluation
+ $this->lazy[$option][] = $value;
+ $this->defined[$option] = true;
+
+ // Make sure the option is processed and is not nested anymore
+ unset($this->resolved[$option], $this->nested[$option]);
+
+ return $this;
+ }
+
+ if (isset($params[0]) && null !== ($type = $params[0]->getType()) && self::class === $type->getName() && (!isset($params[1]) || (($type = $params[1]->getType()) instanceof \ReflectionNamedType && Options::class === $type->getName()))) {
+ // Store closure for later evaluation
+ $this->nested[$option][] = $value;
+ $this->defaults[$option] = [];
+ $this->defined[$option] = true;
+
+ // Make sure the option is processed and is not lazy anymore
+ unset($this->resolved[$option], $this->lazy[$option]);
+
+ return $this;
+ }
+ }
+
+ // This option is not lazy nor nested anymore
+ unset($this->lazy[$option], $this->nested[$option]);
+
+ // Yet undefined options can be marked as resolved, because we only need
+ // to resolve options with lazy closures, normalizers or validation
+ // rules, none of which can exist for undefined options
+ // If the option was resolved before, update the resolved value
+ if (!isset($this->defined[$option]) || \array_key_exists($option, $this->resolved)) {
+ $this->resolved[$option] = $value;
+ }
+
+ $this->defaults[$option] = $value;
+ $this->defined[$option] = true;
+
+ return $this;
+ }
+
+ /**
+ * @return $this
+ *
+ * @throws AccessException If called from a lazy option or normalizer
+ */
+ public function setDefaults(array $defaults)
+ {
+ foreach ($defaults as $option => $value) {
+ $this->setDefault($option, $value);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Returns whether a default value is set for an option.
+ *
+ * Returns true if {@link setDefault()} was called for this option.
+ * An option is also considered set if it was set to null.
+ *
+ * @return bool
+ */
+ public function hasDefault(string $option)
+ {
+ return \array_key_exists($option, $this->defaults);
+ }
+
+ /**
+ * Marks one or more options as required.
+ *
+ * @param string|string[] $optionNames One or more option names
+ *
+ * @return $this
+ *
+ * @throws AccessException If called from a lazy option or normalizer
+ */
+ public function setRequired($optionNames)
+ {
+ if ($this->locked) {
+ throw new AccessException('Options cannot be made required from a lazy option or normalizer.');
+ }
+
+ foreach ((array) $optionNames as $option) {
+ $this->defined[$option] = true;
+ $this->required[$option] = true;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Returns whether an option is required.
+ *
+ * An option is required if it was passed to {@link setRequired()}.
+ *
+ * @return bool
+ */
+ public function isRequired(string $option)
+ {
+ return isset($this->required[$option]);
+ }
+
+ /**
+ * Returns the names of all required options.
+ *
+ * @return string[]
+ *
+ * @see isRequired()
+ */
+ public function getRequiredOptions()
+ {
+ return array_keys($this->required);
+ }
+
+ /**
+ * Returns whether an option is missing a default value.
+ *
+ * An option is missing if it was passed to {@link setRequired()}, but not
+ * to {@link setDefault()}. This option must be passed explicitly to
+ * {@link resolve()}, otherwise an exception will be thrown.
+ *
+ * @return bool
+ */
+ public function isMissing(string $option)
+ {
+ return isset($this->required[$option]) && !\array_key_exists($option, $this->defaults);
+ }
+
+ /**
+ * Returns the names of all options missing a default value.
+ *
+ * @return string[]
+ */
+ public function getMissingOptions()
+ {
+ return array_keys(array_diff_key($this->required, $this->defaults));
+ }
+
+ /**
+ * Defines a valid option name.
+ *
+ * Defines an option name without setting a default value. The option will
+ * be accepted when passed to {@link resolve()}. When not passed, the
+ * option will not be included in the resolved options.
+ *
+ * @param string|string[] $optionNames One or more option names
+ *
+ * @return $this
+ *
+ * @throws AccessException If called from a lazy option or normalizer
+ */
+ public function setDefined($optionNames)
+ {
+ if ($this->locked) {
+ throw new AccessException('Options cannot be defined from a lazy option or normalizer.');
+ }
+
+ foreach ((array) $optionNames as $option) {
+ $this->defined[$option] = true;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Returns whether an option is defined.
+ *
+ * Returns true for any option passed to {@link setDefault()},
+ * {@link setRequired()} or {@link setDefined()}.
+ *
+ * @return bool
+ */
+ public function isDefined(string $option)
+ {
+ return isset($this->defined[$option]);
+ }
+
+ /**
+ * Returns the names of all defined options.
+ *
+ * @return string[]
+ *
+ * @see isDefined()
+ */
+ public function getDefinedOptions()
+ {
+ return array_keys($this->defined);
+ }
+
+ public function isNested(string $option): bool
+ {
+ return isset($this->nested[$option]);
+ }
+
+ /**
+ * Deprecates an option, allowed types or values.
+ *
+ * Instead of passing the message, you may also pass a closure with the
+ * following signature:
+ *
+ * function (Options $options, $value): string {
+ * // ...
+ * }
+ *
+ * The closure receives the value as argument and should return a string.
+ * Return an empty string to ignore the option deprecation.
+ *
+ * The closure is invoked when {@link resolve()} is called. The parameter
+ * passed to the closure is the value of the option after validating it
+ * and before normalizing it.
+ *
+ * @param string $package The name of the composer package that is triggering the deprecation
+ * @param string $version The version of the package that introduced the deprecation
+ * @param string|\Closure $message The deprecation message to use
+ *
+ * @return $this
+ */
+ public function setDeprecated(string $option/* , string $package, string $version, $message = 'The option "%name%" is deprecated.' */): self
+ {
+ if ($this->locked) {
+ throw new AccessException('Options cannot be deprecated from a lazy option or normalizer.');
+ }
+
+ if (!isset($this->defined[$option])) {
+ throw new UndefinedOptionsException(sprintf('The option "%s" does not exist, defined options are: "%s".', $this->formatOptions([$option]), implode('", "', array_keys($this->defined))));
+ }
+
+ $args = \func_get_args();
+
+ if (\func_num_args() < 3) {
+ trigger_deprecation('symfony/options-resolver', '5.1', 'The signature of method "%s()" requires 2 new arguments: "string $package, string $version", not defining them is deprecated.', __METHOD__);
+
+ $message = $args[1] ?? 'The option "%name%" is deprecated.';
+ $package = $version = '';
+ } else {
+ $package = $args[1];
+ $version = $args[2];
+ $message = $args[3] ?? 'The option "%name%" is deprecated.';
+ }
+
+ if (!\is_string($message) && !$message instanceof \Closure) {
+ throw new InvalidArgumentException(sprintf('Invalid type for deprecation message argument, expected string or \Closure, but got "%s".', get_debug_type($message)));
+ }
+
+ // ignore if empty string
+ if ('' === $message) {
+ return $this;
+ }
+
+ $this->deprecated[$option] = [
+ 'package' => $package,
+ 'version' => $version,
+ 'message' => $message,
+ ];
+
+ // Make sure the option is processed
+ unset($this->resolved[$option]);
+
+ return $this;
+ }
+
+ public function isDeprecated(string $option): bool
+ {
+ return isset($this->deprecated[$option]);
+ }
+
+ /**
+ * Sets the normalizer for an option.
+ *
+ * The normalizer should be a closure with the following signature:
+ *
+ * function (Options $options, $value) {
+ * // ...
+ * }
+ *
+ * The closure is invoked when {@link resolve()} is called. The closure
+ * has access to the resolved values of other options through the passed
+ * {@link Options} instance.
+ *
+ * The second parameter passed to the closure is the value of
+ * the option.
+ *
+ * The resolved option value is set to the return value of the closure.
+ *
+ * @return $this
+ *
+ * @throws UndefinedOptionsException If the option is undefined
+ * @throws AccessException If called from a lazy option or normalizer
+ */
+ public function setNormalizer(string $option, \Closure $normalizer)
+ {
+ if ($this->locked) {
+ throw new AccessException('Normalizers cannot be set from a lazy option or normalizer.');
+ }
+
+ if (!isset($this->defined[$option])) {
+ throw new UndefinedOptionsException(sprintf('The option "%s" does not exist. Defined options are: "%s".', $this->formatOptions([$option]), implode('", "', array_keys($this->defined))));
+ }
+
+ $this->normalizers[$option] = [$normalizer];
+
+ // Make sure the option is processed
+ unset($this->resolved[$option]);
+
+ return $this;
+ }
+
+ /**
+ * Adds a normalizer for an option.
+ *
+ * The normalizer should be a closure with the following signature:
+ *
+ * function (Options $options, $value): mixed {
+ * // ...
+ * }
+ *
+ * The closure is invoked when {@link resolve()} is called. The closure
+ * has access to the resolved values of other options through the passed
+ * {@link Options} instance.
+ *
+ * The second parameter passed to the closure is the value of
+ * the option.
+ *
+ * The resolved option value is set to the return value of the closure.
+ *
+ * @return $this
+ *
+ * @throws UndefinedOptionsException If the option is undefined
+ * @throws AccessException If called from a lazy option or normalizer
+ */
+ public function addNormalizer(string $option, \Closure $normalizer, bool $forcePrepend = false): self
+ {
+ if ($this->locked) {
+ throw new AccessException('Normalizers cannot be set from a lazy option or normalizer.');
+ }
+
+ if (!isset($this->defined[$option])) {
+ throw new UndefinedOptionsException(sprintf('The option "%s" does not exist. Defined options are: "%s".', $this->formatOptions([$option]), implode('", "', array_keys($this->defined))));
+ }
+
+ if ($forcePrepend) {
+ $this->normalizers[$option] = $this->normalizers[$option] ?? [];
+ array_unshift($this->normalizers[$option], $normalizer);
+ } else {
+ $this->normalizers[$option][] = $normalizer;
+ }
+
+ // Make sure the option is processed
+ unset($this->resolved[$option]);
+
+ return $this;
+ }
+
+ /**
+ * Sets allowed values for an option.
+ *
+ * Instead of passing values, you may also pass a closures with the
+ * following signature:
+ *
+ * function ($value) {
+ * // return true or false
+ * }
+ *
+ * The closure receives the value as argument and should return true to
+ * accept the value and false to reject the value.
+ *
+ * @param string $option The option name
+ * @param mixed $allowedValues One or more acceptable values/closures
+ *
+ * @return $this
+ *
+ * @throws UndefinedOptionsException If the option is undefined
+ * @throws AccessException If called from a lazy option or normalizer
+ */
+ public function setAllowedValues(string $option, $allowedValues)
+ {
+ if ($this->locked) {
+ throw new AccessException('Allowed values cannot be set from a lazy option or normalizer.');
+ }
+
+ if (!isset($this->defined[$option])) {
+ throw new UndefinedOptionsException(sprintf('The option "%s" does not exist. Defined options are: "%s".', $this->formatOptions([$option]), implode('", "', array_keys($this->defined))));
+ }
+
+ $this->allowedValues[$option] = \is_array($allowedValues) ? $allowedValues : [$allowedValues];
+
+ // Make sure the option is processed
+ unset($this->resolved[$option]);
+
+ return $this;
+ }
+
+ /**
+ * Adds allowed values for an option.
+ *
+ * The values are merged with the allowed values defined previously.
+ *
+ * Instead of passing values, you may also pass a closures with the
+ * following signature:
+ *
+ * function ($value) {
+ * // return true or false
+ * }
+ *
+ * The closure receives the value as argument and should return true to
+ * accept the value and false to reject the value.
+ *
+ * @param string $option The option name
+ * @param mixed $allowedValues One or more acceptable values/closures
+ *
+ * @return $this
+ *
+ * @throws UndefinedOptionsException If the option is undefined
+ * @throws AccessException If called from a lazy option or normalizer
+ */
+ public function addAllowedValues(string $option, $allowedValues)
+ {
+ if ($this->locked) {
+ throw new AccessException('Allowed values cannot be added from a lazy option or normalizer.');
+ }
+
+ if (!isset($this->defined[$option])) {
+ throw new UndefinedOptionsException(sprintf('The option "%s" does not exist. Defined options are: "%s".', $this->formatOptions([$option]), implode('", "', array_keys($this->defined))));
+ }
+
+ if (!\is_array($allowedValues)) {
+ $allowedValues = [$allowedValues];
+ }
+
+ if (!isset($this->allowedValues[$option])) {
+ $this->allowedValues[$option] = $allowedValues;
+ } else {
+ $this->allowedValues[$option] = array_merge($this->allowedValues[$option], $allowedValues);
+ }
+
+ // Make sure the option is processed
+ unset($this->resolved[$option]);
+
+ return $this;
+ }
+
+ /**
+ * Sets allowed types for an option.
+ *
+ * Any type for which a corresponding is_() function exists is
+ * acceptable. Additionally, fully-qualified class or interface names may
+ * be passed.
+ *
+ * @param string|string[] $allowedTypes One or more accepted types
+ *
+ * @return $this
+ *
+ * @throws UndefinedOptionsException If the option is undefined
+ * @throws AccessException If called from a lazy option or normalizer
+ */
+ public function setAllowedTypes(string $option, $allowedTypes)
+ {
+ if ($this->locked) {
+ throw new AccessException('Allowed types cannot be set from a lazy option or normalizer.');
+ }
+
+ if (!isset($this->defined[$option])) {
+ throw new UndefinedOptionsException(sprintf('The option "%s" does not exist. Defined options are: "%s".', $this->formatOptions([$option]), implode('", "', array_keys($this->defined))));
+ }
+
+ $this->allowedTypes[$option] = (array) $allowedTypes;
+
+ // Make sure the option is processed
+ unset($this->resolved[$option]);
+
+ return $this;
+ }
+
+ /**
+ * Adds allowed types for an option.
+ *
+ * The types are merged with the allowed types defined previously.
+ *
+ * Any type for which a corresponding is_() function exists is
+ * acceptable. Additionally, fully-qualified class or interface names may
+ * be passed.
+ *
+ * @param string|string[] $allowedTypes One or more accepted types
+ *
+ * @return $this
+ *
+ * @throws UndefinedOptionsException If the option is undefined
+ * @throws AccessException If called from a lazy option or normalizer
+ */
+ public function addAllowedTypes(string $option, $allowedTypes)
+ {
+ if ($this->locked) {
+ throw new AccessException('Allowed types cannot be added from a lazy option or normalizer.');
+ }
+
+ if (!isset($this->defined[$option])) {
+ throw new UndefinedOptionsException(sprintf('The option "%s" does not exist. Defined options are: "%s".', $this->formatOptions([$option]), implode('", "', array_keys($this->defined))));
+ }
+
+ if (!isset($this->allowedTypes[$option])) {
+ $this->allowedTypes[$option] = (array) $allowedTypes;
+ } else {
+ $this->allowedTypes[$option] = array_merge($this->allowedTypes[$option], (array) $allowedTypes);
+ }
+
+ // Make sure the option is processed
+ unset($this->resolved[$option]);
+
+ return $this;
+ }
+
+ /**
+ * Defines an option configurator with the given name.
+ */
+ public function define(string $option): OptionConfigurator
+ {
+ if (isset($this->defined[$option])) {
+ throw new OptionDefinitionException(sprintf('The option "%s" is already defined.', $option));
+ }
+
+ return new OptionConfigurator($option, $this);
+ }
+
+ /**
+ * Sets an info message for an option.
+ *
+ * @return $this
+ *
+ * @throws UndefinedOptionsException If the option is undefined
+ * @throws AccessException If called from a lazy option or normalizer
+ */
+ public function setInfo(string $option, string $info): self
+ {
+ if ($this->locked) {
+ throw new AccessException('The Info message cannot be set from a lazy option or normalizer.');
+ }
+
+ if (!isset($this->defined[$option])) {
+ throw new UndefinedOptionsException(sprintf('The option "%s" does not exist. Defined options are: "%s".', $this->formatOptions([$option]), implode('", "', array_keys($this->defined))));
+ }
+
+ $this->info[$option] = $info;
+
+ return $this;
+ }
+
+ /**
+ * Gets the info message for an option.
+ */
+ public function getInfo(string $option): ?string
+ {
+ if (!isset($this->defined[$option])) {
+ throw new UndefinedOptionsException(sprintf('The option "%s" does not exist. Defined options are: "%s".', $this->formatOptions([$option]), implode('", "', array_keys($this->defined))));
+ }
+
+ return $this->info[$option] ?? null;
+ }
+
+ /**
+ * Marks the whole options definition as array prototype.
+ *
+ * @return $this
+ *
+ * @throws AccessException If called from a lazy option, a normalizer or a root definition
+ */
+ public function setPrototype(bool $prototype): self
+ {
+ if ($this->locked) {
+ throw new AccessException('The prototype property cannot be set from a lazy option or normalizer.');
+ }
+
+ if (null === $this->prototype && $prototype) {
+ throw new AccessException('The prototype property cannot be set from a root definition.');
+ }
+
+ $this->prototype = $prototype;
+
+ return $this;
+ }
+
+ public function isPrototype(): bool
+ {
+ return $this->prototype ?? false;
+ }
+
+ /**
+ * Removes the option with the given name.
+ *
+ * Undefined options are ignored.
+ *
+ * @param string|string[] $optionNames One or more option names
+ *
+ * @return $this
+ *
+ * @throws AccessException If called from a lazy option or normalizer
+ */
+ public function remove($optionNames)
+ {
+ if ($this->locked) {
+ throw new AccessException('Options cannot be removed from a lazy option or normalizer.');
+ }
+
+ foreach ((array) $optionNames as $option) {
+ unset($this->defined[$option], $this->defaults[$option], $this->required[$option], $this->resolved[$option]);
+ unset($this->lazy[$option], $this->normalizers[$option], $this->allowedTypes[$option], $this->allowedValues[$option], $this->info[$option]);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Removes all options.
+ *
+ * @return $this
+ *
+ * @throws AccessException If called from a lazy option or normalizer
+ */
+ public function clear()
+ {
+ if ($this->locked) {
+ throw new AccessException('Options cannot be cleared from a lazy option or normalizer.');
+ }
+
+ $this->defined = [];
+ $this->defaults = [];
+ $this->nested = [];
+ $this->required = [];
+ $this->resolved = [];
+ $this->lazy = [];
+ $this->normalizers = [];
+ $this->allowedTypes = [];
+ $this->allowedValues = [];
+ $this->deprecated = [];
+ $this->info = [];
+
+ return $this;
+ }
+
+ /**
+ * Merges options with the default values stored in the container and
+ * validates them.
+ *
+ * Exceptions are thrown if:
+ *
+ * - Undefined options are passed;
+ * - Required options are missing;
+ * - Options have invalid types;
+ * - Options have invalid values.
+ *
+ * @return array
+ *
+ * @throws UndefinedOptionsException If an option name is undefined
+ * @throws InvalidOptionsException If an option doesn't fulfill the
+ * specified validation rules
+ * @throws MissingOptionsException If a required option is missing
+ * @throws OptionDefinitionException If there is a cyclic dependency between
+ * lazy options and/or normalizers
+ * @throws NoSuchOptionException If a lazy option reads an unavailable option
+ * @throws AccessException If called from a lazy option or normalizer
+ */
+ public function resolve(array $options = [])
+ {
+ if ($this->locked) {
+ throw new AccessException('Options cannot be resolved from a lazy option or normalizer.');
+ }
+
+ // Allow this method to be called multiple times
+ $clone = clone $this;
+
+ // Make sure that no unknown options are passed
+ $diff = array_diff_key($options, $clone->defined);
+
+ if (\count($diff) > 0) {
+ ksort($clone->defined);
+ ksort($diff);
+
+ throw new UndefinedOptionsException(sprintf((\count($diff) > 1 ? 'The options "%s" do not exist.' : 'The option "%s" does not exist.').' Defined options are: "%s".', $this->formatOptions(array_keys($diff)), implode('", "', array_keys($clone->defined))));
+ }
+
+ // Override options set by the user
+ foreach ($options as $option => $value) {
+ $clone->given[$option] = true;
+ $clone->defaults[$option] = $value;
+ unset($clone->resolved[$option], $clone->lazy[$option]);
+ }
+
+ // Check whether any required option is missing
+ $diff = array_diff_key($clone->required, $clone->defaults);
+
+ if (\count($diff) > 0) {
+ ksort($diff);
+
+ throw new MissingOptionsException(sprintf(\count($diff) > 1 ? 'The required options "%s" are missing.' : 'The required option "%s" is missing.', $this->formatOptions(array_keys($diff))));
+ }
+
+ // Lock the container
+ $clone->locked = true;
+
+ // Now process the individual options. Use offsetGet(), which resolves
+ // the option itself and any options that the option depends on
+ foreach ($clone->defaults as $option => $_) {
+ $clone->offsetGet($option);
+ }
+
+ return $clone->resolved;
+ }
+
+ /**
+ * Returns the resolved value of an option.
+ *
+ * @param bool $triggerDeprecation Whether to trigger the deprecation or not (true by default)
+ *
+ * @return mixed
+ *
+ * @throws AccessException If accessing this method outside of
+ * {@link resolve()}
+ * @throws NoSuchOptionException If the option is not set
+ * @throws InvalidOptionsException If the option doesn't fulfill the
+ * specified validation rules
+ * @throws OptionDefinitionException If there is a cyclic dependency between
+ * lazy options and/or normalizers
+ */
+ #[\ReturnTypeWillChange]
+ public function offsetGet($option, bool $triggerDeprecation = true)
+ {
+ if (!$this->locked) {
+ throw new AccessException('Array access is only supported within closures of lazy options and normalizers.');
+ }
+
+ // Shortcut for resolved options
+ if (isset($this->resolved[$option]) || \array_key_exists($option, $this->resolved)) {
+ if ($triggerDeprecation && isset($this->deprecated[$option]) && (isset($this->given[$option]) || $this->calling) && \is_string($this->deprecated[$option]['message'])) {
+ trigger_deprecation($this->deprecated[$option]['package'], $this->deprecated[$option]['version'], strtr($this->deprecated[$option]['message'], ['%name%' => $option]));
+ }
+
+ return $this->resolved[$option];
+ }
+
+ // Check whether the option is set at all
+ if (!isset($this->defaults[$option]) && !\array_key_exists($option, $this->defaults)) {
+ if (!isset($this->defined[$option])) {
+ throw new NoSuchOptionException(sprintf('The option "%s" does not exist. Defined options are: "%s".', $this->formatOptions([$option]), implode('", "', array_keys($this->defined))));
+ }
+
+ throw new NoSuchOptionException(sprintf('The optional option "%s" has no value set. You should make sure it is set with "isset" before reading it.', $this->formatOptions([$option])));
+ }
+
+ $value = $this->defaults[$option];
+
+ // Resolve the option if it is a nested definition
+ if (isset($this->nested[$option])) {
+ // If the closure is already being called, we have a cyclic dependency
+ if (isset($this->calling[$option])) {
+ throw new OptionDefinitionException(sprintf('The options "%s" have a cyclic dependency.', $this->formatOptions(array_keys($this->calling))));
+ }
+
+ if (!\is_array($value)) {
+ throw new InvalidOptionsException(sprintf('The nested option "%s" with value %s is expected to be of type array, but is of type "%s".', $this->formatOptions([$option]), $this->formatValue($value), get_debug_type($value)));
+ }
+
+ // The following section must be protected from cyclic calls.
+ $this->calling[$option] = true;
+ try {
+ $resolver = new self();
+ $resolver->prototype = false;
+ $resolver->parentsOptions = $this->parentsOptions;
+ $resolver->parentsOptions[] = $option;
+ foreach ($this->nested[$option] as $closure) {
+ $closure($resolver, $this);
+ }
+
+ if ($resolver->prototype) {
+ $values = [];
+ foreach ($value as $index => $prototypeValue) {
+ if (!\is_array($prototypeValue)) {
+ throw new InvalidOptionsException(sprintf('The value of the option "%s" is expected to be of type array of array, but is of type array of "%s".', $this->formatOptions([$option]), get_debug_type($prototypeValue)));
+ }
+
+ $resolver->prototypeIndex = $index;
+ $values[$index] = $resolver->resolve($prototypeValue);
+ }
+ $value = $values;
+ } else {
+ $value = $resolver->resolve($value);
+ }
+ } finally {
+ $resolver->prototypeIndex = null;
+ unset($this->calling[$option]);
+ }
+ }
+
+ // Resolve the option if the default value is lazily evaluated
+ if (isset($this->lazy[$option])) {
+ // If the closure is already being called, we have a cyclic
+ // dependency
+ if (isset($this->calling[$option])) {
+ throw new OptionDefinitionException(sprintf('The options "%s" have a cyclic dependency.', $this->formatOptions(array_keys($this->calling))));
+ }
+
+ // The following section must be protected from cyclic
+ // calls. Set $calling for the current $option to detect a cyclic
+ // dependency
+ // BEGIN
+ $this->calling[$option] = true;
+ try {
+ foreach ($this->lazy[$option] as $closure) {
+ $value = $closure($this, $value);
+ }
+ } finally {
+ unset($this->calling[$option]);
+ }
+ // END
+ }
+
+ // Validate the type of the resolved option
+ if (isset($this->allowedTypes[$option])) {
+ $valid = true;
+ $invalidTypes = [];
+
+ foreach ($this->allowedTypes[$option] as $type) {
+ if ($valid = $this->verifyTypes($type, $value, $invalidTypes)) {
+ break;
+ }
+ }
+
+ if (!$valid) {
+ $fmtActualValue = $this->formatValue($value);
+ $fmtAllowedTypes = implode('" or "', $this->allowedTypes[$option]);
+ $fmtProvidedTypes = implode('|', array_keys($invalidTypes));
+ $allowedContainsArrayType = \count(array_filter($this->allowedTypes[$option], static function ($item) {
+ return str_ends_with($item, '[]');
+ })) > 0;
+
+ if (\is_array($value) && $allowedContainsArrayType) {
+ throw new InvalidOptionsException(sprintf('The option "%s" with value %s is expected to be of type "%s", but one of the elements is of type "%s".', $this->formatOptions([$option]), $fmtActualValue, $fmtAllowedTypes, $fmtProvidedTypes));
+ }
+
+ throw new InvalidOptionsException(sprintf('The option "%s" with value %s is expected to be of type "%s", but is of type "%s".', $this->formatOptions([$option]), $fmtActualValue, $fmtAllowedTypes, $fmtProvidedTypes));
+ }
+ }
+
+ // Validate the value of the resolved option
+ if (isset($this->allowedValues[$option])) {
+ $success = false;
+ $printableAllowedValues = [];
+
+ foreach ($this->allowedValues[$option] as $allowedValue) {
+ if ($allowedValue instanceof \Closure) {
+ if ($allowedValue($value)) {
+ $success = true;
+ break;
+ }
+
+ // Don't include closures in the exception message
+ continue;
+ }
+
+ if ($value === $allowedValue) {
+ $success = true;
+ break;
+ }
+
+ $printableAllowedValues[] = $allowedValue;
+ }
+
+ if (!$success) {
+ $message = sprintf(
+ 'The option "%s" with value %s is invalid.',
+ $option,
+ $this->formatValue($value)
+ );
+
+ if (\count($printableAllowedValues) > 0) {
+ $message .= sprintf(
+ ' Accepted values are: %s.',
+ $this->formatValues($printableAllowedValues)
+ );
+ }
+
+ if (isset($this->info[$option])) {
+ $message .= sprintf(' Info: %s.', $this->info[$option]);
+ }
+
+ throw new InvalidOptionsException($message);
+ }
+ }
+
+ // Check whether the option is deprecated
+ // and it is provided by the user or is being called from a lazy evaluation
+ if ($triggerDeprecation && isset($this->deprecated[$option]) && (isset($this->given[$option]) || ($this->calling && \is_string($this->deprecated[$option]['message'])))) {
+ $deprecation = $this->deprecated[$option];
+ $message = $this->deprecated[$option]['message'];
+
+ if ($message instanceof \Closure) {
+ // If the closure is already being called, we have a cyclic dependency
+ if (isset($this->calling[$option])) {
+ throw new OptionDefinitionException(sprintf('The options "%s" have a cyclic dependency.', $this->formatOptions(array_keys($this->calling))));
+ }
+
+ $this->calling[$option] = true;
+ try {
+ if (!\is_string($message = $message($this, $value))) {
+ throw new InvalidOptionsException(sprintf('Invalid type for deprecation message, expected string but got "%s", return an empty string to ignore.', get_debug_type($message)));
+ }
+ } finally {
+ unset($this->calling[$option]);
+ }
+ }
+
+ if ('' !== $message) {
+ trigger_deprecation($deprecation['package'], $deprecation['version'], strtr($message, ['%name%' => $option]));
+ }
+ }
+
+ // Normalize the validated option
+ if (isset($this->normalizers[$option])) {
+ // If the closure is already being called, we have a cyclic
+ // dependency
+ if (isset($this->calling[$option])) {
+ throw new OptionDefinitionException(sprintf('The options "%s" have a cyclic dependency.', $this->formatOptions(array_keys($this->calling))));
+ }
+
+ // The following section must be protected from cyclic
+ // calls. Set $calling for the current $option to detect a cyclic
+ // dependency
+ // BEGIN
+ $this->calling[$option] = true;
+ try {
+ foreach ($this->normalizers[$option] as $normalizer) {
+ $value = $normalizer($this, $value);
+ }
+ } finally {
+ unset($this->calling[$option]);
+ }
+ // END
+ }
+
+ // Mark as resolved
+ $this->resolved[$option] = $value;
+
+ return $value;
+ }
+
+ private function verifyTypes(string $type, $value, array &$invalidTypes, int $level = 0): bool
+ {
+ if (\is_array($value) && '[]' === substr($type, -2)) {
+ $type = substr($type, 0, -2);
+ $valid = true;
+
+ foreach ($value as $val) {
+ if (!$this->verifyTypes($type, $val, $invalidTypes, $level + 1)) {
+ $valid = false;
+ }
+ }
+
+ return $valid;
+ }
+
+ if (('null' === $type && null === $value) || (isset(self::VALIDATION_FUNCTIONS[$type]) ? self::VALIDATION_FUNCTIONS[$type]($value) : $value instanceof $type)) {
+ return true;
+ }
+
+ if (!$invalidTypes || $level > 0) {
+ $invalidTypes[get_debug_type($value)] = true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns whether a resolved option with the given name exists.
+ *
+ * @param string $option The option name
+ *
+ * @return bool
+ *
+ * @throws AccessException If accessing this method outside of {@link resolve()}
+ *
+ * @see \ArrayAccess::offsetExists()
+ */
+ #[\ReturnTypeWillChange]
+ public function offsetExists($option)
+ {
+ if (!$this->locked) {
+ throw new AccessException('Array access is only supported within closures of lazy options and normalizers.');
+ }
+
+ return \array_key_exists($option, $this->defaults);
+ }
+
+ /**
+ * Not supported.
+ *
+ * @return void
+ *
+ * @throws AccessException
+ */
+ #[\ReturnTypeWillChange]
+ public function offsetSet($option, $value)
+ {
+ throw new AccessException('Setting options via array access is not supported. Use setDefault() instead.');
+ }
+
+ /**
+ * Not supported.
+ *
+ * @return void
+ *
+ * @throws AccessException
+ */
+ #[\ReturnTypeWillChange]
+ public function offsetUnset($option)
+ {
+ throw new AccessException('Removing options via array access is not supported. Use remove() instead.');
+ }
+
+ /**
+ * Returns the number of set options.
+ *
+ * This may be only a subset of the defined options.
+ *
+ * @return int
+ *
+ * @throws AccessException If accessing this method outside of {@link resolve()}
+ *
+ * @see \Countable::count()
+ */
+ #[\ReturnTypeWillChange]
+ public function count()
+ {
+ if (!$this->locked) {
+ throw new AccessException('Counting is only supported within closures of lazy options and normalizers.');
+ }
+
+ return \count($this->defaults);
+ }
+
+ /**
+ * Returns a string representation of the value.
+ *
+ * This method returns the equivalent PHP tokens for most scalar types
+ * (i.e. "false" for false, "1" for 1 etc.). Strings are always wrapped
+ * in double quotes (").
+ *
+ * @param mixed $value The value to format as string
+ */
+ private function formatValue($value): string
+ {
+ if (\is_object($value)) {
+ return \get_class($value);
+ }
+
+ if (\is_array($value)) {
+ return 'array';
+ }
+
+ if (\is_string($value)) {
+ return '"'.$value.'"';
+ }
+
+ if (\is_resource($value)) {
+ return 'resource';
+ }
+
+ if (null === $value) {
+ return 'null';
+ }
+
+ if (false === $value) {
+ return 'false';
+ }
+
+ if (true === $value) {
+ return 'true';
+ }
+
+ return (string) $value;
+ }
+
+ /**
+ * Returns a string representation of a list of values.
+ *
+ * Each of the values is converted to a string using
+ * {@link formatValue()}. The values are then concatenated with commas.
+ *
+ * @see formatValue()
+ */
+ private function formatValues(array $values): string
+ {
+ foreach ($values as $key => $value) {
+ $values[$key] = $this->formatValue($value);
+ }
+
+ return implode(', ', $values);
+ }
+
+ private function formatOptions(array $options): string
+ {
+ if ($this->parentsOptions) {
+ $prefix = array_shift($this->parentsOptions);
+ if ($this->parentsOptions) {
+ $prefix .= sprintf('[%s]', implode('][', $this->parentsOptions));
+ }
+
+ if ($this->prototype && null !== $this->prototypeIndex) {
+ $prefix .= sprintf('[%s]', $this->prototypeIndex);
+ }
+
+ $options = array_map(static function (string $option) use ($prefix): string {
+ return sprintf('%s[%s]', $prefix, $option);
+ }, $options);
+ }
+
+ return implode('", "', $options);
+ }
+
+ private function getParameterClassName(\ReflectionParameter $parameter): ?string
+ {
+ if (!($type = $parameter->getType()) instanceof \ReflectionNamedType || $type->isBuiltin()) {
+ return null;
+ }
+
+ return $type->getName();
+ }
+}
diff --git a/vendor/symfony/options-resolver/README.md b/vendor/symfony/options-resolver/README.md
new file mode 100644
index 000000000..c63b9005e
--- /dev/null
+++ b/vendor/symfony/options-resolver/README.md
@@ -0,0 +1,15 @@
+OptionsResolver Component
+=========================
+
+The OptionsResolver component is `array_replace` on steroids. It allows you to
+create an options system with required options, defaults, validation (type,
+value), normalization and more.
+
+Resources
+---------
+
+ * [Documentation](https://symfony.com/doc/current/components/options_resolver.html)
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/symfony/issues) and
+ [send Pull Requests](https://github.com/symfony/symfony/pulls)
+ in the [main Symfony repository](https://github.com/symfony/symfony)
diff --git a/vendor/symfony/options-resolver/composer.json b/vendor/symfony/options-resolver/composer.json
new file mode 100644
index 000000000..a38d1bd04
--- /dev/null
+++ b/vendor/symfony/options-resolver/composer.json
@@ -0,0 +1,31 @@
+{
+ "name": "symfony/options-resolver",
+ "type": "library",
+ "description": "Provides an improved replacement for the array_replace PHP function",
+ "keywords": ["options", "config", "configuration"],
+ "homepage": "https://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/deprecation-contracts": "^2.1|^3",
+ "symfony/polyfill-php73": "~1.0",
+ "symfony/polyfill-php80": "^1.16"
+ },
+ "autoload": {
+ "psr-4": { "Symfony\\Component\\OptionsResolver\\": "" },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "minimum-stability": "dev"
+}
diff --git a/vendor/symfony/service-contracts/Attribute/Required.php b/vendor/symfony/service-contracts/Attribute/Required.php
new file mode 100644
index 000000000..9df851189
--- /dev/null
+++ b/vendor/symfony/service-contracts/Attribute/Required.php
@@ -0,0 +1,25 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Contracts\Service\Attribute;
+
+/**
+ * A required dependency.
+ *
+ * This attribute indicates that a property holds a required dependency. The annotated property or method should be
+ * considered during the instantiation process of the containing class.
+ *
+ * @author Alexander M. Turek
+ */
+#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY)]
+final class Required
+{
+}
diff --git a/vendor/symfony/service-contracts/Attribute/SubscribedService.php b/vendor/symfony/service-contracts/Attribute/SubscribedService.php
new file mode 100644
index 000000000..10d1bc38e
--- /dev/null
+++ b/vendor/symfony/service-contracts/Attribute/SubscribedService.php
@@ -0,0 +1,33 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Contracts\Service\Attribute;
+
+use Symfony\Contracts\Service\ServiceSubscriberTrait;
+
+/**
+ * Use with {@see ServiceSubscriberTrait} to mark a method's return type
+ * as a subscribed service.
+ *
+ * @author Kevin Bond
+ */
+#[\Attribute(\Attribute::TARGET_METHOD)]
+final class SubscribedService
+{
+ /**
+ * @param string|null $key The key to use for the service
+ * If null, use "ClassName::methodName"
+ */
+ public function __construct(
+ public ?string $key = null
+ ) {
+ }
+}
diff --git a/vendor/symfony/service-contracts/CHANGELOG.md b/vendor/symfony/service-contracts/CHANGELOG.md
new file mode 100644
index 000000000..7932e2613
--- /dev/null
+++ b/vendor/symfony/service-contracts/CHANGELOG.md
@@ -0,0 +1,5 @@
+CHANGELOG
+=========
+
+The changelog is maintained for all Symfony contracts at the following URL:
+https://github.com/symfony/contracts/blob/main/CHANGELOG.md
diff --git a/vendor/symfony/service-contracts/ServiceLocatorTrait.php b/vendor/symfony/service-contracts/ServiceLocatorTrait.php
index da797edca..74dfa4362 100644
--- a/vendor/symfony/service-contracts/ServiceLocatorTrait.php
+++ b/vendor/symfony/service-contracts/ServiceLocatorTrait.php
@@ -43,7 +43,7 @@ trait ServiceLocatorTrait
*
* @return bool
*/
- public function has($id)
+ public function has(string $id)
{
return isset($this->factories[$id]);
}
@@ -53,7 +53,7 @@ trait ServiceLocatorTrait
*
* @return mixed
*/
- public function get($id)
+ public function get(string $id)
{
if (!isset($this->factories[$id])) {
throw $this->createNotFoundException($id);
diff --git a/vendor/symfony/service-contracts/ServiceSubscriberTrait.php b/vendor/symfony/service-contracts/ServiceSubscriberTrait.php
index 48c610ab1..16e3eb2c1 100644
--- a/vendor/symfony/service-contracts/ServiceSubscriberTrait.php
+++ b/vendor/symfony/service-contracts/ServiceSubscriberTrait.php
@@ -12,10 +12,11 @@
namespace Symfony\Contracts\Service;
use Psr\Container\ContainerInterface;
+use Symfony\Contracts\Service\Attribute\SubscribedService;
/**
* Implementation of ServiceSubscriberInterface that determines subscribed services from
- * private method return types. Service ids are available as "ClassName::methodName".
+ * method return types. Service ids are available as "ClassName::methodName".
*
* @author Kevin Bond
*/
@@ -30,25 +31,61 @@ trait ServiceSubscriberTrait
public static function getSubscribedServices(): array
{
$services = method_exists(get_parent_class(self::class) ?: '', __FUNCTION__) ? parent::getSubscribedServices() : [];
+ $attributeOptIn = false;
- foreach ((new \ReflectionClass(self::class))->getMethods() as $method) {
- if ($method->isStatic() || $method->isAbstract() || $method->isGenerator() || $method->isInternal() || $method->getNumberOfRequiredParameters()) {
- continue;
+ if (\PHP_VERSION_ID >= 80000) {
+ foreach ((new \ReflectionClass(self::class))->getMethods() as $method) {
+ if (self::class !== $method->getDeclaringClass()->name) {
+ continue;
+ }
+
+ if (!$attribute = $method->getAttributes(SubscribedService::class)[0] ?? null) {
+ continue;
+ }
+
+ if ($method->isStatic() || $method->isAbstract() || $method->isGenerator() || $method->isInternal() || $method->getNumberOfRequiredParameters()) {
+ throw new \LogicException(sprintf('Cannot use "%s" on method "%s::%s()" (can only be used on non-static, non-abstract methods with no parameters).', SubscribedService::class, self::class, $method->name));
+ }
+
+ if (!$returnType = $method->getReturnType()) {
+ throw new \LogicException(sprintf('Cannot use "%s" on methods without a return type in "%s::%s()".', SubscribedService::class, $method->name, self::class));
+ }
+
+ $serviceId = $returnType instanceof \ReflectionNamedType ? $returnType->getName() : (string) $returnType;
+
+ if ($returnType->allowsNull()) {
+ $serviceId = '?'.$serviceId;
+ }
+
+ $services[$attribute->newInstance()->key ?? self::class.'::'.$method->name] = $serviceId;
+ $attributeOptIn = true;
}
+ }
- if (self::class !== $method->getDeclaringClass()->name) {
- continue;
+ if (!$attributeOptIn) {
+ foreach ((new \ReflectionClass(self::class))->getMethods() as $method) {
+ if ($method->isStatic() || $method->isAbstract() || $method->isGenerator() || $method->isInternal() || $method->getNumberOfRequiredParameters()) {
+ continue;
+ }
+
+ if (self::class !== $method->getDeclaringClass()->name) {
+ continue;
+ }
+
+ if (!($returnType = $method->getReturnType()) instanceof \ReflectionNamedType) {
+ continue;
+ }
+
+ if ($returnType->isBuiltin()) {
+ continue;
+ }
+
+ if (\PHP_VERSION_ID >= 80000) {
+ trigger_deprecation('symfony/service-contracts', '2.5', 'Using "%s" in "%s" without using the "%s" attribute on any method is deprecated.', ServiceSubscriberTrait::class, self::class, SubscribedService::class);
+ }
+
+ $services[self::class.'::'.$method->name] = '?'.($returnType instanceof \ReflectionNamedType ? $returnType->getName() : $returnType);
}
-
- if (!($returnType = $method->getReturnType()) instanceof \ReflectionNamedType) {
- continue;
- }
-
- if ($returnType->isBuiltin()) {
- continue;
- }
-
- $services[self::class.'::'.$method->name] = '?'.$returnType->getName();
}
return $services;
diff --git a/vendor/symfony/service-contracts/composer.json b/vendor/symfony/service-contracts/composer.json
index e3bf920ca..f05863701 100644
--- a/vendor/symfony/service-contracts/composer.json
+++ b/vendor/symfony/service-contracts/composer.json
@@ -16,8 +16,12 @@
}
],
"require": {
- "php": ">=7.1.3",
- "psr/container": "^1.0"
+ "php": ">=7.2.5",
+ "psr/container": "^1.1",
+ "symfony/deprecation-contracts": "^2.1|^3"
+ },
+ "conflict": {
+ "ext-psr": "<1.1|>=2"
},
"suggest": {
"symfony/service-implementation": ""
@@ -28,7 +32,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-main": "1.1-dev"
+ "dev-main": "2.5-dev"
},
"thanks": {
"name": "symfony/contracts",
diff --git a/vendor/symfony/translation-contracts/CHANGELOG.md b/vendor/symfony/translation-contracts/CHANGELOG.md
new file mode 100644
index 000000000..7932e2613
--- /dev/null
+++ b/vendor/symfony/translation-contracts/CHANGELOG.md
@@ -0,0 +1,5 @@
+CHANGELOG
+=========
+
+The changelog is maintained for all Symfony contracts at the following URL:
+https://github.com/symfony/contracts/blob/main/CHANGELOG.md
diff --git a/vendor/symfony/translation-contracts/LocaleAwareInterface.php b/vendor/symfony/translation-contracts/LocaleAwareInterface.php
index dbd8894fe..693f92ba9 100644
--- a/vendor/symfony/translation-contracts/LocaleAwareInterface.php
+++ b/vendor/symfony/translation-contracts/LocaleAwareInterface.php
@@ -20,12 +20,12 @@ interface LocaleAwareInterface
*
* @throws \InvalidArgumentException If the locale contains invalid characters
*/
- public function setLocale($locale);
+ public function setLocale(string $locale);
/**
* Returns the current locale.
*
- * @return string The locale
+ * @return string
*/
public function getLocale();
}
diff --git a/vendor/symfony/translation-contracts/Test/TranslatorTest.php b/vendor/symfony/translation-contracts/Test/TranslatorTest.php
index 83551cb84..a3e9b20af 100644
--- a/vendor/symfony/translation-contracts/Test/TranslatorTest.php
+++ b/vendor/symfony/translation-contracts/Test/TranslatorTest.php
@@ -74,6 +74,8 @@ class TranslatorTest extends TestCase
}
/**
+ * @requires extension intl
+ *
* @dataProvider getTransChoiceTests
*/
public function testTransChoiceWithDefaultLocale($expected, $id, $number)
@@ -165,11 +167,11 @@ class TranslatorTest extends TestCase
/**
* @dataProvider getChooseTests
*/
- public function testChoose($expected, $id, $number)
+ public function testChoose($expected, $id, $number, $locale = null)
{
$translator = $this->getTranslator();
- $this->assertEquals($expected, $translator->trans($id, ['%count%' => $number]));
+ $this->assertEquals($expected, $translator->trans($id, ['%count%' => $number], null, $locale));
}
public function testReturnMessageIfExactlyOneStandardRuleIsGiven()
@@ -278,6 +280,18 @@ class TranslatorTest extends TestCase
['', '|', 1],
// Empty plural set (3 plural forms) from a .PO file
['', '||', 1],
+
+ // Floating values
+ ['1.5 liters', '%count% liter|%count% liters', 1.5],
+ ['1.5 litre', '%count% litre|%count% litres', 1.5, 'fr'],
+
+ // Negative values
+ ['-1 degree', '%count% degree|%count% degrees', -1],
+ ['-1 degré', '%count% degré|%count% degrés', -1],
+ ['-1.5 degrees', '%count% degree|%count% degrees', -1.5],
+ ['-1.5 degré', '%count% degré|%count% degrés', -1.5, 'fr'],
+ ['-2 degrees', '%count% degree|%count% degrees', -2],
+ ['-2 degrés', '%count% degré|%count% degrés', -2],
];
}
diff --git a/vendor/symfony/translation-contracts/TranslatableInterface.php b/vendor/symfony/translation-contracts/TranslatableInterface.php
new file mode 100644
index 000000000..47fd6fa02
--- /dev/null
+++ b/vendor/symfony/translation-contracts/TranslatableInterface.php
@@ -0,0 +1,20 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Contracts\Translation;
+
+/**
+ * @author Nicolas Grekas
+ */
+interface TranslatableInterface
+{
+ public function trans(TranslatorInterface $translator, string $locale = null): string;
+}
diff --git a/vendor/symfony/translation-contracts/TranslatorInterface.php b/vendor/symfony/translation-contracts/TranslatorInterface.php
index d86763737..77b7a9c58 100644
--- a/vendor/symfony/translation-contracts/TranslatorInterface.php
+++ b/vendor/symfony/translation-contracts/TranslatorInterface.php
@@ -13,6 +13,8 @@ namespace Symfony\Contracts\Translation;
/**
* @author Fabien Potencier
+ *
+ * @method string getLocale() Returns the default locale
*/
interface TranslatorInterface
{
@@ -57,9 +59,9 @@ interface TranslatorInterface
* @param string|null $domain The domain for the message or null to use the default
* @param string|null $locale The locale or null to use the default
*
- * @return string The translated string
+ * @return string
*
* @throws \InvalidArgumentException If the locale contains invalid characters
*/
- public function trans($id, array $parameters = [], $domain = null, $locale = null);
+ public function trans(string $id, array $parameters = [], string $domain = null, string $locale = null);
}
diff --git a/vendor/symfony/translation-contracts/TranslatorTrait.php b/vendor/symfony/translation-contracts/TranslatorTrait.php
index 92a6a0021..405ce8d70 100644
--- a/vendor/symfony/translation-contracts/TranslatorTrait.php
+++ b/vendor/symfony/translation-contracts/TranslatorTrait.php
@@ -25,13 +25,15 @@ trait TranslatorTrait
/**
* {@inheritdoc}
*/
- public function setLocale($locale)
+ public function setLocale(string $locale)
{
- $this->locale = (string) $locale;
+ $this->locale = $locale;
}
/**
* {@inheritdoc}
+ *
+ * @return string
*/
public function getLocale()
{
@@ -41,9 +43,9 @@ trait TranslatorTrait
/**
* {@inheritdoc}
*/
- public function trans($id, array $parameters = [], $domain = null, $locale = null)
+ public function trans(?string $id, array $parameters = [], string $domain = null, string $locale = null): string
{
- if ('' === $id = (string) $id) {
+ if (null === $id || '' === $id) {
return '';
}
@@ -52,7 +54,7 @@ trait TranslatorTrait
}
$number = (float) $parameters['%count%'];
- $locale = (string) $locale ?: $this->getLocale();
+ $locale = $locale ?: $this->getLocale();
$parts = [];
if (preg_match('/^\|++$/', $id)) {
diff --git a/vendor/symfony/translation-contracts/composer.json b/vendor/symfony/translation-contracts/composer.json
index 8fe4b2094..65fe243a4 100644
--- a/vendor/symfony/translation-contracts/composer.json
+++ b/vendor/symfony/translation-contracts/composer.json
@@ -16,7 +16,7 @@
}
],
"require": {
- "php": ">=7.1.3"
+ "php": ">=7.2.5"
},
"suggest": {
"symfony/translation-implementation": ""
@@ -27,7 +27,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-main": "1.1-dev"
+ "dev-main": "2.5-dev"
},
"thanks": {
"name": "symfony/contracts",
diff --git a/vendor/tijsverkoyen/css-to-inline-styles/src/CssToInlineStyles.php b/vendor/tijsverkoyen/css-to-inline-styles/src/CssToInlineStyles.php
index 6efc06f39..e40ae25df 100644
--- a/vendor/tijsverkoyen/css-to-inline-styles/src/CssToInlineStyles.php
+++ b/vendor/tijsverkoyen/css-to-inline-styles/src/CssToInlineStyles.php
@@ -113,7 +113,7 @@ class CssToInlineStyles
{
$document = new \DOMDocument('1.0', 'UTF-8');
$internalErrors = libxml_use_internal_errors(true);
- $document->loadHTML(mb_encode_numericentity($html, [0x80, 0xFFFF, 0, 0xFFFF], 'UTF-8'));
+ $document->loadHTML(mb_encode_numericentity($html, [0x80, 0x10FFFF, 0, 0x1FFFFF], 'UTF-8'));
libxml_use_internal_errors($internalErrors);
$document->formatOutput = true;
diff --git a/vendor/twig/twig/.github/dependabot.yml b/vendor/twig/twig/.github/dependabot.yml
new file mode 100644
index 000000000..5ace4600a
--- /dev/null
+++ b/vendor/twig/twig/.github/dependabot.yml
@@ -0,0 +1,6 @@
+version: 2
+updates:
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "weekly"
diff --git a/vendor/twig/twig/.github/workflows/ci.yml b/vendor/twig/twig/.github/workflows/ci.yml
index 88aebc164..3f49259ca 100644
--- a/vendor/twig/twig/.github/workflows/ci.yml
+++ b/vendor/twig/twig/.github/workflows/ci.yml
@@ -29,11 +29,12 @@ jobs:
- '7.4'
- '8.0'
- '8.1'
+ - '8.2'
experimental: [false]
steps:
- name: "Checkout code"
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: "Install PHP with extensions"
uses: shivammathur/setup-php@v2
@@ -74,6 +75,7 @@ jobs:
- '7.4'
- '8.0'
- '8.1'
+ - '8.2'
extension:
- 'extra/cssinliner-extra'
- 'extra/html-extra'
@@ -86,7 +88,7 @@ jobs:
steps:
- name: "Checkout code"
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: "Install PHP with extensions"
uses: shivammathur/setup-php@v2
@@ -131,7 +133,7 @@ jobs:
steps:
- name: "Checkout code"
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: "Install PHP with extensions"
uses: shivammathur/setup-php@v2
diff --git a/vendor/twig/twig/.github/workflows/documentation.yml b/vendor/twig/twig/.github/workflows/documentation.yml
index ee83b5887..f2f46fc6d 100644
--- a/vendor/twig/twig/.github/workflows/documentation.yml
+++ b/vendor/twig/twig/.github/workflows/documentation.yml
@@ -18,22 +18,22 @@ jobs:
steps:
- name: "Checkout code"
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: "Set-up PHP"
uses: shivammathur/setup-php@v2
with:
- php-version: 8.1
+ php-version: 8.2
coverage: none
tools: "composer:v2"
- name: Get composer cache directory
id: composercache
working-directory: doc/_build
- run: echo "::set-output name=dir::$(composer config cache-files-dir)"
+ run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache dependencies
- uses: actions/cache@v2
+ uses: actions/cache@v3
with:
path: ${{ steps.composercache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
@@ -54,7 +54,7 @@ jobs:
steps:
- name: "Checkout code"
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: "Run DOCtor-RST"
uses: docker://oskarstark/doctor-rst
diff --git a/vendor/twig/twig/CHANGELOG b/vendor/twig/twig/CHANGELOG
index 51712223b..db87b2360 100644
--- a/vendor/twig/twig/CHANGELOG
+++ b/vendor/twig/twig/CHANGELOG
@@ -1,3 +1,9 @@
+# 2.15.4 (2022-12-27)
+
+ * Fix optimizing closures callbacks
+ * Add a better exception when getting an undefined constant via `constant`
+ * Fix `if` nodes when outside of a block and with an empty body
+
# 2.15.3 (2022-09-28)
* Fix a security issue on filesystem loader (possibility to load a template outside a configured directory)
diff --git a/vendor/twig/twig/src/Environment.php b/vendor/twig/twig/src/Environment.php
index 13ce511f4..96f725106 100644
--- a/vendor/twig/twig/src/Environment.php
+++ b/vendor/twig/twig/src/Environment.php
@@ -38,11 +38,11 @@ use Twig\TokenParser\TokenParserInterface;
*/
class Environment
{
- public const VERSION = '2.15.3';
- public const VERSION_ID = 21503;
+ public const VERSION = '2.15.4';
+ public const VERSION_ID = 21504;
public const MAJOR_VERSION = 2;
public const MINOR_VERSION = 15;
- public const RELEASE_VERSION = 3;
+ public const RELEASE_VERSION = 4;
public const EXTRA_VERSION = '';
private $charset;
diff --git a/vendor/twig/twig/src/Extension/CoreExtension.php b/vendor/twig/twig/src/Extension/CoreExtension.php
index 6ac361081..5c4087ec2 100644
--- a/vendor/twig/twig/src/Extension/CoreExtension.php
+++ b/vendor/twig/twig/src/Extension/CoreExtension.php
@@ -1329,6 +1329,10 @@ function twig_constant($constant, $object = null)
$constant = \get_class($object).'::'.$constant;
}
+ if (!\defined($constant)) {
+ throw new RuntimeError(sprintf('Constant "%s" is undefined.', $constant));
+ }
+
return \constant($constant);
}
diff --git a/vendor/twig/twig/src/Node/Expression/CallExpression.php b/vendor/twig/twig/src/Node/Expression/CallExpression.php
index 79e9defdf..aeb38c42f 100644
--- a/vendor/twig/twig/src/Node/Expression/CallExpression.php
+++ b/vendor/twig/twig/src/Node/Expression/CallExpression.php
@@ -304,7 +304,9 @@ abstract class CallExpression extends AbstractExpression
if ($object = $r->getClosureThis()) {
$callable = [$object, $r->name];
$callableName = (\function_exists('get_debug_type') ? get_debug_type($object) : \get_class($object)).'::'.$r->name;
- } elseif ($class = $r->getClosureScopeClass()) {
+ } elseif (\PHP_VERSION_ID >= 80111 && $class = $r->getClosureCalledClass()) {
+ $callableName = $class->name.'::'.$r->name;
+ } elseif (\PHP_VERSION_ID < 80111 && $class = $r->getClosureScopeClass()) {
$callableName = (\is_array($callable) ? $callable[0] : $class->name).'::'.$r->name;
} else {
$callable = $callableName = $r->name;
diff --git a/vendor/twig/twig/src/Node/IfNode.php b/vendor/twig/twig/src/Node/IfNode.php
index 8ba23ddb6..e74ca523b 100644
--- a/vendor/twig/twig/src/Node/IfNode.php
+++ b/vendor/twig/twig/src/Node/IfNode.php
@@ -50,8 +50,11 @@ class IfNode extends Node
->subcompile($this->getNode('tests')->getNode($i))
->raw(") {\n")
->indent()
- ->subcompile($this->getNode('tests')->getNode($i + 1))
;
+ // The node might not exists if the content is empty
+ if ($this->getNode('tests')->hasNode($i + 1)) {
+ $compiler->subcompile($this->getNode('tests')->getNode($i + 1));
+ }
}
if ($this->hasNode('else')) {
diff --git a/vendor/wikimedia/less.php/.github/workflows/php.yml b/vendor/wikimedia/less.php/.github/workflows/php.yml
deleted file mode 100644
index 14be2ca0a..000000000
--- a/vendor/wikimedia/less.php/.github/workflows/php.yml
+++ /dev/null
@@ -1,33 +0,0 @@
-name: PHP Composer
-
-on: [push,pull_request]
-
-jobs:
- build:
- name: Test PHP ${{ matrix.php-version }}
-
- strategy:
- matrix:
- php-version: ['7.1', '7.2', '7.3', '7.4']
-
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout
- uses: actions/checkout@v1
-
- - name: Setup PHP, with composer and extensions
- uses: shivammathur/setup-php@master
- with:
- php-version: ${{ matrix.php-version }}
- extension-csv: dom, mbstring
- # coverage: xdebug
-
- - name: Validate composer.json and composer.lock
- run: composer validate
-
- - name: Install dependencies
- run: composer install --prefer-dist --no-progress --no-suggest
-
- - name: Run test suite
- run: composer run-script test
diff --git a/vendor/wikimedia/less.php/API.md b/vendor/wikimedia/less.php/API.md
new file mode 100644
index 000000000..010c90f85
--- /dev/null
+++ b/vendor/wikimedia/less.php/API.md
@@ -0,0 +1,197 @@
+Less.php API
+========
+
+## Basic use
+
+#### Parse strings
+
+```php
+$parser = new Less_Parser();
+$parser->parse( '@color: #36c; .link { color: @color; } a { color: @color; }' );
+$css = $parser->getCss();
+```
+
+#### Parse files
+
+The `parseFile()` function takes two parameters:
+
+* The absolute path to a `.less` file.
+* The base URL for any relative image or CSS references in the `.less` file,
+ typically the same directory that contains the `.less` file or a public equivalent.
+
+```php
+$parser = new Less_Parser();
+$parser->parseFile( '/var/www/mysite/bootstrap.less', 'https://example.org/mysite/' );
+$css = $parser->getCss();
+```
+
+#### Handle invalid syntax
+
+An exception will be thrown if the compiler encounters invalid LESS.
+
+```php
+try{
+ $parser = new Less_Parser();
+ $parser->parseFile( '/var/www/mysite/bootstrap.less', 'https://example.org/mysite/' );
+ $css = $parser->getCss();
+} catch (Exception $e) {
+ echo $e->getMessage();
+}
+```
+
+#### Parse multiple inputs
+
+Less.php can parse multiple input sources (e.g. files and/or strings) and generate a single CSS output.
+
+```php
+$parser = new Less_Parser();
+$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' );
+$parser->parse( '@color: #36c; .link { color: @color; } a { color: @color; }' );
+$css = $parser->getCss();
+```
+
+#### Metadata
+
+Less.php keeps track of which `.less` files have been parsed, i.e. the input
+file(s) and any direct and indirect imports.
+
+```php
+$parser = new Less_Parser();
+$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' );
+$css = $parser->getCss();
+$files = $parser->AllParsedFiles();
+```
+
+#### Compress output
+
+You can tell Less.php to remove comments and whitespace to generate minified CSS.
+
+```php
+$options = [ 'compress' => true ];
+$parser = new Less_Parser( $options );
+$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' );
+$css = $parser->getCss();
+```
+
+#### Get variables
+
+You can use the `getVariables()` method to get an all variables defined and
+their value in an associative array. Note that the input must be compiled first
+by calling `getCss()`.
+
+```php
+$parser = new Less_Parser;
+$parser->parseFile( '/var/www/mysite/bootstrap.less');
+$css = $parser->getCss();
+$variables = $parser->getVariables();
+
+```
+
+#### Set variables
+
+Use the `ModifyVars()` method to inject additional variables, i.e. custom values
+computed or accessed from your PHP code.
+
+```php
+$parser = new Less_Parser();
+$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' );
+$parser->ModifyVars( [ 'font-size-base' => '16px' ] );
+$css = $parser->getCss();
+```
+
+#### Import directories
+
+By default, Less.php will look for imported files in the directory of the file passed to `parseFile()`.
+
+If you use `parse()`, or if need to enable additional import directories, you can specify these by
+calling `SetImportDirs()`.
+
+```php
+$directories = [ '/var/www/mysite/bootstrap/' => '/mysite/bootstrap/' ];
+$parser = new Less_Parser();
+$parser->SetImportDirs( $directories );
+$parser->parseFile( '/var/www/mysite/theme.less', '/mysite/' );
+$css = $parser->getCss();
+```
+
+## Caching
+
+Compiling LESS code into CSS can be a time-consuming process. It is recommended to cache your results.
+
+#### Basic cache
+
+Use the `Less_Cache` class to save and reuse the results of compiling LESS files.
+This class will check the modified time and size of each LESS file (including imported files) and
+either re-use or re-generate the CSS output accordingly.
+
+The cache files are determinstically named, based on the full list of referenced LESS files and the metadata (file path, file mtime, file size) of each file. This means that each time a change is made, a different cache filename is used.
+
+```php
+$lessFiles = [ '/var/www/mysite/bootstrap.less' => '/mysite/' ];
+$options = [ 'cache_dir' => '/var/www/writable_folder' ];
+$cssOutputFile = Less_Cache::Get( $lessFiles, $options );
+$css = file_get_contents( '/var/www/writable_folder/' . $cssOutputFile );
+```
+
+#### Caching with variables
+
+Passing custom variables to `Less_Cache::Get()`:
+
+```php
+$lessFiles = [ '/var/www/mysite/bootstrap.less' => '/mysite/' ];
+$options = [ 'cache_dir' => '/var/www/writable_folder' ];
+$variables = [ 'width' => '100px' ];
+$cssOutputFile = Less_Cache::Get( $lessFiles, $options, $variables );
+$css = file_get_contents( '/var/www/writable_folder/' . $cssOutputFile );
+```
+
+#### Incremental caching
+
+In addition to the whole-output caching described above, Less.php also has the ability to keep an internal cache which allows re-parses to be faster by effectively only re-compiling portions that have changed.
+
+## Source maps
+
+Less.php supports v3 sourcemaps.
+
+#### Inline
+
+The sourcemap will be appended to the generated CSS file.
+
+```php
+$options = [ 'sourceMap' => true ];
+$parser = new Less_Parser($options);
+$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' );
+$css = $parser->getCss();
+```
+
+#### Saving to map file
+
+```php
+$options = [
+ 'sourceMap' => true,
+ 'sourceMapWriteTo' => '/var/www/mysite/writable_folder/filename.map',
+ 'sourceMapURL' => '/mysite/writable_folder/filename.map',
+];
+$parser = new Less_Parser($options);
+$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' );
+$css = $parser->getCss();
+```
+
+## Command line
+
+An additional script has been included to use the Less.php compiler from the command line.
+In its simplest invocation, you specify an input file and the compiled CSS is written to standard out:
+
+```
+$ lessc input.less > output.css
+```
+
+By using the `-w` flag you can watch a specified input file and have it compile as needed to the output file:
+
+```
+$ lessc -w input.less output.css
+```
+
+Errors from watch mode are written to standard out.
+
+For more information, run `lessc --help`
diff --git a/vendor/wikimedia/less.php/CHANGES.md b/vendor/wikimedia/less.php/CHANGES.md
index 0164bd1c7..3334aeb48 100644
--- a/vendor/wikimedia/less.php/CHANGES.md
+++ b/vendor/wikimedia/less.php/CHANGES.md
@@ -1,55 +1,91 @@
-# 2.0.0
-- [All Changes](https://github.com/wikimedia/less.php/compare/1.8.2...2.0.0)
-- Relax PHP requirement down to 7.1, from 7.2.9 (Franz Liedke)
-- Reflect recent breaking changes properly with the semantic versioning (James Forrester)
+# Changelog
-# 1.8.2
-- [All Changes](https://github.com/wikimedia/less.php/compare/1.8.1...1.8.2)
-- Require PHP 7.2.9+, up from 5.3+ (James Forrester)
-- Release: Update Version.php with the current release ID (COBadger)
-- Fix access array offset on value of type null (Michele Locati)
-- Fixed test suite on PHP 7.4 (Sergei Morozov)
-- docs: Fix 1.8.1 "All changes" link (Timo Tijhof)
+## 3.2.1
-# 1.8.1
-- [All Changes](https://github.com/wikimedia/less.php/compare/v1.8.0...1.8.1)
-- Another PHP 7.3 compatibility tweak
+* [All changes](https://gerrit.wikimedia.org/g/mediawiki/libs/less.php/+log/v3.2.1)
+* Tree_Ruleset: Fix support for nested parent selectors (Timo Tijhof) [T204816](https://phabricator.wikimedia.org/T204816)
+* Fix ParseError when interpolating variable after colon in selector (Timo Tijhof) [T327163](https://phabricator.wikimedia.org/T327163)
+* Functions: Fix "Undefined property" warning on bad minmax arg
+* Tree_Call: Include previous exception when catching functions (Robert Frunzke)
-# 1.8.0
-- [All Changes](https://github.com/Asenar/less.php/compare/v1.7.0.13...v1.8.0)
-- Wikimedia fork
-- Supports up to PHP 7.3
-- No longer tested against PHP 5, though it's still remains allowed in `composer.json` for HHVM compatibility
-- Switched to [semantic versioning](https://semver.org/), hence version numbers now use 3 digits
+## 3.2.0
-# 1.7.0.13
- - [All Changes](https://github.com/Asenar/less.php/compare/v1.7.0.12...v1.7.0.13)
- - Fix composer.json (PSR-4 was invalid)
+* [All changes](https://github.com/wikimedia/less.php/compare/v3.1.0...v3.2.0)
+* Fix "Implicit conversion" PHP 8.1 warnings (Ayokunle Odusan)
+* Fix "Creation of dynamic property" PHP 8.2 warnings (Bas Couwenberg)
+* Fix "Creation of dynamic property" PHP 8.2 warnings (Rajesh Kumar)
+* Tree_Url: Add support for "Url" type to `Parser::getVariables()` (ciroarcadio) [#51](https://github.com/wikimedia/less.php/pull/51)
+* Tree_Import: Add support for importing URLs without file extension (Timo Tijhof) [#27](https://github.com/wikimedia/less.php/issues/27)
-# 1.7.0.12
- - [All Changes](https://github.com/Asenar/less.php/compare/v1.7.0.11...v1.7.0.12)
- - set bin/lessc bit executable
- - Add 'gettingVariables' method in Less_Parser
+## 3.1.0
-# 1.7.0.11
- - [All Changes](https://github.com/Asenar/less.php/compare/v1.7.0.10...v1.7.0.11)
- - Fix realpath issue (windows)
- - Set Less_Tree_Call property back to public ( Fix 258 266 267 issues from oyejorge/less.php)
+* [All changes](https://github.com/wikimedia/less.php/compare/v3.0.0...v3.1.0)
+* Add PHP 8.0 support: Drop use of curly braces for sub-string eval (James D. Forrester)
+* Make `Directive::__construct` $rules arg optional (fix PHP 7.4 warning) (Sam Reed)
+* ProcessExtends: Improve performance by using a map for selectors and parents (Andrey Legayev)
-# 1.7.0.10
+## 3.0.0
- - [All Changes](https://github.com/oyejorge/less.php/compare/v1.7.0.9...v1.7.10)
- - Add indentation option
- - Add 'optional' modifier for @import
- - fix $color in Exception messages
- - don't use set_time_limit when running cli
- - take relative-url into account when building the cache filename
- - urlArgs should be string no array()
- - add bug-report fixtures [#6dc898f](https://github.com/oyejorge/less.php/commit/6dc898f5d75b447464906bdf19d79c2e19d95e33)
- - fix #269, missing on NameValue type [#a8dac63](https://github.com/oyejorge/less.php/commit/a8dac63d93fb941c54fb78b12588abf635747c1b)
+* [All changes](https://github.com/wikimedia/less.php/compare/v2.0.0...v3.0.0)
+* Raise PHP requirement from 7.1 to 7.2.9 (James Forrester)
-# 1.7.0.9
+## 2.0.0
- - [All Changes](https://github.com/oyejorge/less.php/compare/v1.7.0.8...v1.7.0.9)
- - Remove space at beginning of Version.php
- - Revert require() paths in test interface
+* [All changes](https://github.com/wikimedia/less.php/compare/v1.8.2...v2.0.0)
+* Relax PHP requirement down to 7.1, from 7.2.9 (Franz Liedke)
+* Reflect recent breaking changes properly with the semantic versioning (James Forrester)
+
+## 1.8.2
+
+* [All changes](https://github.com/wikimedia/less.php/compare/v1.8.1...v1.8.2)
+* Require PHP 7.2.9+, up from 5.3+ (James Forrester)
+* release: Update Version.php with the current release ID (COBadger)
+* Fix access array offset on value of type null (Michele Locati)
+* Fix test suite on PHP 7.4 (Sergei Morozov)
+
+## 1.8.1
+
+* [All changes](https://github.com/wikimedia/less.php/compare/v1.8.0...v1.8.1)
+* Another PHP 7.3 compatibility tweak
+
+## 1.8.0
+
+Library forked by Wikimedia, from [oyejorge/less.php](https://github.com/oyejorge/less.php).
+
+* [All changes](https://github.com/wikimedia/less.php/compare/v1.7.0.13...v1.8.0)
+* Supports up to PHP 7.3
+* No longer tested against PHP 5, though it's still remains allowed in `composer.json` for HHVM compatibility
+* Switched to [semantic versioning](https://semver.org/), hence version numbers now use 3 digits
+
+## 1.7.0.13
+
+* [All changes](https://github.com/wikimedia/less.php/compare/v1.7.0.12...v1.7.0.13)
+* Fix composer.json (PSR-4 was invalid)
+
+## 1.7.0.12
+
+* [All changes](https://github.com/wikimedia/less.php/compare/v1.7.0.11...v1.7.0.12)
+* set bin/lessc bit executable
+* Add `gettingVariables` method to `Less_Parser`
+
+## 1.7.0.11
+
+* [All changes](https://github.com/wikimedia/less.php/compare/v1.7.0.10...v1.7.0.11)
+* Fix realpath issue (windows)
+* Set Less_Tree_Call property back to public ( Fix 258 266 267 issues from oyejorge/less.php)
+
+## 1.7.0.10
+
+* [All changes](https://github.com/wikimedia/less.php/compare/v1.7.0.9...v1.7.10)
+* Add indentation option
+* Add `optional` modifier for `@import`
+* Fix $color in Exception messages
+* take relative-url into account when building the cache filename
+* urlArgs should be string no array()
+* fix missing on NameValue type [#269](https://github.com/oyejorge/less.php/issues/269)
+
+## 1.7.0.9
+
+* [All changes](https://github.com/wikimedia/less.php/compare/v1.7.0.8...v1.7.0.9)
+* Remove space at beginning of Version.php
+* Revert require() paths in test interface
diff --git a/vendor/wikimedia/less.php/CODE_OF_CONDUCT.md b/vendor/wikimedia/less.php/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000..498acf76f
--- /dev/null
+++ b/vendor/wikimedia/less.php/CODE_OF_CONDUCT.md
@@ -0,0 +1 @@
+The development of this software is covered by a [Code of Conduct](https://www.mediawiki.org/wiki/Special:MyLanguage/Code_of_Conduct).
diff --git a/vendor/wikimedia/less.php/LICENSE b/vendor/wikimedia/less.php/LICENSE
index 82216a5da..d64569567 100644
--- a/vendor/wikimedia/less.php/LICENSE
+++ b/vendor/wikimedia/less.php/LICENSE
@@ -1,178 +1,202 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-1. Definitions.
+ 1. Definitions.
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
-2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
-3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
-4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
-5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
-6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
-7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
-8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
-9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
-END OF TERMS AND CONDITIONS
+ END OF TERMS AND CONDITIONS
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/wikimedia/less.php/NOTICE.txt b/vendor/wikimedia/less.php/NOTICE.txt
new file mode 100644
index 000000000..099293ca0
--- /dev/null
+++ b/vendor/wikimedia/less.php/NOTICE.txt
@@ -0,0 +1,18 @@
+wikimedia/less.php. https://gerrit.wikimedia.org/g/mediawiki/libs/less.php
+
+Copyright Matt Agar
+Copyright Martin Jantošovič
+Copyright Josh Schmidt
+Copyright Timo Tijhof
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/vendor/wikimedia/less.php/README.md b/vendor/wikimedia/less.php/README.md
index 440c4db06..a89ea6ce7 100644
--- a/vendor/wikimedia/less.php/README.md
+++ b/vendor/wikimedia/less.php/README.md
@@ -1,323 +1,77 @@
-[Less.php](http://lessphp.typesettercms.com)
+[](https://packagist.org/packages/wikimedia/less.php)
+
+Less.php
========
-This is the Wikimedia fork of a PHP port of the official LESS processor . [](https://travis-ci.org/wikimedia/less.php)
+This is a PHP port of the [official LESS processor](https://lesscss.org).
-* [About](#about)
-* [Installation](#installation)
-* [Basic Use](#basic-use)
-* [Caching](#caching)
-* [Source Maps](#source-maps)
-* [Command Line](#command-line)
-* [Integration with other projects](#integration-with-other-projects)
-* [Transitioning from Leafo/lessphp](#transitioning-from-leafolessphp)
-* [Credits](#credits)
+## About
+The code structure of Less.php mirrors that of upstream Less.js to ensure compatibility and help reduce maintenance. The port is currently compatible with Less.js 2.5.3. Please note that "inline JavaScript expressions" (via eval or backticks) are not supported.
+* [API § Caching](./API.md#caching), Less.php includes a file-based cache.
+* [API § Source maps](./API.md#source-maps), Less.php supports v3 sourcemaps.
+* [API § Command line](./API.md#command-line), the `lessc` command includes a watch mode.
-About
----
-The code structure of less.php mirrors that of the official processor which helps us ensure compatibility and allows for easy maintenance.
+## Installation
-Please note, there are a few unsupported LESS features:
+You can install the library with Composer or standalone.
-- Evaluation of JavaScript expressions within back-ticks (for obvious reasons).
-- Definition of custom functions.
+If you have [Composer](https://getcomposer.org/download/) installed:
+1. Run `composer require wikimedia/less.php`
+2. Use `Less_Parser` in your code.
-Installation
----
+Or standalone:
-You can install the library with Composer or manually.
+1. [Download Less.php](https://gerrit.wikimedia.org/g/mediawiki/libs/less.php/+archive/HEAD.tar.gz) and upload the PHP files to your server.
+2. Include the library:
+ ```php
+ require_once '[path to]/less.php/lib/Less/Autoloader.php';
+ Less_Autoloader::register();
+ ```
+3. Use `Less_Parser` in your code.
-#### Composer
+## Security
-1. [Install Composer](https://getcomposer.org/download/)
-2. Run `composer require wikimedia/less.php`
+The LESS processor language is powerful and includes features that may read or embed arbitrary files that the web server has access to, and features that may be computationally exensive if misused.
-#### Manually From Release
+In general you should treat LESS files as being in the same trust domain as other server-side executables, such as PHP code. In particular, it is not recommended to allow people that use your web service to provide arbitrary LESS code for server-side processing.
-Step 1. [Download the latest release](https://github.com/wikimedia/less.php/releases) and upload the PHP files to your server.
+_See also [SECURITY](./SECURITY.md)._
-Step 2. Include the library:
+## Who uses Less.php?
-```php
-require_once '[path to less.php]/Less.php';
-```
+* **[Wikipedia](https://en.wikipedia.org/wiki/MediaWiki)** and the MediaWiki platform ([docs](https://www.mediawiki.org/wiki/ResourceLoader/Architecture#Resource:_Styles)).
+* **[Matomo](https://en.wikipedia.org/wiki/Matomo_(software))** ([docs](https://devdocs.magento.com/guides/v2.4/frontend-dev-guide/css-topics/custom_preprocess.html)).
+* **[Magento](https://en.wikipedia.org/wiki/Magento)** as part of Adobe Commerce ([docs](https://developer.matomo.org/guides/asset-pipeline#vanilla-javascript-css-and-less-files)).
+* **[Icinga](https://en.wikipedia.org/wiki/Icinga)** in Icinga Web ([docs](https://github.com/Icinga/icingaweb2)).
+* **[Shopware](https://de.wikipedia.org/wiki/Shopware)** ([docs](https://developers.shopware.com/designers-guide/less/)).
-#### Manually From Source
+## Integrations
-Step 1. [Download the source](https://github.com/wikimedia/less.php/archive/master.zip) and upload the files in /lib/Less to a folder on your server.
+Less.php has been integrated with various other projects.
-Step 2. Include the library and register the autoloader
+#### Transitioning from Leafo/lessphp
-```php
-require_once '[path to less.php]/Autoloader.php';
-Less_Autoloader::register();
-```
+If you're looking to transition from the [Leafo/lessphp](https://github.com/leafo/lessphp) library, use the `lessc.inc.php` adapter file that comes with Less.php.
-Basic Use
----
+This allows Less.php to be a drop-in replacement for Leafo/lessphp.
-#### Parsing Strings
+[Download Less.php](https://gerrit.wikimedia.org/g/mediawiki/libs/less.php/+archive/HEAD.tar.gz), unzip the files into your project, and include its `lessc.inc.php` instead.
-```php
-$parser = new Less_Parser();
-$parser->parse( '@color: #4D926F; #header { color: @color; } h2 { color: @color; }' );
-$css = $parser->getCss();
-```
+Note: The `setPreserveComments` option is ignored. Less.php already preserves CSS block comments by default, and removes LESS inline comments.
+#### Drupal
-#### Parsing LESS Files
-The parseFile() function takes two arguments:
-
-1. The absolute path of the .less file to be parsed
-2. The url root to prepend to any relative image or @import urls in the .less file.
-
-```php
-$parser = new Less_Parser();
-$parser->parseFile( '/var/www/mysite/bootstrap.less', 'http://example.com/mysite/' );
-$css = $parser->getCss();
-```
-
-
-#### Handling Invalid LESS
-An exception will be thrown if the compiler encounters invalid LESS.
-
-```php
-try{
- $parser = new Less_Parser();
- $parser->parseFile( '/var/www/mysite/bootstrap.less', 'http://example.com/mysite/' );
- $css = $parser->getCss();
-}catch(Exception $e){
- $error_message = $e->getMessage();
-}
-```
-
-
-#### Parsing Multiple Sources
-less.php can parse multiple sources to generate a single CSS file.
-
-```php
-$parser = new Less_Parser();
-$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' );
-$parser->parse( '@color: #4D926F; #header { color: @color; } h2 { color: @color; }' );
-$css = $parser->getCss();
-```
-
-#### Getting Info About The Parsed Files
-less.php can tell you which .less files were imported and parsed.
-
-```php
-$parser = new Less_Parser();
-$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' );
-$css = $parser->getCss();
-$imported_files = $parser->allParsedFiles();
-```
-
-
-#### Compressing Output
-You can tell less.php to remove comments and whitespace to generate minimized CSS files.
-
-```php
-$options = array( 'compress'=>true );
-$parser = new Less_Parser( $options );
-$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' );
-$css = $parser->getCss();
-```
-
-#### Getting Variables
-You can use the getVariables() method to get an all variables defined and
-their value in a php associative array. Note that LESS has to be previously
-compiled.
-```php
-$parser = new Less_Parser;
-$parser->parseFile( '/var/www/mysite/bootstrap.less');
-$css = $parser->getCss();
-$variables = $parser->getVariables();
-
-```
-
-
-
-#### Setting Variables
-You can use the ModifyVars() method to customize your CSS if you have variables stored in PHP associative arrays.
-
-```php
-$parser = new Less_Parser();
-$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' );
-$parser->ModifyVars( array('font-size-base'=>'16px') );
-$css = $parser->getCss();
-```
-
-
-#### Import Directories
-By default, less.php will look for @imports in the directory of the file passed to parseFile().
-If you're using parse() or if @imports reside in different directories, you can tell less.php where to look.
-
-```php
-$directories = array( '/var/www/mysite/bootstrap/' => '/mysite/bootstrap/' );
-$parser = new Less_Parser();
-$parser->SetImportDirs( $directories );
-$parser->parseFile( '/var/www/mysite/theme.less', '/mysite/' );
-$css = $parser->getCss();
-```
-
-
-Caching
----
-Compiling LESS code into CSS is a time consuming process, caching your results is highly recommended.
-
-
-#### Caching CSS
-Use the Less_Cache class to save and reuse the results of compiled LESS files.
-This method will check the modified time and size of each LESS file (including imported files) and regenerate a new CSS file when changes are found.
-Note: When changes are found, this method will return a different file name for the new cached content.
-
-```php
-$less_files = array( '/var/www/mysite/bootstrap.less' => '/mysite/' );
-$options = array( 'cache_dir' => '/var/www/writable_folder' );
-$css_file_name = Less_Cache::Get( $less_files, $options );
-$compiled = file_get_contents( '/var/www/writable_folder/'.$css_file_name );
-```
-
-#### Caching CSS With Variables
-Passing options to Less_Cache::Get()
-
-```php
-$less_files = array( '/var/www/mysite/bootstrap.less' => '/mysite/' );
-$options = array( 'cache_dir' => '/var/www/writable_folder' );
-$variables = array( 'width' => '100px' );
-$css_file_name = Less_Cache::Get( $less_files, $options, $variables );
-$compiled = file_get_contents( '/var/www/writable_folder/'.$css_file_name );
-```
-
-
-#### Parser Caching
-less.php will save serialized parser data for each .less file if a writable folder is passed to the SetCacheDir() method.
-Note: This feature only caches intermediate parsing results to improve the performance of repeated CSS generation.
-Your application should cache any CSS generated by less.php.
-
-```php
-$options = array('cache_dir'=>'/var/www/writable_folder');
-$parser = new Less_Parser( $options );
-$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' );
-$css = $parser->getCss();
-```
-
-You can specify the caching technique used by changing the ```cache_method``` option. Supported methods are:
-* ```php```: Creates valid PHP files which can be included without any changes (default method).
-* ```var_export```: Like "php", but using PHP's ```var_export()``` function without any optimizations.
- It's recommended to use "php" instead.
-* ```serialize```: Faster, but pretty memory-intense.
-* ```callback```: Use custom callback functions to implement your own caching method. Give the "cache_callback_get" and
- "cache_callback_set" options with callables (see PHP's ```call_user_func()``` and ```is_callable()``` functions). less.php
- will pass the parser object (class ```Less_Parser```), the path to the parsed .less file ("/some/path/to/file.less") and
- an identifier that will change every time the .less file is modified. The ```get``` callback must return the ruleset
- (an array with ```Less_Tree``` objects) provided as fourth parameter of the ```set``` callback. If something goes wrong,
- return ```NULL``` (cache doesn't exist) or ```FALSE```.
-
-
-
-Source Maps
----
-Less.php supports v3 sourcemaps
-
-#### Inline
-The sourcemap will be appended to the generated CSS file.
-
-```php
-$options = array( 'sourceMap' => true );
-$parser = new Less_Parser($options);
-$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' );
-$css = $parser->getCss();
-```
-
-#### Saving to Map File
-
-```php
-$options = array(
- 'sourceMap' => true,
- 'sourceMapWriteTo' => '/var/www/mysite/writable_folder/filename.map',
- 'sourceMapURL' => '/mysite/writable_folder/filename.map',
- );
-$parser = new Less_Parser($options);
-$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' );
-$css = $parser->getCss();
-```
-
-
-Command line
----
-An additional script has been included to use the compiler from the command line.
-In the simplest invocation, you specify an input file and the compiled CSS is written to standard out:
-
-```
-$ lessc input.less > output.css
-```
-
-By using the -w flag you can watch a specified input file and have it compile as needed to the output file:
-
-```
-$ lessc -w input.less output.css
-```
-
-Errors from watch mode are written to standard out.
-
-For more help, run `lessc --help`
-
-
-Integration with other projects
----
-
-#### Drupal 7
-
-This library can be used as drop-in replacement of lessphp to work with [Drupal 7 less module](https://drupal.org/project/less).
-
-How to install:
-
-1. [Download the less.php source code](https://github.com/wikimedia/less.php/archive/master.zip) and unzip it so that 'lessc.inc.php' is located at 'sites/all/libraries/lessphp/lessc.inc.php'.
-2. Download and install [Drupal 7 less module](https://drupal.org/project/less) as usual.
-3. That's it :)
-
-#### JBST WordPress theme
-
-JBST has a built-in LESS compiler based on lessphp. Customize your WordPress theme with LESS.
-
-How to use / install:
-
-1. [Download the latest release](https://github.com/bassjobsen/jamedo-bootstrap-start-theme) copy the files to your {wordpress/}wp-content/themes folder and activate it.
-2. Find the compiler under Appearance > LESS Compiler in your WordPress dashboard
-3. Enter your LESS code in the text area and press (re)compile
-
-Use the built-in compiler to:
-- set any [Bootstrap](http://getbootstrap.com/customize/) variable or use Bootstrap's mixins:
- -`@navbar-default-color: blue;`
- - create a custom button: `.btn-custom {
- .button-variant(white; red; blue);
-}`
-- set any built-in LESS variable: for example `@footer_bg_color: black;` sets the background color of the footer to black
-- use built-in mixins: - add a custom font: `.include-custom-font(@family: arial,@font-path, @path: @custom-font-dir, @weight: normal, @style: normal);`
-
-The compiler can also be downloaded as [plugin](http://wordpress.org/plugins/wp-less-to-css/)
+Less.php can be used with [Drupal's less module](https://drupal.org/project/less) via the `lessc.inc.php` adapter. [Download Less.php](https://gerrit.wikimedia.org/g/mediawiki/libs/less.php/+archive/HEAD.tar.gz) and unzip it so that `lessc.inc.php` is located at `sites/all/libraries/lessphp/lessc.inc.php`, then install the Drupal less module as usual.
#### WordPress
-This simple plugin will simply make the library available to other plugins and themes and can be used as a dependency using the [TGM Library](http://tgmpluginactivation.com/)
+* [wp_enqueue_less](https://github.com/Ed-ITSolutions/wp_enqueue_less) is a Composer package for use in WordPress themes and plugins. It provides a `wp_enqueue_less()` function to automatically manage caching and compilation on-demand, and loads the compressed CSS on the page.
+* [JBST framework](https://github.com/bassjobsen/jamedo-bootstrap-start-theme) bundles a copy of Less.php.
+* The [lessphp plugin](https://wordpress.org/plugins/lessphp/) bundles a copy of Less.php for use in other plugins or themes. This dependency can also be combined with the [TGM Library](http://tgmpluginactivation.com/).
-How to install:
-
-1. Install the plugin from your WordPress Dashboard: http://wordpress.org/plugins/lessphp/
-2. That's it :)
-
-
-Transitioning from Leafo/lessphp
----
-Projects looking for an easy transition from leafo/lessphp can use the lessc.inc.php adapter. To use, [Download the less.php source code](https://github.com/wikimedia/less.php/archive/master.zip) and unzip the files into your project so that the new 'lessc.inc.php' replaces the existing 'lessc.inc.php'.
-
-Note, the 'setPreserveComments' will no longer have any effect on the compiled LESS.
-
-Credits
----
-less.php was originally ported to PHP by [Matt Agar](https://github.com/agar) and then updated by [Martin Jantošovič](https://github.com/Mordred). This Wikimedia-maintained fork was split off from [Josh Schmidt's version](https://github.com/oyejorge/less.php).
+## Credits
+Less.php was originally ported to PHP in 2011 by [Matt Agar](https://github.com/agar) and then updated by [Martin Jantošovič](https://github.com/Mordred) in 2012. From 2013 to 2017, [Josh Schmidt](https://github.com/oyejorge) lead development of the library. Since 2019, the library is maintained by Wikimedia Foundation.
diff --git a/vendor/wikimedia/less.php/SECURITY.md b/vendor/wikimedia/less.php/SECURITY.md
new file mode 100644
index 000000000..687c7357c
--- /dev/null
+++ b/vendor/wikimedia/less.php/SECURITY.md
@@ -0,0 +1,5 @@
+# Security policy
+
+Wikimedia takes security seriously. If you believe you have found a
+security issue, see
+for information on how to responsibly report it.
diff --git a/vendor/wikimedia/less.php/bin/lessc b/vendor/wikimedia/less.php/bin/lessc
index fa1fb9588..7e3d128d8 100755
--- a/vendor/wikimedia/less.php/bin/lessc
+++ b/vendor/wikimedia/less.php/bin/lessc
@@ -1,7 +1,7 @@
#!/usr/bin/env php
=7.1"
- },
- "require-dev": {
- "phpunit/phpunit": "7.5.14"
- },
- "scripts": {
- "test": [
- "phpunit"
- ]
- },
- "autoload": {
- "psr-0": { "Less": "lib/" },
- "classmap": ["lessc.inc.php"]
- },
- "bin": [
- "bin/lessc"
- ]
-}
diff --git a/vendor/wikimedia/less.php/lessc.inc.php b/vendor/wikimedia/less.php/lessc.inc.php
index e6cdf20ab..a3c66dd26 100644
--- a/vendor/wikimedia/less.php/lessc.inc.php
+++ b/vendor/wikimedia/less.php/lessc.inc.php
@@ -14,16 +14,17 @@ if ( !class_exists( 'Less_Parser' ) ) {
class lessc {
- static public $VERSION = Less_Version::less_version;
+ public static $VERSION = Less_Version::less_version;
public $importDir = '';
- protected $allParsedFiles = array();
- protected $libFunctions = array();
- protected $registeredVars = array();
+ protected $allParsedFiles = [];
+ protected $libFunctions = [];
+ protected $registeredVars = [];
private $formatterName;
- private $options = array();
+ private $options = [];
- public function __construct( $lessc=null, $sourceName=null ) {}
+ public function __construct( $lessc = null, $sourceName = null ) {
+ }
public function setImportDir( $dirs ) {
$this->importDir = (array)$dirs;
@@ -38,7 +39,8 @@ class lessc {
$this->formatterName = $name;
}
- public function setPreserveComments( $preserve ) {}
+ public function setPreserveComments( $preserve ) {
+ }
public function registerFunction( $name, $func ) {
$this->libFunctions[$name] = $func;
@@ -48,7 +50,7 @@ class lessc {
unset( $this->libFunctions[$name] );
}
- public function setVariables( $variables ){
+ public function setVariables( $variables ) {
foreach ( $variables as $name => $value ) {
$this->setVariable( $name, $value );
}
@@ -64,16 +66,15 @@ class lessc {
public function setOptions( $options ) {
foreach ( $options as $name => $value ) {
- $this->setOption( $name, $value);
+ $this->setOption( $name, $value );
}
}
-
+
public function setOption( $name, $value ) {
$this->options[$name] = $value;
}
-
- public function parse( $buffer, $presets = array() ) {
+ public function parse( $buffer, $presets = [] ) {
$this->setVariables( $presets );
$parser = new Less_Parser( $this->getOptions() );
@@ -81,7 +82,7 @@ class lessc {
foreach ( $this->libFunctions as $name => $func ) {
$parser->registerFunction( $name, $func );
}
- $parser->parse($buffer);
+ $parser->parse( $buffer );
if ( count( $this->registeredVars ) ) {
$parser->ModifyVars( $this->registeredVars );
}
@@ -90,22 +91,21 @@ class lessc {
}
protected function getOptions() {
- $options = array( 'relativeUrls'=>false );
- switch( $this->formatterName ) {
+ $options = [ 'relativeUrls' => false ];
+ switch ( $this->formatterName ) {
case 'compressed':
$options['compress'] = true;
break;
}
- if (is_array($this->options))
- {
- $options = array_merge($options, $this->options);
+ if ( is_array( $this->options ) ) {
+ $options = array_merge( $options, $this->options );
}
return $options;
}
protected function getImportDirs() {
$dirs_ = (array)$this->importDir;
- $dirs = array();
+ $dirs = [];
foreach ( $dirs_ as $dir ) {
$dirs[$dir] = '';
}
@@ -113,11 +113,10 @@ class lessc {
}
public function compile( $string, $name = null ) {
-
$oldImport = $this->importDir;
$this->importDir = (array)$this->importDir;
- $this->allParsedFiles = array();
+ $this->allParsedFiles = [];
$parser = new Less_Parser( $this->getOptions() );
$parser->SetImportDirs( $this->getImportDirs() );
@@ -142,7 +141,7 @@ class lessc {
public function compileFile( $fname, $outFname = null ) {
if ( !is_readable( $fname ) ) {
- throw new Exception( 'load error: failed to find '.$fname );
+ throw new Exception( 'load error: failed to find ' . $fname );
}
$pi = pathinfo( $fname );
@@ -150,9 +149,9 @@ class lessc {
$oldImport = $this->importDir;
$this->importDir = (array)$this->importDir;
- $this->importDir[] = Less_Parser::AbsPath( $pi['dirname'] ).'/';
+ $this->importDir[] = Less_Parser::AbsPath( $pi['dirname'] ) . '/';
- $this->allParsedFiles = array();
+ $this->allParsedFiles = [];
$this->addParsedFile( $fname );
$parser = new Less_Parser( $this->getOptions() );
@@ -182,13 +181,12 @@ class lessc {
public function checkedCompile( $in, $out ) {
if ( !is_file( $out ) || filemtime( $in ) > filemtime( $out ) ) {
- $this->compileFile($in, $out);
+ $this->compileFile( $in, $out );
return true;
}
return false;
}
-
/**
* Execute lessphp on a .less file or a lessphp cache structure
*
@@ -216,7 +214,7 @@ class lessc {
if ( is_string( $in ) ) {
$root = $in;
} elseif ( is_array( $in ) and isset( $in['root'] ) ) {
- if ( $force or ! isset( $in['files'] ) ) {
+ if ( $force or !isset( $in['files'] ) ) {
// If we are forcing a recompile or if for some reason the
// structure does not contain any file information we should
// specify the root to trigger a rebuild.
@@ -239,9 +237,9 @@ class lessc {
if ( $root !== null ) {
// If we have a root value which means we should rebuild.
- $out = array();
+ $out = [];
$out['root'] = $root;
- $out['compiled'] = $this->compileFile($root);
+ $out['compiled'] = $this->compileFile( $root );
$out['files'] = $this->allParsedFiles();
$out['updated'] = time();
return $out;
@@ -263,7 +261,7 @@ class lessc {
if ( $less === null ) {
$less = new self;
}
- return $less->cachedCompile($in, $force);
+ return $less->cachedCompile( $in, $force );
}
public function allParsedFiles() {
diff --git a/vendor/wikimedia/less.php/lib/Less/Autoloader.php b/vendor/wikimedia/less.php/lib/Less/Autoloader.php
index b6300c020..a4f7a4a23 100644
--- a/vendor/wikimedia/less.php/lib/Less/Autoloader.php
+++ b/vendor/wikimedia/less.php/lib/Less/Autoloader.php
@@ -2,78 +2,56 @@
/**
* Autoloader
- *
- * @package Less
- * @subpackage autoload
*/
class Less_Autoloader {
- /**
- * Registered flag
- *
- * @var boolean
- */
+ /** @var bool */
protected static $registered = false;
/**
- * Library directory
- *
- * @var string
- */
- protected static $libDir;
-
- /**
- * Register the autoloader in the spl autoloader
+ * Register the autoloader in the SPL autoloader
*
* @return void
* @throws Exception If there was an error in registration
*/
- public static function register(){
- if( self::$registered ){
+ public static function register() {
+ if ( self::$registered ) {
return;
}
- self::$libDir = dirname(__FILE__);
-
- if(false === spl_autoload_register(array('Less_Autoloader', 'loadClass'))){
- throw new Exception('Unable to register Less_Autoloader::loadClass as an autoloading method.');
+ if ( !spl_autoload_register( [ 'Less_Autoloader', 'loadClass' ] ) ) {
+ throw new Exception( 'Unable to register Less_Autoloader::loadClass as an autoloading method.' );
}
self::$registered = true;
}
/**
- * Unregisters the autoloader
+ * Unregister the autoloader
*
* @return void
*/
- public static function unregister(){
- spl_autoload_unregister(array('Less_Autoloader', 'loadClass'));
+ public static function unregister() {
+ spl_autoload_unregister( [ 'Less_Autoloader', 'loadClass' ] );
self::$registered = false;
}
/**
- * Loads the class
+ * Load the class
*
* @param string $className The class to load
*/
- public static function loadClass($className){
-
-
+ public static function loadClass( $className ) {
// handle only package classes
- if(strpos($className, 'Less_') !== 0){
+ if ( strpos( $className, 'Less_' ) !== 0 ) {
return;
}
- $className = substr($className,5);
- $fileName = self::$libDir . DIRECTORY_SEPARATOR . str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
+ $className = substr( $className, 5 );
+ $fileName = __DIR__ . DIRECTORY_SEPARATOR . str_replace( '_', DIRECTORY_SEPARATOR, $className ) . '.php';
- if(file_exists($fileName)){
- require $fileName;
- return true;
- }else{
- throw new Exception('file not loadable '.$fileName);
- }
+ require $fileName;
+ return true;
}
-}
\ No newline at end of file
+}
diff --git a/vendor/wikimedia/less.php/lib/Less/Cache.php b/vendor/wikimedia/less.php/lib/Less/Cache.php
index 40d0358dd..c8c4b4489 100644
--- a/vendor/wikimedia/less.php/lib/Less/Cache.php
+++ b/vendor/wikimedia/less.php/lib/Less/Cache.php
@@ -1,28 +1,21 @@
'/');
+ $less_files += [ $vars_file => '/' ];
}
-
// generate name for compiled css file
- $hash = md5(json_encode($less_files));
- $list_file = Less_Cache::$cache_dir . Less_Cache::$prefix . $hash . '.list';
+ $hash = md5( json_encode( $less_files ) );
+ $list_file = self::$cache_dir . self::$prefix . $hash . '.list';
- // check cached content
- if( !isset($parser_options['use_cache']) || $parser_options['use_cache'] === true ){
- if( file_exists($list_file) ){
+ // check cached content
+ if ( !isset( $parser_options['use_cache'] ) || $parser_options['use_cache'] === true ) {
+ if ( file_exists( $list_file ) ) {
- self::ListFiles($list_file, $list, $cached_name);
- $compiled_name = self::CompiledName($list, $hash);
+ self::ListFiles( $list_file, $list, $cached_name );
+ $compiled_name = self::CompiledName( $list, $hash );
// if $cached_name is the same as the $compiled name, don't regenerate
- if( !$cached_name || $cached_name === $compiled_name ){
+ if ( !$cached_name || $cached_name === $compiled_name ) {
- $output_file = self::OutputFile($compiled_name, $parser_options );
+ $output_file = self::OutputFile( $compiled_name, $parser_options );
- if( $output_file && file_exists($output_file) ){
- @touch($list_file);
- return basename($output_file); // for backwards compatibility, we just return the name of the file
+ if ( $output_file && file_exists( $output_file ) ) {
+ @touch( $list_file );
+ return basename( $output_file ); // for backwards compatibility, we just return the name of the file
}
}
}
}
$compiled = self::Cache( $less_files, $parser_options );
- if( !$compiled ){
+ if ( !$compiled ) {
return false;
}
$compiled_name = self::CompiledName( $less_files, $hash );
- $output_file = self::OutputFile($compiled_name, $parser_options );
+ $output_file = self::OutputFile( $compiled_name, $parser_options );
-
- //save the file list
+ // save the file list
$list = $less_files;
$list[] = $compiled_name;
- $cache = implode("\n",$list);
+ $cache = implode( "\n", $list );
file_put_contents( $list_file, $cache );
-
- //save the css
+ // save the css
file_put_contents( $output_file, $compiled );
-
- //clean up
+ // clean up
self::CleanCache();
- return basename($output_file);
+ return basename( $output_file );
}
/**
@@ -137,29 +123,20 @@ class Less_Cache{
* @param array $modify_vars Array of variables
* @return string Name of the css file
*/
- public static function Regen( $less_files, $parser_options = array(), $modify_vars = array() ){
+ public static function Regen( $less_files, $parser_options = [], $modify_vars = [] ) {
$parser_options['use_cache'] = false;
return self::Get( $less_files, $parser_options, $modify_vars );
}
- public static function Cache( &$less_files, $parser_options = array() ){
-
-
- // get less.php if it exists
- $file = dirname(__FILE__) . '/Less.php';
- if( file_exists($file) && !class_exists('Less_Parser') ){
- require_once($file);
- }
-
- $parser_options['cache_dir'] = Less_Cache::$cache_dir;
- $parser = new Less_Parser($parser_options);
-
+ public static function Cache( &$less_files, $parser_options = [] ) {
+ $parser_options['cache_dir'] = self::$cache_dir;
+ $parser = new Less_Parser( $parser_options );
// combine files
- foreach($less_files as $file_path => $uri_or_less ){
+ foreach ( $less_files as $file_path => $uri_or_less ) {
- //treat as less markup if there are newline characters
- if( strpos($uri_or_less,"\n") !== false ){
+ // treat as less markup if there are newline characters
+ if ( strpos( $uri_or_less, "\n" ) !== false ) {
$parser->Parse( $uri_or_less );
continue;
}
@@ -169,77 +146,66 @@ class Less_Cache{
$compiled = $parser->getCss();
-
$less_files = $parser->allParsedFiles();
return $compiled;
}
+ private static function OutputFile( $compiled_name, $parser_options ) {
+ // custom output file
+ if ( !empty( $parser_options['output'] ) ) {
- private static function OutputFile( $compiled_name, $parser_options ){
-
- //custom output file
- if( !empty($parser_options['output']) ){
-
- //relative to cache directory?
- if( preg_match('#[\\\\/]#',$parser_options['output']) ){
+ // relative to cache directory?
+ if ( preg_match( '#[\\\\/]#', $parser_options['output'] ) ) {
return $parser_options['output'];
}
- return Less_Cache::$cache_dir.$parser_options['output'];
+ return self::$cache_dir . $parser_options['output'];
}
- return Less_Cache::$cache_dir.$compiled_name;
+ return self::$cache_dir . $compiled_name;
}
-
- private static function CompiledName( $files, $extrahash ){
-
- //save the file list
- $temp = array(Less_Version::cache_version);
- foreach($files as $file){
- $temp[] = filemtime($file)."\t".filesize($file)."\t".$file;
+ private static function CompiledName( $files, $extrahash ) {
+ // save the file list
+ $temp = [ Less_Version::cache_version ];
+ foreach ( $files as $file ) {
+ $temp[] = filemtime( $file ) . "\t" . filesize( $file ) . "\t" . $file;
}
- return Less_Cache::$prefix.sha1(json_encode($temp).$extrahash).'.css';
+ return self::$prefix . sha1( json_encode( $temp ) . $extrahash ) . '.css';
}
-
- public static function SetCacheDir( $dir ){
- Less_Cache::$cache_dir = $dir;
+ public static function SetCacheDir( $dir ) {
+ self::$cache_dir = $dir;
self::CheckCacheDir();
}
- public static function CheckCacheDir(){
+ public static function CheckCacheDir() {
+ self::$cache_dir = str_replace( '\\', '/', self::$cache_dir );
+ self::$cache_dir = rtrim( self::$cache_dir, '/' ) . '/';
- Less_Cache::$cache_dir = str_replace('\\','/',Less_Cache::$cache_dir);
- Less_Cache::$cache_dir = rtrim(Less_Cache::$cache_dir,'/').'/';
-
- if( !file_exists(Less_Cache::$cache_dir) ){
- if( !mkdir(Less_Cache::$cache_dir) ){
- throw new Less_Exception_Parser('Less.php cache directory couldn\'t be created: '.Less_Cache::$cache_dir);
+ if ( !file_exists( self::$cache_dir ) ) {
+ if ( !mkdir( self::$cache_dir ) ) {
+ throw new Less_Exception_Parser( 'Less.php cache directory couldn\'t be created: ' . self::$cache_dir );
}
- }elseif( !is_dir(Less_Cache::$cache_dir) ){
- throw new Less_Exception_Parser('Less.php cache directory doesn\'t exist: '.Less_Cache::$cache_dir);
+ } elseif ( !is_dir( self::$cache_dir ) ) {
+ throw new Less_Exception_Parser( 'Less.php cache directory doesn\'t exist: ' . self::$cache_dir );
- }elseif( !is_writable(Less_Cache::$cache_dir) ){
- throw new Less_Exception_Parser('Less.php cache directory isn\'t writable: '.Less_Cache::$cache_dir);
+ } elseif ( !is_writable( self::$cache_dir ) ) {
+ throw new Less_Exception_Parser( 'Less.php cache directory isn\'t writable: ' . self::$cache_dir );
}
-
}
-
/**
* Delete unused less.php files
- *
*/
- public static function CleanCache(){
+ public static function CleanCache() {
static $clean = false;
-
- if( $clean || empty(Less_Cache::$cache_dir) ){
+ if ( $clean || empty( self::$cache_dir ) ) {
return;
}
@@ -247,73 +213,64 @@ class Less_Cache{
// only remove files with extensions created by less.php
// css files removed based on the list files
- $remove_types = array('lesscache'=>1,'list'=>1,'less'=>1,'map'=>1);
+ $remove_types = [ 'lesscache' => 1,'list' => 1,'less' => 1,'map' => 1 ];
- $files = scandir(Less_Cache::$cache_dir);
- if( !$files ){
+ $files = scandir( self::$cache_dir );
+ if ( !$files ) {
return;
}
$check_time = time() - self::$gc_lifetime;
- foreach($files as $file){
-
+ foreach ( $files as $file ) {
// don't delete if the file wasn't created with less.php
- if( strpos($file,Less_Cache::$prefix) !== 0 ){
+ if ( strpos( $file, self::$prefix ) !== 0 ) {
continue;
}
- $parts = explode('.',$file);
- $type = array_pop($parts);
+ $parts = explode( '.', $file );
+ $type = array_pop( $parts );
-
- if( !isset($remove_types[$type]) ){
+ if ( !isset( $remove_types[$type] ) ) {
continue;
}
- $full_path = Less_Cache::$cache_dir . $file;
- $mtime = filemtime($full_path);
+ $full_path = self::$cache_dir . $file;
+ $mtime = filemtime( $full_path );
// don't delete if it's a relatively new file
- if( $mtime > $check_time ){
+ if ( $mtime > $check_time ) {
continue;
}
-
// delete the list file and associated css file
- if( $type === 'list' ){
- self::ListFiles($full_path, $list, $css_file_name);
- if( $css_file_name ){
- $css_file = Less_Cache::$cache_dir . $css_file_name;
- if( file_exists($css_file) ){
- unlink($css_file);
+ if ( $type === 'list' ) {
+ self::ListFiles( $full_path, $list, $css_file_name );
+ if ( $css_file_name ) {
+ $css_file = self::$cache_dir . $css_file_name;
+ if ( file_exists( $css_file ) ) {
+ unlink( $css_file );
}
}
}
- unlink($full_path);
+ unlink( $full_path );
}
-
-
}
-
/**
* Get the list of less files and generated css file from a list file
- *
*/
- static function ListFiles($list_file, &$list, &$css_file_name ){
+ static function ListFiles( $list_file, &$list, &$css_file_name ) {
+ $list = explode( "\n", file_get_contents( $list_file ) );
- $list = explode("\n",file_get_contents($list_file));
+ // pop the cached name that should match $compiled_name
+ $css_file_name = array_pop( $list );
- //pop the cached name that should match $compiled_name
- $css_file_name = array_pop($list);
-
- if( !preg_match('/^' . Less_Cache::$prefix . '[a-f0-9]+\.css$/',$css_file_name) ){
+ if ( !preg_match( '/^' . self::$prefix . '[a-f0-9]+\.css$/', $css_file_name ) ) {
$list[] = $css_file_name;
$css_file_name = false;
}
-
}
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Colors.php b/vendor/wikimedia/less.php/lib/Less/Colors.php
index ad3f31dc4..2f715c2b8 100644
--- a/vendor/wikimedia/less.php/lib/Less/Colors.php
+++ b/vendor/wikimedia/less.php/lib/Less/Colors.php
@@ -1,170 +1,176 @@
'#f0f8ff',
- 'antiquewhite'=>'#faebd7',
- 'aqua'=>'#00ffff',
- 'aquamarine'=>'#7fffd4',
- 'azure'=>'#f0ffff',
- 'beige'=>'#f5f5dc',
- 'bisque'=>'#ffe4c4',
- 'black'=>'#000000',
- 'blanchedalmond'=>'#ffebcd',
- 'blue'=>'#0000ff',
- 'blueviolet'=>'#8a2be2',
- 'brown'=>'#a52a2a',
- 'burlywood'=>'#deb887',
- 'cadetblue'=>'#5f9ea0',
- 'chartreuse'=>'#7fff00',
- 'chocolate'=>'#d2691e',
- 'coral'=>'#ff7f50',
- 'cornflowerblue'=>'#6495ed',
- 'cornsilk'=>'#fff8dc',
- 'crimson'=>'#dc143c',
- 'cyan'=>'#00ffff',
- 'darkblue'=>'#00008b',
- 'darkcyan'=>'#008b8b',
- 'darkgoldenrod'=>'#b8860b',
- 'darkgray'=>'#a9a9a9',
- 'darkgrey'=>'#a9a9a9',
- 'darkgreen'=>'#006400',
- 'darkkhaki'=>'#bdb76b',
- 'darkmagenta'=>'#8b008b',
- 'darkolivegreen'=>'#556b2f',
- 'darkorange'=>'#ff8c00',
- 'darkorchid'=>'#9932cc',
- 'darkred'=>'#8b0000',
- 'darksalmon'=>'#e9967a',
- 'darkseagreen'=>'#8fbc8f',
- 'darkslateblue'=>'#483d8b',
- 'darkslategray'=>'#2f4f4f',
- 'darkslategrey'=>'#2f4f4f',
- 'darkturquoise'=>'#00ced1',
- 'darkviolet'=>'#9400d3',
- 'deeppink'=>'#ff1493',
- 'deepskyblue'=>'#00bfff',
- 'dimgray'=>'#696969',
- 'dimgrey'=>'#696969',
- 'dodgerblue'=>'#1e90ff',
- 'firebrick'=>'#b22222',
- 'floralwhite'=>'#fffaf0',
- 'forestgreen'=>'#228b22',
- 'fuchsia'=>'#ff00ff',
- 'gainsboro'=>'#dcdcdc',
- 'ghostwhite'=>'#f8f8ff',
- 'gold'=>'#ffd700',
- 'goldenrod'=>'#daa520',
- 'gray'=>'#808080',
- 'grey'=>'#808080',
- 'green'=>'#008000',
- 'greenyellow'=>'#adff2f',
- 'honeydew'=>'#f0fff0',
- 'hotpink'=>'#ff69b4',
- 'indianred'=>'#cd5c5c',
- 'indigo'=>'#4b0082',
- 'ivory'=>'#fffff0',
- 'khaki'=>'#f0e68c',
- 'lavender'=>'#e6e6fa',
- 'lavenderblush'=>'#fff0f5',
- 'lawngreen'=>'#7cfc00',
- 'lemonchiffon'=>'#fffacd',
- 'lightblue'=>'#add8e6',
- 'lightcoral'=>'#f08080',
- 'lightcyan'=>'#e0ffff',
- 'lightgoldenrodyellow'=>'#fafad2',
- 'lightgray'=>'#d3d3d3',
- 'lightgrey'=>'#d3d3d3',
- 'lightgreen'=>'#90ee90',
- 'lightpink'=>'#ffb6c1',
- 'lightsalmon'=>'#ffa07a',
- 'lightseagreen'=>'#20b2aa',
- 'lightskyblue'=>'#87cefa',
- 'lightslategray'=>'#778899',
- 'lightslategrey'=>'#778899',
- 'lightsteelblue'=>'#b0c4de',
- 'lightyellow'=>'#ffffe0',
- 'lime'=>'#00ff00',
- 'limegreen'=>'#32cd32',
- 'linen'=>'#faf0e6',
- 'magenta'=>'#ff00ff',
- 'maroon'=>'#800000',
- 'mediumaquamarine'=>'#66cdaa',
- 'mediumblue'=>'#0000cd',
- 'mediumorchid'=>'#ba55d3',
- 'mediumpurple'=>'#9370d8',
- 'mediumseagreen'=>'#3cb371',
- 'mediumslateblue'=>'#7b68ee',
- 'mediumspringgreen'=>'#00fa9a',
- 'mediumturquoise'=>'#48d1cc',
- 'mediumvioletred'=>'#c71585',
- 'midnightblue'=>'#191970',
- 'mintcream'=>'#f5fffa',
- 'mistyrose'=>'#ffe4e1',
- 'moccasin'=>'#ffe4b5',
- 'navajowhite'=>'#ffdead',
- 'navy'=>'#000080',
- 'oldlace'=>'#fdf5e6',
- 'olive'=>'#808000',
- 'olivedrab'=>'#6b8e23',
- 'orange'=>'#ffa500',
- 'orangered'=>'#ff4500',
- 'orchid'=>'#da70d6',
- 'palegoldenrod'=>'#eee8aa',
- 'palegreen'=>'#98fb98',
- 'paleturquoise'=>'#afeeee',
- 'palevioletred'=>'#d87093',
- 'papayawhip'=>'#ffefd5',
- 'peachpuff'=>'#ffdab9',
- 'peru'=>'#cd853f',
- 'pink'=>'#ffc0cb',
- 'plum'=>'#dda0dd',
- 'powderblue'=>'#b0e0e6',
- 'purple'=>'#800080',
- 'red'=>'#ff0000',
- 'rosybrown'=>'#bc8f8f',
- 'royalblue'=>'#4169e1',
- 'saddlebrown'=>'#8b4513',
- 'salmon'=>'#fa8072',
- 'sandybrown'=>'#f4a460',
- 'seagreen'=>'#2e8b57',
- 'seashell'=>'#fff5ee',
- 'sienna'=>'#a0522d',
- 'silver'=>'#c0c0c0',
- 'skyblue'=>'#87ceeb',
- 'slateblue'=>'#6a5acd',
- 'slategray'=>'#708090',
- 'slategrey'=>'#708090',
- 'snow'=>'#fffafa',
- 'springgreen'=>'#00ff7f',
- 'steelblue'=>'#4682b4',
- 'tan'=>'#d2b48c',
- 'teal'=>'#008080',
- 'thistle'=>'#d8bfd8',
- 'tomato'=>'#ff6347',
- 'turquoise'=>'#40e0d0',
- 'violet'=>'#ee82ee',
- 'wheat'=>'#f5deb3',
- 'white'=>'#ffffff',
- 'whitesmoke'=>'#f5f5f5',
- 'yellow'=>'#ffff00',
- 'yellowgreen'=>'#9acd32'
- );
+ private const COLORS = [
+ 'aliceblue' => '#f0f8ff',
+ 'antiquewhite' => '#faebd7',
+ 'aqua' => '#00ffff',
+ 'aquamarine' => '#7fffd4',
+ 'azure' => '#f0ffff',
+ 'beige' => '#f5f5dc',
+ 'bisque' => '#ffe4c4',
+ 'black' => '#000000',
+ 'blanchedalmond' => '#ffebcd',
+ 'blue' => '#0000ff',
+ 'blueviolet' => '#8a2be2',
+ 'brown' => '#a52a2a',
+ 'burlywood' => '#deb887',
+ 'cadetblue' => '#5f9ea0',
+ 'chartreuse' => '#7fff00',
+ 'chocolate' => '#d2691e',
+ 'coral' => '#ff7f50',
+ 'cornflowerblue' => '#6495ed',
+ 'cornsilk' => '#fff8dc',
+ 'crimson' => '#dc143c',
+ 'cyan' => '#00ffff',
+ 'darkblue' => '#00008b',
+ 'darkcyan' => '#008b8b',
+ 'darkgoldenrod' => '#b8860b',
+ 'darkgray' => '#a9a9a9',
+ 'darkgrey' => '#a9a9a9',
+ 'darkgreen' => '#006400',
+ 'darkkhaki' => '#bdb76b',
+ 'darkmagenta' => '#8b008b',
+ 'darkolivegreen' => '#556b2f',
+ 'darkorange' => '#ff8c00',
+ 'darkorchid' => '#9932cc',
+ 'darkred' => '#8b0000',
+ 'darksalmon' => '#e9967a',
+ 'darkseagreen' => '#8fbc8f',
+ 'darkslateblue' => '#483d8b',
+ 'darkslategray' => '#2f4f4f',
+ 'darkslategrey' => '#2f4f4f',
+ 'darkturquoise' => '#00ced1',
+ 'darkviolet' => '#9400d3',
+ 'deeppink' => '#ff1493',
+ 'deepskyblue' => '#00bfff',
+ 'dimgray' => '#696969',
+ 'dimgrey' => '#696969',
+ 'dodgerblue' => '#1e90ff',
+ 'firebrick' => '#b22222',
+ 'floralwhite' => '#fffaf0',
+ 'forestgreen' => '#228b22',
+ 'fuchsia' => '#ff00ff',
+ 'gainsboro' => '#dcdcdc',
+ 'ghostwhite' => '#f8f8ff',
+ 'gold' => '#ffd700',
+ 'goldenrod' => '#daa520',
+ 'gray' => '#808080',
+ 'grey' => '#808080',
+ 'green' => '#008000',
+ 'greenyellow' => '#adff2f',
+ 'honeydew' => '#f0fff0',
+ 'hotpink' => '#ff69b4',
+ 'indianred' => '#cd5c5c',
+ 'indigo' => '#4b0082',
+ 'ivory' => '#fffff0',
+ 'khaki' => '#f0e68c',
+ 'lavender' => '#e6e6fa',
+ 'lavenderblush' => '#fff0f5',
+ 'lawngreen' => '#7cfc00',
+ 'lemonchiffon' => '#fffacd',
+ 'lightblue' => '#add8e6',
+ 'lightcoral' => '#f08080',
+ 'lightcyan' => '#e0ffff',
+ 'lightgoldenrodyellow' => '#fafad2',
+ 'lightgray' => '#d3d3d3',
+ 'lightgrey' => '#d3d3d3',
+ 'lightgreen' => '#90ee90',
+ 'lightpink' => '#ffb6c1',
+ 'lightsalmon' => '#ffa07a',
+ 'lightseagreen' => '#20b2aa',
+ 'lightskyblue' => '#87cefa',
+ 'lightslategray' => '#778899',
+ 'lightslategrey' => '#778899',
+ 'lightsteelblue' => '#b0c4de',
+ 'lightyellow' => '#ffffe0',
+ 'lime' => '#00ff00',
+ 'limegreen' => '#32cd32',
+ 'linen' => '#faf0e6',
+ 'magenta' => '#ff00ff',
+ 'maroon' => '#800000',
+ 'mediumaquamarine' => '#66cdaa',
+ 'mediumblue' => '#0000cd',
+ 'mediumorchid' => '#ba55d3',
+ 'mediumpurple' => '#9370d8',
+ 'mediumseagreen' => '#3cb371',
+ 'mediumslateblue' => '#7b68ee',
+ 'mediumspringgreen' => '#00fa9a',
+ 'mediumturquoise' => '#48d1cc',
+ 'mediumvioletred' => '#c71585',
+ 'midnightblue' => '#191970',
+ 'mintcream' => '#f5fffa',
+ 'mistyrose' => '#ffe4e1',
+ 'moccasin' => '#ffe4b5',
+ 'navajowhite' => '#ffdead',
+ 'navy' => '#000080',
+ 'oldlace' => '#fdf5e6',
+ 'olive' => '#808000',
+ 'olivedrab' => '#6b8e23',
+ 'orange' => '#ffa500',
+ 'orangered' => '#ff4500',
+ 'orchid' => '#da70d6',
+ 'palegoldenrod' => '#eee8aa',
+ 'palegreen' => '#98fb98',
+ 'paleturquoise' => '#afeeee',
+ 'palevioletred' => '#d87093',
+ 'papayawhip' => '#ffefd5',
+ 'peachpuff' => '#ffdab9',
+ 'peru' => '#cd853f',
+ 'pink' => '#ffc0cb',
+ 'plum' => '#dda0dd',
+ 'powderblue' => '#b0e0e6',
+ 'purple' => '#800080',
+ 'red' => '#ff0000',
+ 'rosybrown' => '#bc8f8f',
+ 'royalblue' => '#4169e1',
+ 'saddlebrown' => '#8b4513',
+ 'salmon' => '#fa8072',
+ 'sandybrown' => '#f4a460',
+ 'seagreen' => '#2e8b57',
+ 'seashell' => '#fff5ee',
+ 'sienna' => '#a0522d',
+ 'silver' => '#c0c0c0',
+ 'skyblue' => '#87ceeb',
+ 'slateblue' => '#6a5acd',
+ 'slategray' => '#708090',
+ 'slategrey' => '#708090',
+ 'snow' => '#fffafa',
+ 'springgreen' => '#00ff7f',
+ 'steelblue' => '#4682b4',
+ 'tan' => '#d2b48c',
+ 'teal' => '#008080',
+ 'thistle' => '#d8bfd8',
+ 'tomato' => '#ff6347',
+ 'turquoise' => '#40e0d0',
+ 'violet' => '#ee82ee',
+ 'wheat' => '#f5deb3',
+ 'white' => '#ffffff',
+ 'whitesmoke' => '#f5f5f5',
+ 'yellow' => '#ffff00',
+ 'yellowgreen' => '#9acd32',
+ ];
- public static function hasOwnProperty($color) {
- return isset(self::$colors[$color]);
+ /**
+ * @param string $color
+ * @return bool
+ */
+ public static function hasOwnProperty( string $color ): bool {
+ return isset( self::COLORS[$color] );
}
-
- public static function color($color) {
- return self::$colors[$color];
+ /**
+ * @param string $color Should be an existing color name,
+ * checked via hasOwnProperty()
+ * @return string the corresponding hexadecimal representation
+ */
+ public static function color( string $color ): string {
+ return self::COLORS[$color];
}
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Configurable.php b/vendor/wikimedia/less.php/lib/Less/Configurable.php
index aa7fd3eb7..ec16d801b 100644
--- a/vendor/wikimedia/less.php/lib/Less/Configurable.php
+++ b/vendor/wikimedia/less.php/lib/Less/Configurable.php
@@ -1,10 +1,6 @@
defaultOptions);
- $this->options = array_merge($this->defaultOptions, $this->options, $options);
+ public function setOptions( $options ) {
+ $options = array_intersect_key( $options, $this->defaultOptions );
+ $this->options = array_merge( $this->defaultOptions, $this->options, $options );
}
-
/**
* Get an option value by name
*
@@ -48,22 +40,21 @@ abstract class Less_Configurable {
* @param mixed $default Default value if confiuration of $name is not present
* @return mixed
*/
- public function getOption($name, $default = null){
- if(isset($this->options[$name])){
+ public function getOption( $name, $default = null ) {
+ if ( isset( $this->options[$name] ) ) {
return $this->options[$name];
}
return $default;
}
-
/**
* Set an option
*
* @param string $name
* @param mixed $value
*/
- public function setOption($name, $value){
+ public function setOption( $name, $value ) {
$this->options[$name] = $value;
}
-}
\ No newline at end of file
+}
diff --git a/vendor/wikimedia/less.php/lib/Less/Environment.php b/vendor/wikimedia/less.php/lib/Less/Environment.php
index b2203014f..bfc382550 100644
--- a/vendor/wikimedia/less.php/lib/Less/Environment.php
+++ b/vendor/wikimedia/less.php/lib/Less/Environment.php
@@ -1,41 +1,35 @@
',',
': ' => ':',
'' => '',
@@ -72,13 +64,13 @@ class Less_Environment{
'~' => '~',
'>' => '>',
'|' => '|',
- '^' => '^',
- '^^' => '^^'
- );
+ '^' => '^',
+ '^^' => '^^'
+ ];
- }else{
+ } else {
- Less_Environment::$_outputMap = array(
+ self::$_outputMap = [
',' => ', ',
': ' => ': ',
'' => '',
@@ -88,79 +80,74 @@ class Less_Environment{
'~' => ' ~ ',
'>' => ' > ',
'|' => '|',
- '^' => ' ^ ',
- '^^' => ' ^^ '
- );
+ '^' => ' ^ ',
+ '^^' => ' ^^ '
+ ];
}
}
-
- public function copyEvalEnv($frames = array() ){
+ public function copyEvalEnv( $frames = [] ) {
$new_env = new Less_Environment();
$new_env->frames = $frames;
return $new_env;
}
-
- public static function isMathOn(){
- return !Less_Parser::$options['strictMath'] || Less_Environment::$parensStack;
+ public static function isMathOn() {
+ return !Less_Parser::$options['strictMath'] || self::$parensStack;
}
- public static function isPathRelative($path){
- return !preg_match('/^(?:[a-z-]+:|\/)/',$path);
+ public static function isPathRelative( $path ) {
+ return !preg_match( '/^(?:[a-z-]+:|\/)/', $path );
}
-
/**
* Canonicalize a path by resolving references to '/./', '/../'
* Does not remove leading "../"
- * @param string path or url
+ * @param string $path or url
* @return string Canonicalized path
- *
*/
- public static function normalizePath($path){
+ public static function normalizePath( $path ) {
+ $segments = explode( '/', $path );
+ $segments = array_reverse( $segments );
- $segments = explode('/',$path);
- $segments = array_reverse($segments);
-
- $path = array();
+ $path = [];
$path_len = 0;
- while( $segments ){
- $segment = array_pop($segments);
- switch( $segment ) {
+ while ( $segments ) {
+ $segment = array_pop( $segments );
+ switch ( $segment ) {
case '.':
- break;
+ break;
case '..':
- if( !$path_len || ( $path[$path_len-1] === '..') ){
+ // @phan-suppress-next-line PhanTypeInvalidDimOffset False positive
+ if ( !$path_len || ( $path[$path_len - 1] === '..' ) ) {
$path[] = $segment;
$path_len++;
- }else{
- array_pop($path);
+ } else {
+ array_pop( $path );
$path_len--;
}
- break;
+ break;
default:
$path[] = $segment;
$path_len++;
- break;
+ break;
}
}
- return implode('/',$path);
+ return implode( '/', $path );
}
-
- public function unshiftFrame($frame){
- array_unshift($this->frames, $frame);
+ public function unshiftFrame( $frame ) {
+ array_unshift( $this->frames, $frame );
}
- public function shiftFrame(){
- return array_shift($this->frames);
+ public function shiftFrame() {
+ return array_shift( $this->frames );
}
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Exception/Chunk.php b/vendor/wikimedia/less.php/lib/Less/Exception/Chunk.php
index 0a4f4e507..8071eb85a 100644
--- a/vendor/wikimedia/less.php/lib/Less/Exception/Chunk.php
+++ b/vendor/wikimedia/less.php/lib/Less/Exception/Chunk.php
@@ -1,13 +1,8 @@
message = 'ParseError: Unexpected input'; //default message
+ public function __construct( $input, Exception $previous = null, $index = null, $currentFile = null, $code = 0 ) {
+ $this->message = 'ParseError: Unexpected input'; // default message
$this->index = $index;
$this->currentFile = $currentFile;
$this->input = $input;
- $this->input_len = strlen($input);
+ $this->input_len = strlen( $input );
$this->Chunks();
$this->genMessage();
}
-
/**
* See less.js chunks()
* We don't actually need the chunks
- *
*/
- protected function Chunks(){
+ protected function Chunks() {
$level = 0;
$parenLevel = 0;
$lastMultiCommentEndBrace = null;
@@ -54,14 +43,14 @@ class Less_Exception_Chunk extends Less_Exception_Parser{
$lastMultiComment = null;
$lastParen = null;
- for( $this->parserCurrentIndex = 0; $this->parserCurrentIndex < $this->input_len; $this->parserCurrentIndex++ ){
- $cc = $this->CharCode($this->parserCurrentIndex);
- if ((($cc >= 97) && ($cc <= 122)) || ($cc < 34)) {
+ for ( $this->parserCurrentIndex = 0; $this->parserCurrentIndex < $this->input_len; $this->parserCurrentIndex++ ) {
+ $cc = $this->CharCode( $this->parserCurrentIndex );
+ if ( ( ( $cc >= 97 ) && ( $cc <= 122 ) ) || ( $cc < 34 ) ) {
// a-z or whitespace
continue;
}
- switch ($cc) {
+ switch ( $cc ) {
// (
case 40:
@@ -72,14 +61,14 @@ class Less_Exception_Chunk extends Less_Exception_Parser{
// )
case 41:
$parenLevel--;
- if( $parenLevel < 0 ){
- return $this->fail("missing opening `(`");
+ if ( $parenLevel < 0 ) {
+ return $this->fail( "missing opening `(`" );
}
break;
// ;
case 59:
- //if (!$parenLevel) { $this->emitChunk(); }
+ // if (!$parenLevel) { $this->emitChunk(); }
break;
// {
@@ -91,16 +80,19 @@ class Less_Exception_Chunk extends Less_Exception_Parser{
// }
case 125:
$level--;
- if( $level < 0 ){
- return $this->fail("missing opening `{`");
+ if ( $level < 0 ) {
+ return $this->fail( "missing opening `{`" );
}
- //if (!$level && !$parenLevel) { $this->emitChunk(); }
+ // if (!$level && !$parenLevel) { $this->emitChunk(); }
break;
// \
case 92:
- if ($this->parserCurrentIndex < $this->input_len - 1) { $this->parserCurrentIndex++; break; }
- return $this->fail("unescaped `\\`");
+ if ( $this->parserCurrentIndex < $this->input_len - 1 ) {
+ $this->parserCurrentIndex++;
+ break;
+ }
+ return $this->fail( "unescaped `\\`" );
// ", ' and `
case 34:
@@ -108,87 +100,91 @@ class Less_Exception_Chunk extends Less_Exception_Parser{
case 96:
$matched = 0;
$currentChunkStartIndex = $this->parserCurrentIndex;
- for ($this->parserCurrentIndex = $this->parserCurrentIndex + 1; $this->parserCurrentIndex < $this->input_len; $this->parserCurrentIndex++) {
- $cc2 = $this->CharCode($this->parserCurrentIndex);
- if ($cc2 > 96) { continue; }
- if ($cc2 == $cc) { $matched = 1; break; }
- if ($cc2 == 92) { // \
- if ($this->parserCurrentIndex == $this->input_len - 1) {
- return $this->fail("unescaped `\\`");
+ for ( $this->parserCurrentIndex += 1; $this->parserCurrentIndex < $this->input_len; $this->parserCurrentIndex++ ) {
+ $cc2 = $this->CharCode( $this->parserCurrentIndex );
+ if ( $cc2 > 96 ) { continue;
+ }
+ if ( $cc2 == $cc ) { $matched = 1;
+break;
+ }
+ if ( $cc2 == 92 ) { // \
+ if ( $this->parserCurrentIndex == $this->input_len - 1 ) {
+ return $this->fail( "unescaped `\\`" );
}
$this->parserCurrentIndex++;
}
}
- if ($matched) { break; }
- return $this->fail("unmatched `" . chr($cc) . "`", $currentChunkStartIndex);
+ if ( $matched ) { break;
+ }
+ return $this->fail( "unmatched `" . chr( $cc ) . "`", $currentChunkStartIndex );
// /, check for comment
case 47:
- if ($parenLevel || ($this->parserCurrentIndex == $this->input_len - 1)) { break; }
- $cc2 = $this->CharCode($this->parserCurrentIndex+1);
- if ($cc2 == 47) {
+ if ( $parenLevel || ( $this->parserCurrentIndex == $this->input_len - 1 ) ) { break;
+ }
+ $cc2 = $this->CharCode( $this->parserCurrentIndex + 1 );
+ if ( $cc2 == 47 ) {
// //, find lnfeed
- for ($this->parserCurrentIndex = $this->parserCurrentIndex + 2; $this->parserCurrentIndex < $this->input_len; $this->parserCurrentIndex++) {
- $cc2 = $this->CharCode($this->parserCurrentIndex);
- if (($cc2 <= 13) && (($cc2 == 10) || ($cc2 == 13))) { break; }
+ for ( $this->parserCurrentIndex += 2; $this->parserCurrentIndex < $this->input_len; $this->parserCurrentIndex++ ) {
+ $cc2 = $this->CharCode( $this->parserCurrentIndex );
+ if ( ( $cc2 <= 13 ) && ( ( $cc2 == 10 ) || ( $cc2 == 13 ) ) ) { break;
+ }
}
- } else if ($cc2 == 42) {
+ } elseif ( $cc2 == 42 ) {
// /*, find */
$lastMultiComment = $currentChunkStartIndex = $this->parserCurrentIndex;
- for ($this->parserCurrentIndex = $this->parserCurrentIndex + 2; $this->parserCurrentIndex < $this->input_len - 1; $this->parserCurrentIndex++) {
- $cc2 = $this->CharCode($this->parserCurrentIndex);
- if ($cc2 == 125) { $lastMultiCommentEndBrace = $this->parserCurrentIndex; }
- if ($cc2 != 42) { continue; }
- if ($this->CharCode($this->parserCurrentIndex+1) == 47) { break; }
+ for ( $this->parserCurrentIndex += 2; $this->parserCurrentIndex < $this->input_len - 1; $this->parserCurrentIndex++ ) {
+ $cc2 = $this->CharCode( $this->parserCurrentIndex );
+ if ( $cc2 == 125 ) { $lastMultiCommentEndBrace = $this->parserCurrentIndex;
+ }
+ if ( $cc2 != 42 ) { continue;
+ }
+ if ( $this->CharCode( $this->parserCurrentIndex + 1 ) == 47 ) { break;
+ }
}
- if ($this->parserCurrentIndex == $this->input_len - 1) {
- return $this->fail("missing closing `*/`", $currentChunkStartIndex);
+ if ( $this->parserCurrentIndex == $this->input_len - 1 ) {
+ return $this->fail( "missing closing `*/`", $currentChunkStartIndex );
}
}
break;
// *, check for unmatched */
case 42:
- if (($this->parserCurrentIndex < $this->input_len - 1) && ($this->CharCode($this->parserCurrentIndex+1) == 47)) {
- return $this->fail("unmatched `/*`");
+ if ( ( $this->parserCurrentIndex < $this->input_len - 1 ) && ( $this->CharCode( $this->parserCurrentIndex + 1 ) == 47 ) ) {
+ return $this->fail( "unmatched `/*`" );
}
break;
}
}
- if( $level !== 0 ){
- if( ($lastMultiComment > $lastOpening) && ($lastMultiCommentEndBrace > $lastMultiComment) ){
- return $this->fail("missing closing `}` or `*/`", $lastOpening);
+ if ( $level !== 0 ) {
+ if ( ( $lastMultiComment > $lastOpening ) && ( $lastMultiCommentEndBrace > $lastMultiComment ) ) {
+ return $this->fail( "missing closing `}` or `*/`", $lastOpening );
} else {
- return $this->fail("missing closing `}`", $lastOpening);
+ return $this->fail( "missing closing `}`", $lastOpening );
}
- } else if ( $parenLevel !== 0 ){
- return $this->fail("missing closing `)`", $lastParen);
+ } elseif ( $parenLevel !== 0 ) {
+ return $this->fail( "missing closing `)`", $lastParen );
}
-
- //chunk didn't fail
-
+ // chunk didn't fail
//$this->emitChunk(true);
}
- public function CharCode($pos){
- return ord($this->input[$pos]);
+ public function CharCode( $pos ) {
+ return ord( $this->input[$pos] );
}
-
- public function fail( $msg, $index = null ){
-
- if( !$index ){
+ public function fail( $msg, $index = null ) {
+ if ( !$index ) {
$this->index = $this->parserCurrentIndex;
- }else{
+ } else {
$this->index = $index;
}
- $this->message = 'ParseError: '.$msg;
+ $this->message = 'ParseError: ' . $msg;
}
-
/*
function emitChunk( $force = false ){
$len = $this->parserCurrentIndex - $this->emitFrom;
diff --git a/vendor/wikimedia/less.php/lib/Less/Exception/Compiler.php b/vendor/wikimedia/less.php/lib/Less/Exception/Compiler.php
index 713e030d0..e963b6984 100644
--- a/vendor/wikimedia/less.php/lib/Less/Exception/Compiler.php
+++ b/vendor/wikimedia/less.php/lib/Less/Exception/Compiler.php
@@ -2,10 +2,7 @@
/**
* Compiler Exception
- *
- * @package Less
- * @subpackage exception
*/
-class Less_Exception_Compiler extends Less_Exception_Parser{
+class Less_Exception_Compiler extends Less_Exception_Parser {
-}
\ No newline at end of file
+}
diff --git a/vendor/wikimedia/less.php/lib/Less/Exception/Parser.php b/vendor/wikimedia/less.php/lib/Less/Exception/Parser.php
index f96b23c8d..22d9d1928 100644
--- a/vendor/wikimedia/less.php/lib/Less/Exception/Parser.php
+++ b/vendor/wikimedia/less.php/lib/Less/Exception/Parser.php
@@ -2,48 +2,36 @@
/**
* Parser Exception
- *
- * @package Less
- * @subpackage exception
*/
-class Less_Exception_Parser extends Exception{
+class Less_Exception_Parser extends Exception {
/**
* The current file
*
- * @var Less_ImportedFile
+ * @var array
*/
public $currentFile;
/**
* The current parser index
*
- * @var integer
+ * @var int
*/
public $index;
protected $input;
- protected $details = array();
-
+ protected $details = [];
/**
- * Constructor
- *
- * @param string $message
- * @param Exception $previous Previous exception
- * @param integer $index The current parser index
- * @param Less_FileInfo|string $currentFile The file
- * @param integer $code The exception code
+ * @param string|null $message
+ * @param Exception|null $previous Previous exception
+ * @param int|null $index The current parser index
+ * @param array|null $currentFile The file
+ * @param int $code The exception code
*/
- public function __construct($message = null, Exception $previous = null, $index = null, $currentFile = null, $code = 0){
-
- if (PHP_VERSION_ID < 50300) {
- $this->previous = $previous;
- parent::__construct($message, $code);
- } else {
- parent::__construct($message, $code, $previous);
- }
+ public function __construct( $message = null, Exception $previous = null, $index = null, $currentFile = null, $code = 0 ) {
+ parent::__construct( $message, $code, $previous );
$this->currentFile = $currentFile;
$this->index = $index;
@@ -51,74 +39,64 @@ class Less_Exception_Parser extends Exception{
$this->genMessage();
}
-
- protected function getInput(){
-
- if( !$this->input && $this->currentFile && $this->currentFile['filename'] && file_exists($this->currentFile['filename']) ){
+ protected function getInput() {
+ if ( !$this->input && $this->currentFile && $this->currentFile['filename'] && file_exists( $this->currentFile['filename'] ) ) {
$this->input = file_get_contents( $this->currentFile['filename'] );
}
}
-
-
/**
- * Converts the exception to string
- *
- * @return string
+ * Set a message based on the exception info
*/
- public function genMessage(){
-
- if( $this->currentFile && $this->currentFile['filename'] ){
- $this->message .= ' in '.basename($this->currentFile['filename']);
+ public function genMessage() {
+ if ( $this->currentFile && $this->currentFile['filename'] ) {
+ $this->message .= ' in ' . basename( $this->currentFile['filename'] );
}
- if( $this->index !== null ){
+ if ( $this->index !== null ) {
$this->getInput();
- if( $this->input ){
+ if ( $this->input ) {
$line = self::getLineNumber();
- $this->message .= ' on line '.$line.', column '.self::getColumn();
+ $this->message .= ' on line ' . $line . ', column ' . self::getColumn();
- $lines = explode("\n",$this->input);
+ $lines = explode( "\n", $this->input );
- $count = count($lines);
- $start_line = max(0, $line-3);
- $last_line = min($count, $start_line+6);
- $num_len = strlen($last_line);
- for( $i = $start_line; $i < $last_line; $i++ ){
- $this->message .= "\n".str_pad($i+1,$num_len,'0',STR_PAD_LEFT).'| '.$lines[$i];
+ $count = count( $lines );
+ $start_line = max( 0, $line - 3 );
+ $last_line = min( $count, $start_line + 6 );
+ $num_len = strlen( $last_line );
+ for ( $i = $start_line; $i < $last_line; $i++ ) {
+ $this->message .= "\n" . str_pad( (string)( $i + 1 ), $num_len, '0', STR_PAD_LEFT ) . '| ' . $lines[$i];
}
}
}
-
}
/**
* Returns the line number the error was encountered
*
- * @return integer
+ * @return int
*/
- public function getLineNumber(){
- if( $this->index ){
+ public function getLineNumber() {
+ if ( $this->index ) {
// https://bugs.php.net/bug.php?id=49790
- if (ini_get("mbstring.func_overload")) {
- return substr_count(substr($this->input, 0, $this->index), "\n") + 1;
+ if ( ini_get( "mbstring.func_overload" ) ) {
+ return substr_count( substr( $this->input, 0, $this->index ), "\n" ) + 1;
} else {
- return substr_count($this->input, "\n", 0, $this->index) + 1;
+ return substr_count( $this->input, "\n", 0, $this->index ) + 1;
}
}
return 1;
}
-
/**
* Returns the column the error was encountered
*
- * @return integer
+ * @return int
*/
- public function getColumn(){
-
- $part = substr($this->input, 0, $this->index);
- $pos = strrpos($part,"\n");
+ public function getColumn() {
+ $part = substr( $this->input, 0, $this->index );
+ $pos = strrpos( $part, "\n" );
return $this->index - $pos;
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Functions.php b/vendor/wikimedia/less.php/lib/Less/Functions.php
index a61e5ac3c..43a964c6e 100644
--- a/vendor/wikimedia/less.php/lib/Less/Functions.php
+++ b/vendor/wikimedia/less.php/lib/Less/Functions.php
@@ -2,414 +2,429 @@
/**
* Builtin functions
- *
- * @package Less
- * @subpackage function
- * @see http://lesscss.org/functions/
+ * @see https://lesscss.org/functions/
*/
-class Less_Functions{
+class Less_Functions {
public $env;
public $currentFileInfo;
- function __construct($env, $currentFileInfo = null ){
+ function __construct( $env, array $currentFileInfo = null ) {
$this->env = $env;
$this->currentFileInfo = $currentFileInfo;
}
/**
* @param string $op
+ * @param float $a
+ * @param float $b
*/
- public static function operate( $op, $a, $b ){
- switch ($op) {
- case '+': return $a + $b;
- case '-': return $a - $b;
- case '*': return $a * $b;
- case '/': return $a / $b;
+ public static function operate( $op, $a, $b ) {
+ switch ( $op ) {
+ case '+':
+ return $a + $b;
+ case '-':
+ return $a - $b;
+ case '*':
+ return $a * $b;
+ case '/':
+ return $a / $b;
}
}
- public static function clamp($val, $max = 1){
- return min( max($val, 0), $max);
+ public static function clamp( $val, $max = 1 ) {
+ return min( max( $val, 0 ), $max );
}
- public static function fround( $value ){
-
- if( $value === 0 ){
+ public static function fround( $value ) {
+ if ( $value === 0 ) {
return $value;
}
- if( Less_Parser::$options['numPrecision'] ){
- $p = pow(10, Less_Parser::$options['numPrecision']);
- return round( $value * $p) / $p;
+ if ( Less_Parser::$options['numPrecision'] ) {
+ $p = pow( 10, Less_Parser::$options['numPrecision'] );
+ return round( $value * $p ) / $p;
}
return $value;
}
- public static function number($n){
-
- if ($n instanceof Less_Tree_Dimension) {
- return floatval( $n->unit->is('%') ? $n->value / 100 : $n->value);
- } else if (is_numeric($n)) {
+ public static function number( $n ) {
+ if ( $n instanceof Less_Tree_Dimension ) {
+ return floatval( $n->unit->is( '%' ) ? $n->value / 100 : $n->value );
+ } elseif ( is_numeric( $n ) ) {
return $n;
} else {
- throw new Less_Exception_Compiler("color functions take numbers as parameters");
+ throw new Less_Exception_Compiler( "color functions take numbers as parameters" );
}
}
- public static function scaled($n, $size = 255 ){
- if( $n instanceof Less_Tree_Dimension && $n->unit->is('%') ){
+ public static function scaled( $n, $size = 255 ) {
+ if ( $n instanceof Less_Tree_Dimension && $n->unit->is( '%' ) ) {
return (float)$n->value * $size / 100;
} else {
- return Less_Functions::number($n);
+ return self::number( $n );
}
}
- public function rgb ($r = null, $g = null, $b = null){
- if (is_null($r) || is_null($g) || is_null($b)) {
- throw new Less_Exception_Compiler("rgb expects three parameters");
+ public function rgb( $r = null, $g = null, $b = null ) {
+ if ( $r === null || $g === null || $b === null ) {
+ throw new Less_Exception_Compiler( "rgb expects three parameters" );
}
- return $this->rgba($r, $g, $b, 1.0);
+ return $this->rgba( $r, $g, $b, 1.0 );
}
- public function rgba($r = null, $g = null, $b = null, $a = null){
- $rgb = array($r, $g, $b);
- $rgb = array_map(array('Less_Functions','scaled'),$rgb);
+ public function rgba( $r = null, $g = null, $b = null, $a = null ) {
+ $rgb = [ $r, $g, $b ];
+ $rgb = array_map( [ 'Less_Functions','scaled' ], $rgb );
- $a = self::number($a);
- return new Less_Tree_Color($rgb, $a);
+ $a = self::number( $a );
+ return new Less_Tree_Color( $rgb, $a );
}
- public function hsl($h, $s, $l){
- return $this->hsla($h, $s, $l, 1.0);
+ public function hsl( $h, $s, $l ) {
+ return $this->hsla( $h, $s, $l, 1.0 );
}
- public function hsla($h, $s, $l, $a){
+ public function hsla( $h, $s, $l, $a ) {
+ $h = fmod( self::number( $h ), 360 ) / 360; // Classic % operator will change float to int
+ $s = self::clamp( self::number( $s ) );
+ $l = self::clamp( self::number( $l ) );
+ $a = self::clamp( self::number( $a ) );
- $h = fmod(self::number($h), 360) / 360; // Classic % operator will change float to int
- $s = self::clamp(self::number($s));
- $l = self::clamp(self::number($l));
- $a = self::clamp(self::number($a));
-
- $m2 = $l <= 0.5 ? $l * ($s + 1) : $l + $s - $l * $s;
+ $m2 = $l <= 0.5 ? $l * ( $s + 1 ) : $l + $s - $l * $s;
$m1 = $l * 2 - $m2;
- return $this->rgba( self::hsla_hue($h + 1/3, $m1, $m2) * 255,
- self::hsla_hue($h, $m1, $m2) * 255,
- self::hsla_hue($h - 1/3, $m1, $m2) * 255,
- $a);
+ return $this->rgba(
+ self::hsla_hue( $h + 1 / 3, $m1, $m2 ) * 255,
+ self::hsla_hue( $h, $m1, $m2 ) * 255,
+ self::hsla_hue( $h - 1 / 3, $m1, $m2 ) * 255,
+ $a
+ );
}
/**
- * @param double $h
+ * @param float $h
+ * @param float $m1
+ * @param float $m2
*/
- public function hsla_hue($h, $m1, $m2){
- $h = $h < 0 ? $h + 1 : ($h > 1 ? $h - 1 : $h);
- if ($h * 6 < 1) return $m1 + ($m2 - $m1) * $h * 6;
- else if ($h * 2 < 1) return $m2;
- else if ($h * 3 < 2) return $m1 + ($m2 - $m1) * (2/3 - $h) * 6;
- else return $m1;
+ public function hsla_hue( $h, $m1, $m2 ) {
+ $h = $h < 0 ? $h + 1 : ( $h > 1 ? $h - 1 : $h );
+ if ( $h * 6 < 1 ) {
+ return $m1 + ( $m2 - $m1 ) * $h * 6;
+ } elseif ( $h * 2 < 1 ) {
+ return $m2;
+ } elseif ( $h * 3 < 2 ) {
+ return $m1 + ( $m2 - $m1 ) * ( 2 / 3 - $h ) * 6;
+ } else {
+ return $m1;
+ }
}
- public function hsv($h, $s, $v) {
- return $this->hsva($h, $s, $v, 1.0);
+ public function hsv( $h, $s, $v ) {
+ return $this->hsva( $h, $s, $v, 1.0 );
}
/**
- * @param double $a
+ * @param Less_Tree|float $h
+ * @param Less_Tree|float $s
+ * @param Less_Tree|float $v
+ * @param float $a
*/
- public function hsva($h, $s, $v, $a) {
- $h = ((Less_Functions::number($h) % 360) / 360 ) * 360;
- $s = Less_Functions::number($s);
- $v = Less_Functions::number($v);
- $a = Less_Functions::number($a);
+ public function hsva( $h, $s, $v, $a ) {
+ $h = ( ( self::number( $h ) % 360 ) / 360 ) * 360;
+ $s = self::number( $s );
+ $v = self::number( $v );
+ $a = self::number( $a );
- $i = floor(($h / 60) % 6);
- $f = ($h / 60) - $i;
+ $i = floor( (int)( $h / 60 ) % 6 );
+ $f = ( $h / 60 ) - $i;
- $vs = array( $v,
- $v * (1 - $s),
- $v * (1 - $f * $s),
- $v * (1 - (1 - $f) * $s));
+ $vs = [
+ $v,
+ $v * ( 1 - $s ),
+ $v * ( 1 - $f * $s ),
+ $v * ( 1 - ( 1 - $f ) * $s )
+ ];
- $perm = array(array(0, 3, 1),
- array(2, 0, 1),
- array(1, 0, 3),
- array(1, 2, 0),
- array(3, 1, 0),
- array(0, 1, 2));
+ $perm = [
+ [ 0, 3, 1 ],
+ [ 2, 0, 1 ],
+ [ 1, 0, 3 ],
+ [ 1, 2, 0 ],
+ [ 3, 1, 0 ],
+ [ 0, 1, 2 ]
+ ];
- return $this->rgba($vs[$perm[$i][0]] * 255,
- $vs[$perm[$i][1]] * 255,
- $vs[$perm[$i][2]] * 255,
- $a);
+ return $this->rgba(
+ $vs[$perm[$i][0]] * 255,
+ $vs[$perm[$i][1]] * 255,
+ $vs[$perm[$i][2]] * 255,
+ $a
+ );
}
- public function hue($color = null){
- if (!$color instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to hue must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function hue( $color = null ) {
+ if ( !$color instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to hue must be a color' . ( $color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
$c = $color->toHSL();
- return new Less_Tree_Dimension(Less_Parser::round($c['h']));
+ return new Less_Tree_Dimension( Less_Parser::round( $c['h'] ) );
}
- public function saturation($color = null){
- if (!$color instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to saturation must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function saturation( $color = null ) {
+ if ( !$color instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to saturation must be a color' . ( $color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
$c = $color->toHSL();
- return new Less_Tree_Dimension(Less_Parser::round($c['s'] * 100), '%');
+ return new Less_Tree_Dimension( Less_Parser::round( $c['s'] * 100 ), '%' );
}
- public function lightness($color = null){
- if (!$color instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to lightness must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function lightness( $color = null ) {
+ if ( !$color instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to lightness must be a color' . ( $color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
$c = $color->toHSL();
- return new Less_Tree_Dimension(Less_Parser::round($c['l'] * 100), '%');
+ return new Less_Tree_Dimension( Less_Parser::round( $c['l'] * 100 ), '%' );
}
- public function hsvhue( $color = null ){
- if (!$color instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to hsvhue must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function hsvhue( $color = null ) {
+ if ( !$color instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to hsvhue must be a color' . ( $color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
$hsv = $color->toHSV();
- return new Less_Tree_Dimension( Less_Parser::round($hsv['h']) );
+ return new Less_Tree_Dimension( Less_Parser::round( $hsv['h'] ) );
}
-
- public function hsvsaturation( $color = null ){
- if (!$color instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to hsvsaturation must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function hsvsaturation( $color = null ) {
+ if ( !$color instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to hsvsaturation must be a color' . ( $color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
$hsv = $color->toHSV();
- return new Less_Tree_Dimension( Less_Parser::round($hsv['s'] * 100), '%' );
+ return new Less_Tree_Dimension( Less_Parser::round( $hsv['s'] * 100 ), '%' );
}
- public function hsvvalue( $color = null ){
- if (!$color instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to hsvvalue must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function hsvvalue( $color = null ) {
+ if ( !$color instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to hsvvalue must be a color' . ( $color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
$hsv = $color->toHSV();
- return new Less_Tree_Dimension( Less_Parser::round($hsv['v'] * 100), '%' );
+ return new Less_Tree_Dimension( Less_Parser::round( $hsv['v'] * 100 ), '%' );
}
- public function red($color = null) {
- if (!$color instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to red must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function red( $color = null ) {
+ if ( !$color instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to red must be a color' . ( $color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
return new Less_Tree_Dimension( $color->rgb[0] );
}
- public function green($color = null) {
- if (!$color instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to green must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function green( $color = null ) {
+ if ( !$color instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to green must be a color' . ( $color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
return new Less_Tree_Dimension( $color->rgb[1] );
}
- public function blue($color = null) {
- if (!$color instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to blue must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function blue( $color = null ) {
+ if ( !$color instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to blue must be a color' . ( $color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
return new Less_Tree_Dimension( $color->rgb[2] );
}
- public function alpha($color = null){
- if (!$color instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to alpha must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function alpha( $color = null ) {
+ if ( !$color instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to alpha must be a color' . ( $color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
$c = $color->toHSL();
- return new Less_Tree_Dimension($c['a']);
+ return new Less_Tree_Dimension( $c['a'] );
}
- public function luma ($color = null) {
- if (!$color instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to luma must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function luma( $color = null ) {
+ if ( !$color instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to luma must be a color' . ( $color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- return new Less_Tree_Dimension(Less_Parser::round( $color->luma() * $color->alpha * 100), '%');
+ return new Less_Tree_Dimension( Less_Parser::round( $color->luma() * $color->alpha * 100 ), '%' );
}
- public function luminance( $color = null ){
- if (!$color instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to luminance must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function luminance( $color = null ) {
+ if ( !$color instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to luminance must be a color' . ( $color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
$luminance =
- (0.2126 * $color->rgb[0] / 255)
- + (0.7152 * $color->rgb[1] / 255)
- + (0.0722 * $color->rgb[2] / 255);
+ ( 0.2126 * $color->rgb[0] / 255 )
+ + ( 0.7152 * $color->rgb[1] / 255 )
+ + ( 0.0722 * $color->rgb[2] / 255 );
- return new Less_Tree_Dimension(Less_Parser::round( $luminance * $color->alpha * 100), '%');
+ return new Less_Tree_Dimension( Less_Parser::round( $luminance * $color->alpha * 100 ), '%' );
}
- public function saturate($color = null, $amount = null){
+ public function saturate( $color = null, $amount = null ) {
// filter: saturate(3.2);
// should be kept as is, so check for color
- if ($color instanceof Less_Tree_Dimension) {
+ if ( $color instanceof Less_Tree_Dimension ) {
return null;
}
- if (!$color instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to saturate must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ if ( !$color instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to saturate must be a color' . ( $color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- if (!$amount instanceof Less_Tree_Dimension) {
- throw new Less_Exception_Compiler('The second argument to saturate must be a percentage' . ($amount instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ if ( !$amount instanceof Less_Tree_Dimension ) {
+ throw new Less_Exception_Compiler( 'The second argument to saturate must be a percentage' . ( $amount instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
$hsl = $color->toHSL();
$hsl['s'] += $amount->value / 100;
- $hsl['s'] = self::clamp($hsl['s']);
+ $hsl['s'] = self::clamp( $hsl['s'] );
- return $this->hsla($hsl['h'], $hsl['s'], $hsl['l'], $hsl['a']);
+ return $this->hsla( $hsl['h'], $hsl['s'], $hsl['l'], $hsl['a'] );
}
/**
- * @param Less_Tree_Dimension $amount
+ * @param Less_Tree_Color|null $color
+ * @param Less_Tree_Dimension|null $amount
*/
- public function desaturate($color = null, $amount = null){
- if (!$color instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to desaturate must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function desaturate( $color = null, $amount = null ) {
+ if ( !$color instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to desaturate must be a color' . ( $color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- if (!$amount instanceof Less_Tree_Dimension) {
- throw new Less_Exception_Compiler('The second argument to desaturate must be a percentage' . ($amount instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ if ( !$amount instanceof Less_Tree_Dimension ) {
+ throw new Less_Exception_Compiler( 'The second argument to desaturate must be a percentage' . ( $amount instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
$hsl = $color->toHSL();
-
$hsl['s'] -= $amount->value / 100;
- $hsl['s'] = self::clamp($hsl['s']);
+ $hsl['s'] = self::clamp( $hsl['s'] );
- return $this->hsla($hsl['h'], $hsl['s'], $hsl['l'], $hsl['a']);
+ return $this->hsla( $hsl['h'], $hsl['s'], $hsl['l'], $hsl['a'] );
}
-
-
- public function lighten($color = null, $amount=null){
- if (!$color instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to lighten must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function lighten( $color = null, $amount = null ) {
+ if ( !$color instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to lighten must be a color' . ( $color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- if (!$amount instanceof Less_Tree_Dimension) {
- throw new Less_Exception_Compiler('The second argument to lighten must be a percentage' . ($amount instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ if ( !$amount instanceof Less_Tree_Dimension ) {
+ throw new Less_Exception_Compiler( 'The second argument to lighten must be a percentage' . ( $amount instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
$hsl = $color->toHSL();
$hsl['l'] += $amount->value / 100;
- $hsl['l'] = self::clamp($hsl['l']);
+ $hsl['l'] = self::clamp( $hsl['l'] );
- return $this->hsla($hsl['h'], $hsl['s'], $hsl['l'], $hsl['a']);
+ return $this->hsla( $hsl['h'], $hsl['s'], $hsl['l'], $hsl['a'] );
}
- public function darken($color = null, $amount = null){
- if (!$color instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to darken must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function darken( $color = null, $amount = null ) {
+ if ( !$color instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to darken must be a color' . ( $color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- if (!$amount instanceof Less_Tree_Dimension) {
- throw new Less_Exception_Compiler('The second argument to darken must be a percentage' . ($amount instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ if ( !$amount instanceof Less_Tree_Dimension ) {
+ throw new Less_Exception_Compiler( 'The second argument to darken must be a percentage' . ( $amount instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
$hsl = $color->toHSL();
$hsl['l'] -= $amount->value / 100;
- $hsl['l'] = self::clamp($hsl['l']);
+ $hsl['l'] = self::clamp( $hsl['l'] );
- return $this->hsla($hsl['h'], $hsl['s'], $hsl['l'], $hsl['a']);
+ return $this->hsla( $hsl['h'], $hsl['s'], $hsl['l'], $hsl['a'] );
}
- public function fadein($color = null, $amount = null){
- if (!$color instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to fadein must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function fadein( $color = null, $amount = null ) {
+ if ( !$color instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to fadein must be a color' . ( $color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- if (!$amount instanceof Less_Tree_Dimension) {
- throw new Less_Exception_Compiler('The second argument to fadein must be a percentage' . ($amount instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ if ( !$amount instanceof Less_Tree_Dimension ) {
+ throw new Less_Exception_Compiler( 'The second argument to fadein must be a percentage' . ( $amount instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
$hsl = $color->toHSL();
$hsl['a'] += $amount->value / 100;
- $hsl['a'] = self::clamp($hsl['a']);
- return $this->hsla($hsl['h'], $hsl['s'], $hsl['l'], $hsl['a']);
+ $hsl['a'] = self::clamp( $hsl['a'] );
+ return $this->hsla( $hsl['h'], $hsl['s'], $hsl['l'], $hsl['a'] );
}
- public function fadeout($color = null, $amount = null){
- if (!$color instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to fadeout must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function fadeout( $color = null, $amount = null ) {
+ if ( !$color instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to fadeout must be a color' . ( $color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- if (!$amount instanceof Less_Tree_Dimension) {
- throw new Less_Exception_Compiler('The second argument to fadeout must be a percentage' . ($amount instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ if ( !$amount instanceof Less_Tree_Dimension ) {
+ throw new Less_Exception_Compiler( 'The second argument to fadeout must be a percentage' . ( $amount instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
$hsl = $color->toHSL();
$hsl['a'] -= $amount->value / 100;
- $hsl['a'] = self::clamp($hsl['a']);
- return $this->hsla($hsl['h'], $hsl['s'], $hsl['l'], $hsl['a']);
+ $hsl['a'] = self::clamp( $hsl['a'] );
+ return $this->hsla( $hsl['h'], $hsl['s'], $hsl['l'], $hsl['a'] );
}
- public function fade($color = null, $amount = null){
- if (!$color instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to fade must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function fade( $color = null, $amount = null ) {
+ if ( !$color instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to fade must be a color' . ( $color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- if (!$amount instanceof Less_Tree_Dimension) {
- throw new Less_Exception_Compiler('The second argument to fade must be a percentage' . ($amount instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ if ( !$amount instanceof Less_Tree_Dimension ) {
+ throw new Less_Exception_Compiler( 'The second argument to fade must be a percentage' . ( $amount instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
$hsl = $color->toHSL();
$hsl['a'] = $amount->value / 100;
- $hsl['a'] = self::clamp($hsl['a']);
- return $this->hsla($hsl['h'], $hsl['s'], $hsl['l'], $hsl['a']);
+ $hsl['a'] = self::clamp( $hsl['a'] );
+ return $this->hsla( $hsl['h'], $hsl['s'], $hsl['l'], $hsl['a'] );
}
-
-
- public function spin($color = null, $amount = null){
- if (!$color instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to spin must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function spin( $color = null, $amount = null ) {
+ if ( !$color instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to spin must be a color' . ( $color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- if (!$amount instanceof Less_Tree_Dimension) {
- throw new Less_Exception_Compiler('The second argument to spin must be a number' . ($amount instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ if ( !$amount instanceof Less_Tree_Dimension ) {
+ throw new Less_Exception_Compiler( 'The second argument to spin must be a number' . ( $amount instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
$hsl = $color->toHSL();
- $hue = fmod($hsl['h'] + $amount->value, 360);
+ $hue = fmod( $hsl['h'] + $amount->value, 360 );
$hsl['h'] = $hue < 0 ? 360 + $hue : $hue;
- return $this->hsla($hsl['h'], $hsl['s'], $hsl['l'], $hsl['a']);
+ return $this->hsla( $hsl['h'], $hsl['s'], $hsl['l'], $hsl['a'] );
}
//
// Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
- // http://sass-lang.com
+ // https://sass-lang.com/
//
/**
- * @param Less_Tree_Color $color1
+ * @param Less_Tree|null $color1
+ * @param Less_Tree|null $color2
+ * @param Less_Tree|null $weight
*/
- public function mix($color1 = null, $color2 = null, $weight = null){
- if (!$color1 instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to mix must be a color' . ($color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function mix( $color1 = null, $color2 = null, $weight = null ) {
+ if ( !$color1 instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to mix must be a color' . ( $color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- if (!$color2 instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The second argument to mix must be a color' . ($color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ if ( !$color2 instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The second argument to mix must be a color' . ( $color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- if (!$weight) {
- $weight = new Less_Tree_Dimension('50', '%');
+ if ( !$weight ) {
+ $weight = new Less_Tree_Dimension( '50', '%' );
}
- if (!$weight instanceof Less_Tree_Dimension) {
- throw new Less_Exception_Compiler('The third argument to contrast must be a percentage' . ($weight instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ if ( !$weight instanceof Less_Tree_Dimension ) {
+ throw new Less_Exception_Compiler( 'The third argument to contrast must be a percentage' . ( $weight instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
$p = $weight->value / 100.0;
@@ -418,144 +433,142 @@ class Less_Functions{
$hsl2 = $color2->toHSL();
$a = $hsl1['a'] - $hsl2['a'];
- $w1 = (((($w * $a) == -1) ? $w : ($w + $a) / (1 + $w * $a)) + 1) / 2;
+ $w1 = ( ( ( ( $w * $a ) == -1 ) ? $w : ( $w + $a ) / ( 1 + $w * $a ) ) + 1 ) / 2;
$w2 = 1 - $w1;
- $rgb = array($color1->rgb[0] * $w1 + $color2->rgb[0] * $w2,
- $color1->rgb[1] * $w1 + $color2->rgb[1] * $w2,
- $color1->rgb[2] * $w1 + $color2->rgb[2] * $w2);
+ $rgb = [
+ $color1->rgb[0] * $w1 + $color2->rgb[0] * $w2,
+ $color1->rgb[1] * $w1 + $color2->rgb[1] * $w2,
+ $color1->rgb[2] * $w1 + $color2->rgb[2] * $w2
+ ];
- $alpha = $color1->alpha * $p + $color2->alpha * (1 - $p);
+ $alpha = $color1->alpha * $p + $color2->alpha * ( 1 - $p );
- return new Less_Tree_Color($rgb, $alpha);
+ return new Less_Tree_Color( $rgb, $alpha );
}
- public function greyscale($color){
- return $this->desaturate($color, new Less_Tree_Dimension(100,'%'));
+ public function greyscale( $color ) {
+ return $this->desaturate( $color, new Less_Tree_Dimension( 100, '%' ) );
}
-
- public function contrast( $color, $dark = null, $light = null, $threshold = null){
+ public function contrast( $color, $dark = null, $light = null, $threshold = null ) {
// filter: contrast(3.2);
// should be kept as is, so check for color
- if (!$color instanceof Less_Tree_Color) {
+ if ( !$color instanceof Less_Tree_Color ) {
return null;
}
- if( !$light ){
- $light = $this->rgba(255, 255, 255, 1.0);
+ if ( !$light ) {
+ $light = $this->rgba( 255, 255, 255, 1.0 );
}
- if( !$dark ){
- $dark = $this->rgba(0, 0, 0, 1.0);
+ if ( !$dark ) {
+ $dark = $this->rgba( 0, 0, 0, 1.0 );
}
- if (!$dark instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The second argument to contrast must be a color' . ($dark instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ if ( !$dark instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The second argument to contrast must be a color' . ( $dark instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- if (!$light instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The third argument to contrast must be a color' . ($light instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ if ( !$light instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The third argument to contrast must be a color' . ( $light instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- //Figure out which is actually light and dark!
- if( $dark->luma() > $light->luma() ){
+ // Figure out which is actually light and dark!
+ if ( $dark->luma() > $light->luma() ) {
$t = $light;
$light = $dark;
$dark = $t;
}
- if( !$threshold ){
+ if ( !$threshold ) {
$threshold = 0.43;
} else {
- $threshold = Less_Functions::number($threshold);
+ $threshold = self::number( $threshold );
}
- if( $color->luma() < $threshold ){
+ if ( $color->luma() < $threshold ) {
return $light;
} else {
return $dark;
}
}
- public function e ($str){
- if( is_string($str) ){
- return new Less_Tree_Anonymous($str);
+ public function e( $str ) {
+ if ( is_string( $str ) ) {
+ return new Less_Tree_Anonymous( $str );
}
- return new Less_Tree_Anonymous($str instanceof Less_Tree_JavaScript ? $str->expression : $str->value);
+ return new Less_Tree_Anonymous( $str instanceof Less_Tree_JavaScript ? $str->expression : $str->value );
}
- public function escape ($str){
+ public function escape( $str ) {
+ $revert = [ '%21' => '!', '%2A' => '*', '%27' => "'",'%3F' => '?','%26' => '&','%2C' => ',','%2F' => '/','%40' => '@','%2B' => '+','%24' => '$' ];
- $revert = array('%21'=>'!', '%2A'=>'*', '%27'=>"'",'%3F'=>'?','%26'=>'&','%2C'=>',','%2F'=>'/','%40'=>'@','%2B'=>'+','%24'=>'$');
-
- return new Less_Tree_Anonymous(strtr(rawurlencode($str->value), $revert));
+ return new Less_Tree_Anonymous( strtr( rawurlencode( $str->value ), $revert ) );
}
-
/**
* todo: This function will need some additional work to make it work the same as less.js
*
*/
- public function replace( $string, $pattern, $replacement, $flags = null ){
+ public function replace( $string, $pattern, $replacement, $flags = null ) {
$result = $string->value;
- $expr = '/'.str_replace('/','\\/',$pattern->value).'/';
- if( $flags && $flags->value){
- $expr .= self::replace_flags($flags->value);
+ $expr = '/' . str_replace( '/', '\\/', $pattern->value ) . '/';
+ if ( $flags && $flags->value ) {
+ $expr .= self::replace_flags( $flags->value );
}
- $result = preg_replace($expr,$replacement->value,$result);
+ $result = preg_replace( $expr, $replacement->value, $result );
-
- if( property_exists($string,'quote') ){
- return new Less_Tree_Quoted( $string->quote, $result, $string->escaped);
+ if ( property_exists( $string, 'quote' ) ) {
+ return new Less_Tree_Quoted( $string->quote, $result, $string->escaped );
}
return new Less_Tree_Quoted( '', $result );
}
- public static function replace_flags($flags){
- $flags = str_split($flags,1);
+ public static function replace_flags( $flags ) {
+ $flags = str_split( $flags, 1 );
$new_flags = '';
- foreach($flags as $flag){
- switch($flag){
+ foreach ( $flags as $flag ) {
+ switch ( $flag ) {
case 'e':
case 'g':
- break;
+ break;
default:
$new_flags .= $flag;
- break;
+ break;
}
}
return $new_flags;
}
- public function _percent(){
- $string = func_get_arg(0);
+ public function _percent() {
+ $string = func_get_arg( 0 );
$args = func_get_args();
- array_shift($args);
+ array_shift( $args );
$result = $string->value;
- foreach($args as $arg){
- if( preg_match('/%[sda]/i',$result, $token) ){
+ foreach ( $args as $arg ) {
+ if ( preg_match( '/%[sda]/i', $result, $token ) ) {
$token = $token[0];
- $value = stristr($token, 's') ? $arg->value : $arg->toCSS();
- $value = preg_match('/[A-Z]$/', $token) ? urlencode($value) : $value;
- $result = preg_replace('/%[sda]/i',$value, $result, 1);
+ $value = stristr( $token, 's' ) ? $arg->value : $arg->toCSS();
+ $value = preg_match( '/[A-Z]$/', $token ) ? urlencode( $value ) : $value;
+ $result = preg_replace( '/%[sda]/i', $value, $result, 1 );
}
}
- $result = str_replace('%%', '%', $result);
+ $result = str_replace( '%%', '%', $result );
- return new Less_Tree_Quoted( $string->quote , $result, $string->escaped);
+ return new Less_Tree_Quoted( $string->quote, $result, $string->escaped );
}
- public function unit( $val, $unit = null) {
- if( !($val instanceof Less_Tree_Dimension) ){
- throw new Less_Exception_Compiler('The first argument to unit must be a number' . ($val instanceof Less_Tree_Operation ? '. Have you forgotten parenthesis?' : '.') );
+ public function unit( $val, $unit = null ) {
+ if ( !( $val instanceof Less_Tree_Dimension ) ) {
+ throw new Less_Exception_Compiler( 'The first argument to unit must be a number' . ( $val instanceof Less_Tree_Operation ? '. Have you forgotten parenthesis?' : '.' ) );
}
- if( $unit ){
- if( $unit instanceof Less_Tree_Keyword ){
+ if ( $unit ) {
+ if ( $unit instanceof Less_Tree_Keyword ) {
$unit = $unit->value;
} else {
$unit = $unit->toCSS();
@@ -563,320 +576,346 @@ class Less_Functions{
} else {
$unit = "";
}
- return new Less_Tree_Dimension($val->value, $unit );
+ return new Less_Tree_Dimension( $val->value, $unit );
}
- public function convert($val, $unit){
- return $val->convertTo($unit->value);
+ public function convert( $val, $unit ) {
+ return $val->convertTo( $unit->value );
}
- public function round($n, $f = false) {
-
+ public function round( $n, $f = false ) {
$fraction = 0;
- if( $f !== false ){
+ if ( $f !== false ) {
$fraction = $f->value;
}
- return $this->_math('Less_Parser::round',null, $n, $fraction);
+ return $this->_math( 'Less_Parser::round', null, $n, $fraction );
}
- public function pi(){
- return new Less_Tree_Dimension(M_PI);
+ public function pi() {
+ return new Less_Tree_Dimension( M_PI );
}
- public function mod($a, $b) {
- return new Less_Tree_Dimension( $a->value % $b->value, $a->unit);
+ public function mod( $a, $b ) {
+ return new Less_Tree_Dimension( $a->value % $b->value, $a->unit );
}
-
-
- public function pow($x, $y) {
- if( is_numeric($x) && is_numeric($y) ){
- $x = new Less_Tree_Dimension($x);
- $y = new Less_Tree_Dimension($y);
- }elseif( !($x instanceof Less_Tree_Dimension) || !($y instanceof Less_Tree_Dimension) ){
- throw new Less_Exception_Compiler('Arguments must be numbers');
+ public function pow( $x, $y ) {
+ if ( is_numeric( $x ) && is_numeric( $y ) ) {
+ $x = new Less_Tree_Dimension( $x );
+ $y = new Less_Tree_Dimension( $y );
+ } elseif ( !( $x instanceof Less_Tree_Dimension ) || !( $y instanceof Less_Tree_Dimension ) ) {
+ throw new Less_Exception_Compiler( 'Arguments must be numbers' );
}
- return new Less_Tree_Dimension( pow($x->value, $y->value), $x->unit );
+ return new Less_Tree_Dimension( pow( $x->value, $y->value ), $x->unit );
}
// var mathFunctions = [{name:"ce ...
- public function ceil( $n ){ return $this->_math('ceil', null, $n); }
- public function floor( $n ){ return $this->_math('floor', null, $n); }
- public function sqrt( $n ){ return $this->_math('sqrt', null, $n); }
- public function abs( $n ){ return $this->_math('abs', null, $n); }
+ public function ceil( $n ) {
+ return $this->_math( 'ceil', null, $n );
+ }
- public function tan( $n ){ return $this->_math('tan', '', $n); }
- public function sin( $n ){ return $this->_math('sin', '', $n); }
- public function cos( $n ){ return $this->_math('cos', '', $n); }
+ public function floor( $n ) {
+ return $this->_math( 'floor', null, $n );
+ }
- public function atan( $n ){ return $this->_math('atan', 'rad', $n); }
- public function asin( $n ){ return $this->_math('asin', 'rad', $n); }
- public function acos( $n ){ return $this->_math('acos', 'rad', $n); }
+ public function sqrt( $n ) {
+ return $this->_math( 'sqrt', null, $n );
+ }
+
+ public function abs( $n ) {
+ return $this->_math( 'abs', null, $n );
+ }
+
+ public function tan( $n ) {
+ return $this->_math( 'tan', '', $n );
+ }
+
+ public function sin( $n ) {
+ return $this->_math( 'sin', '', $n );
+ }
+
+ public function cos( $n ) {
+ return $this->_math( 'cos', '', $n );
+ }
+
+ public function atan( $n ) {
+ return $this->_math( 'atan', 'rad', $n );
+ }
+
+ public function asin( $n ) {
+ return $this->_math( 'asin', 'rad', $n );
+ }
+
+ public function acos( $n ) {
+ return $this->_math( 'acos', 'rad', $n );
+ }
private function _math() {
$args = func_get_args();
- $fn = array_shift($args);
- $unit = array_shift($args);
+ $fn = array_shift( $args );
+ $unit = array_shift( $args );
- if ($args[0] instanceof Less_Tree_Dimension) {
+ if ( $args[0] instanceof Less_Tree_Dimension ) {
- if( $unit === null ){
+ if ( $unit === null ) {
$unit = $args[0]->unit;
- }else{
+ } else {
$args[0] = $args[0]->unify();
}
$args[0] = (float)$args[0]->value;
- return new Less_Tree_Dimension( call_user_func_array($fn, $args), $unit);
- } else if (is_numeric($args[0])) {
- return call_user_func_array($fn,$args);
+ return new Less_Tree_Dimension( call_user_func_array( $fn, $args ), $unit );
+ } elseif ( is_numeric( $args[0] ) ) {
+ return call_user_func_array( $fn, $args );
} else {
- throw new Less_Exception_Compiler("math functions take numbers as parameters");
+ throw new Less_Exception_Compiler( "math functions take numbers as parameters" );
}
}
/**
- * @param boolean $isMin
+ * @param bool $isMin
+ * @param array $args
*/
- private function _minmax( $isMin, $args ){
+ private function _minmax( $isMin, $args ) {
+ $arg_count = count( $args );
- $arg_count = count($args);
-
- if( $arg_count < 1 ){
- throw new Less_Exception_Compiler( 'one or more arguments required');
+ if ( $arg_count < 1 ) {
+ throw new Less_Exception_Compiler( 'one or more arguments required' );
}
$j = null;
$unitClone = null;
$unitStatic = null;
+ // elems only contains original argument values.
+ $order = [];
+ // key is the unit.toString() for unified tree.Dimension values,
+ // value is the index into the order array.
+ $values = [];
- $order = array(); // elems only contains original argument values.
- $values = array(); // key is the unit.toString() for unified tree.Dimension values,
- // value is the index into the order array.
-
-
- for( $i = 0; $i < $arg_count; $i++ ){
+ for ( $i = 0; $i < $arg_count; $i++ ) {
$current = $args[$i];
- if( !($current instanceof Less_Tree_Dimension) ){
- if( is_array($args[$i]->value) ){
+ if ( !( $current instanceof Less_Tree_Dimension ) ) {
+ // @phan-suppress-next-line PhanUndeclaredProperty Checked Less_Tree->value
+ if ( property_exists( $args[$i], 'value' ) && is_array( $args[$i]->value ) ) {
+ // @phan-suppress-next-line PhanUndeclaredProperty Checked Less_Tree->value
$args[] = $args[$i]->value;
}
continue;
}
+ // PhanTypeInvalidDimOffset -- False positive, safe after continue or non-first iterations
+ '@phan-var non-empty-list $order';
- if( $current->unit->toString() === '' && !$unitClone ){
- $temp = new Less_Tree_Dimension($current->value, $unitClone);
+ if ( $current->unit->toString() === '' && !$unitClone ) {
+ $temp = new Less_Tree_Dimension( $current->value, $unitClone );
$currentUnified = $temp->unify();
- }else{
+ } else {
$currentUnified = $current->unify();
}
- if( $currentUnified->unit->toString() === "" && !$unitStatic ){
+ if ( $currentUnified->unit->toString() === "" && !$unitStatic ) {
$unit = $unitStatic;
- }else{
+ } else {
$unit = $currentUnified->unit->toString();
}
- if( $unit !== '' && !$unitStatic || $unit !== '' && $order[0]->unify()->unit->toString() === "" ){
+ if ( $unit !== '' && !$unitStatic || $unit !== '' && $order[0]->unify()->unit->toString() === "" ) {
$unitStatic = $unit;
}
- if( $unit != '' && !$unitClone ){
+ if ( $unit != '' && !$unitClone ) {
$unitClone = $current->unit->toString();
}
- if( isset($values['']) && $unit !== '' && $unit === $unitStatic ){
+ if ( isset( $values[''] ) && $unit !== '' && $unit === $unitStatic ) {
$j = $values[''];
- }elseif( isset($values[$unit]) ){
+ } elseif ( isset( $values[$unit] ) ) {
$j = $values[$unit];
- }else{
+ } else {
- if( $unitStatic && $unit !== $unitStatic ){
- throw new Less_Exception_Compiler( 'incompatible types');
+ if ( $unitStatic && $unit !== $unitStatic ) {
+ throw new Less_Exception_Compiler( 'incompatible types' );
}
- $values[$unit] = count($order);
+ $values[$unit] = count( $order );
$order[] = $current;
continue;
}
-
- if( $order[$j]->unit->toString() === "" && $unitClone ){
- $temp = new Less_Tree_Dimension( $order[$j]->value, $unitClone);
+ if ( $order[$j]->unit->toString() === "" && $unitClone ) {
+ $temp = new Less_Tree_Dimension( $order[$j]->value, $unitClone );
$referenceUnified = $temp->unify();
- }else{
+ } else {
$referenceUnified = $order[$j]->unify();
}
- if( ($isMin && $currentUnified->value < $referenceUnified->value) || (!$isMin && $currentUnified->value > $referenceUnified->value) ){
+ if ( ( $isMin && $currentUnified->value < $referenceUnified->value ) || ( !$isMin && $currentUnified->value > $referenceUnified->value ) ) {
$order[$j] = $current;
}
}
- if( count($order) == 1 ){
+ if ( count( $order ) == 1 ) {
return $order[0];
}
- $args = array();
- foreach($order as $a){
- $args[] = $a->toCSS($this->env);
+ $args = [];
+ foreach ( $order as $a ) {
+ $args[] = $a->toCSS();
}
- return new Less_Tree_Anonymous( ($isMin?'min(':'max(') . implode(Less_Environment::$_outputMap[','],$args).')');
+ return new Less_Tree_Anonymous( ( $isMin ? 'min(' : 'max(' ) . implode( Less_Environment::$_outputMap[','], $args ) . ')' );
}
- public function min(){
+ public function min() {
$args = func_get_args();
return $this->_minmax( true, $args );
}
- public function max(){
+ public function max() {
$args = func_get_args();
return $this->_minmax( false, $args );
}
- public function getunit($n){
- return new Less_Tree_Anonymous($n->unit);
+ public function getunit( $n ) {
+ return new Less_Tree_Anonymous( $n->unit );
}
- public function argb($color) {
- if (!$color instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to argb must be a color' . ($color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function argb( $color ) {
+ if ( !$color instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to argb must be a color' . ( $color instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- return new Less_Tree_Anonymous($color->toARGB());
+ return new Less_Tree_Anonymous( $color->toARGB() );
}
- public function percentage($n) {
- return new Less_Tree_Dimension($n->value * 100, '%');
+ public function percentage( $n ) {
+ return new Less_Tree_Dimension( $n->value * 100, '%' );
}
- public function color($n) {
-
- if( $n instanceof Less_Tree_Quoted ){
+ public function color( $n ) {
+ if ( $n instanceof Less_Tree_Quoted ) {
$colorCandidate = $n->value;
- $returnColor = Less_Tree_Color::fromKeyword($colorCandidate);
- if( $returnColor ){
+ $returnColor = Less_Tree_Color::fromKeyword( $colorCandidate );
+ if ( $returnColor ) {
return $returnColor;
}
- if( preg_match('/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/',$colorCandidate) ){
- return new Less_Tree_Color(substr($colorCandidate, 1));
+ if ( preg_match( '/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/', $colorCandidate ) ) {
+ return new Less_Tree_Color( substr( $colorCandidate, 1 ) );
}
- throw new Less_Exception_Compiler("argument must be a color keyword or 3/6 digit hex e.g. #FFF");
+ throw new Less_Exception_Compiler( "argument must be a color keyword or 3/6 digit hex e.g. #FFF" );
} else {
- throw new Less_Exception_Compiler("argument must be a string");
+ throw new Less_Exception_Compiler( "argument must be a string" );
}
}
-
- public function iscolor($n) {
- return $this->_isa($n, 'Less_Tree_Color');
+ public function iscolor( $n ) {
+ return $this->_isa( $n, 'Less_Tree_Color' );
}
- public function isnumber($n) {
- return $this->_isa($n, 'Less_Tree_Dimension');
+ public function isnumber( $n ) {
+ return $this->_isa( $n, 'Less_Tree_Dimension' );
}
- public function isstring($n) {
- return $this->_isa($n, 'Less_Tree_Quoted');
+ public function isstring( $n ) {
+ return $this->_isa( $n, 'Less_Tree_Quoted' );
}
- public function iskeyword($n) {
- return $this->_isa($n, 'Less_Tree_Keyword');
+ public function iskeyword( $n ) {
+ return $this->_isa( $n, 'Less_Tree_Keyword' );
}
- public function isurl($n) {
- return $this->_isa($n, 'Less_Tree_Url');
+ public function isurl( $n ) {
+ return $this->_isa( $n, 'Less_Tree_Url' );
}
- public function ispixel($n) {
- return $this->isunit($n, 'px');
+ public function ispixel( $n ) {
+ return $this->isunit( $n, 'px' );
}
- public function ispercentage($n) {
- return $this->isunit($n, '%');
+ public function ispercentage( $n ) {
+ return $this->isunit( $n, '%' );
}
- public function isem($n) {
- return $this->isunit($n, 'em');
+ public function isem( $n ) {
+ return $this->isunit( $n, 'em' );
}
/**
- * @param string $unit
+ * @param Less_Tree $n
+ * @param Less_Tree|string $unit
*/
- public function isunit( $n, $unit ){
-
- if( is_object($unit) && property_exists($unit,'value') ){
+ public function isunit( $n, $unit ) {
+ if ( is_object( $unit ) && property_exists( $unit, 'value' ) ) {
+ // @phan-suppress-next-line PhanUndeclaredProperty Checked Less_Tree->value
$unit = $unit->value;
}
- return ($n instanceof Less_Tree_Dimension) && $n->unit->is($unit) ? new Less_Tree_Keyword('true') : new Less_Tree_Keyword('false');
+ return ( $n instanceof Less_Tree_Dimension ) && $n->unit->is( $unit ) ? new Less_Tree_Keyword( 'true' ) : new Less_Tree_Keyword( 'false' );
}
/**
+ * @param Less_Tree $n
* @param string $type
*/
- private function _isa($n, $type) {
- return is_a($n, $type) ? new Less_Tree_Keyword('true') : new Less_Tree_Keyword('false');
+ private function _isa( $n, $type ) {
+ return is_a( $n, $type ) ? new Less_Tree_Keyword( 'true' ) : new Less_Tree_Keyword( 'false' );
}
- public function tint($color, $amount = null) {
- return $this->mix( $this->rgb(255,255,255), $color, $amount);
+ public function tint( $color, $amount = null ) {
+ return $this->mix( $this->rgb( 255, 255, 255 ), $color, $amount );
}
- public function shade($color, $amount = null) {
- return $this->mix($this->rgb(0, 0, 0), $color, $amount);
+ public function shade( $color, $amount = null ) {
+ return $this->mix( $this->rgb( 0, 0, 0 ), $color, $amount );
}
- public function extract($values, $index ){
+ public function extract( $values, $index ) {
$index = (int)$index->value - 1; // (1-based index)
// handle non-array values as an array of length 1
// return 'undefined' if index is invalid
- if( property_exists($values,'value') && is_array($values->value) ){
- if( isset($values->value[$index]) ){
+ if ( property_exists( $values, 'value' ) && is_array( $values->value ) ) {
+ if ( isset( $values->value[$index] ) ) {
return $values->value[$index];
}
return null;
- }elseif( (int)$index === 0 ){
+ } elseif ( (int)$index === 0 ) {
return $values;
}
return null;
}
- public function length($values){
- $n = (property_exists($values,'value') && is_array($values->value)) ? count($values->value) : 1;
- return new Less_Tree_Dimension($n);
+ public function length( $values ) {
+ $n = ( property_exists( $values, 'value' ) && is_array( $values->value ) ) ? count( $values->value ) : 1;
+ return new Less_Tree_Dimension( $n );
}
- public function datauri($mimetypeNode, $filePathNode = null ) {
-
+ public function datauri( $mimetypeNode, $filePathNode = null ) {
$filePath = ( $filePathNode ? $filePathNode->value : null );
$mimetype = $mimetypeNode->value;
$args = 2;
- if( !$filePath ){
+ if ( !$filePath ) {
$filePath = $mimetype;
$args = 1;
}
- $filePath = str_replace('\\','/',$filePath);
- if( Less_Environment::isPathRelative($filePath) ){
-
- if( Less_Parser::$options['relativeUrls'] ){
- $temp = $this->currentFileInfo['currentDirectory'];
+ $filePath = str_replace( '\\', '/', $filePath );
+ if ( Less_Environment::isPathRelative( $filePath ) ) {
+ $currentFileInfo = $this->currentFileInfo;
+ '@phan-var array $currentFileInfo';
+ if ( Less_Parser::$options['relativeUrls'] ) {
+ $temp = $currentFileInfo['currentDirectory'];
} else {
- $temp = $this->currentFileInfo['entryPath'];
+ $temp = $currentFileInfo['entryPath'];
}
- if( !empty($temp) ){
- $filePath = Less_Environment::normalizePath(rtrim($temp,'/').'/'.$filePath);
+ if ( !empty( $temp ) ) {
+ $filePath = Less_Environment::normalizePath( rtrim( $temp, '/' ) . '/' . $filePath );
}
}
-
// detect the mimetype if not given
- if( $args < 2 ){
+ if ( $args < 2 ) {
/* incomplete
$mime = require('mime');
@@ -888,59 +927,56 @@ class Less_Functions{
if (useBase64) mimetype += ';base64';
*/
- $mimetype = Less_Mime::lookup($filePath);
+ $mimetype = Less_Mime::lookup( $filePath );
- $charset = Less_Mime::charsets_lookup($mimetype);
- $useBase64 = !in_array($charset,array('US-ASCII', 'UTF-8'));
- if( $useBase64 ){ $mimetype .= ';base64'; }
+ $charset = Less_Mime::charsets_lookup( $mimetype );
+ $useBase64 = !in_array( $charset, [ 'US-ASCII', 'UTF-8' ] );
+ if ( $useBase64 ) { $mimetype .= ';base64';
+ }
- }else{
- $useBase64 = preg_match('/;base64$/',$mimetype);
+ } else {
+ $useBase64 = preg_match( '/;base64$/', $mimetype );
}
-
- if( file_exists($filePath) ){
- $buf = @file_get_contents($filePath);
- }else{
+ if ( file_exists( $filePath ) ) {
+ $buf = @file_get_contents( $filePath );
+ } else {
$buf = false;
}
-
// IE8 cannot handle a data-uri larger than 32KB. If this is exceeded
// and the --ieCompat flag is enabled, return a normal url() instead.
$DATA_URI_MAX_KB = 32;
- $fileSizeInKB = round( strlen($buf) / 1024 );
- if( $fileSizeInKB >= $DATA_URI_MAX_KB ){
- $url = new Less_Tree_Url( ($filePathNode ? $filePathNode : $mimetypeNode), $this->currentFileInfo);
- return $url->compile($this);
+ $fileSizeInKB = round( strlen( $buf ) / 1024 );
+ if ( $fileSizeInKB >= $DATA_URI_MAX_KB ) {
+ $url = new Less_Tree_Url( ( $filePathNode ?: $mimetypeNode ), $this->currentFileInfo );
+ return $url->compile( $this->env );
}
- if( $buf ){
- $buf = $useBase64 ? base64_encode($buf) : rawurlencode($buf);
+ if ( $buf ) {
+ $buf = $useBase64 ? base64_encode( $buf ) : rawurlencode( $buf );
$filePath = '"data:' . $mimetype . ',' . $buf . '"';
}
- return new Less_Tree_Url( new Less_Tree_Anonymous($filePath) );
+ return new Less_Tree_Url( new Less_Tree_Anonymous( $filePath ) );
}
- //svg-gradient
- public function svggradient( $direction ){
-
+ // svg-gradient
+ public function svggradient( $direction ) {
$throw_message = 'svg-gradient expects direction, start_color [start_position], [color position,]..., end_color [end_position]';
$arguments = func_get_args();
- if( count($arguments) < 3 ){
+ if ( count( $arguments ) < 3 ) {
throw new Less_Exception_Compiler( $throw_message );
}
- $stops = array_slice($arguments,1);
+ $stops = array_slice( $arguments, 1 );
$gradientType = 'linear';
$rectangleDimension = 'x="0" y="0" width="1" height="1"';
$useBase64 = true;
$directionValue = $direction->toCSS();
-
- switch( $directionValue ){
+ switch ( $directionValue ) {
case "to bottom":
$gradientDirectionSvg = 'x1="0%" y1="0%" x2="0%" y2="100%"';
break;
@@ -967,220 +1003,218 @@ class Less_Functions{
'' .
'<' . $gradientType . 'Gradient id="gradient" gradientUnits="userSpaceOnUse" ' . $gradientDirectionSvg . '>';
- for( $i = 0; $i < count($stops); $i++ ){
- if( is_object($stops[$i]) && property_exists($stops[$i],'value') ){
+ for ( $i = 0; $i < count( $stops ); $i++ ) {
+ if ( is_object( $stops[$i] ) && property_exists( $stops[$i], 'value' ) ) {
$color = $stops[$i]->value[0];
$position = $stops[$i]->value[1];
- }else{
+ } else {
$color = $stops[$i];
$position = null;
}
- if( !($color instanceof Less_Tree_Color) || (!(($i === 0 || $i+1 === count($stops)) && $position === null) && !($position instanceof Less_Tree_Dimension)) ){
+ if ( !( $color instanceof Less_Tree_Color ) || ( !( ( $i === 0 || $i + 1 === count( $stops ) ) && $position === null ) && !( $position instanceof Less_Tree_Dimension ) ) ) {
throw new Less_Exception_Compiler( $throw_message );
}
- if( $position ){
+ if ( $position ) {
$positionValue = $position->toCSS();
- }elseif( $i === 0 ){
+ } elseif ( $i === 0 ) {
$positionValue = '0%';
- }else{
+ } else {
$positionValue = '100%';
}
$alpha = $color->alpha;
- $returner .= ' ';
+ $returner .= ' ';
}
$returner .= '' . $gradientType . 'Gradient> ';
-
- if( $useBase64 ){
- $returner = "'data:image/svg+xml;base64,".base64_encode($returner)."'";
- }else{
- $returner = "'data:image/svg+xml,".$returner."'";
+ if ( $useBase64 ) {
+ $returner = "'data:image/svg+xml;base64," . base64_encode( $returner ) . "'";
+ } else {
+ $returner = "'data:image/svg+xml," . $returner . "'";
}
return new Less_Tree_URL( new Less_Tree_Anonymous( $returner ) );
}
-
/**
* Php version of javascript's `encodeURIComponent` function
*
* @param string $string The string to encode
* @return string The encoded string
*/
- public static function encodeURIComponent($string){
- $revert = array('%21' => '!', '%2A' => '*', '%27' => "'", '%28' => '(', '%29' => ')');
- return strtr(rawurlencode($string), $revert);
+ public static function encodeURIComponent( $string ) {
+ $revert = [ '%21' => '!', '%2A' => '*', '%27' => "'", '%28' => '(', '%29' => ')' ];
+ return strtr( rawurlencode( $string ), $revert );
}
-
// Color Blending
- // ref: http://www.w3.org/TR/compositing-1
+ // ref: https://www.w3.org/TR/compositing-1/
+ public function colorBlend( $mode, $color1, $color2 ) {
+ // backdrop
+ $ab = $color1->alpha;
+ // source
+ $as = $color2->alpha;
+ $result = [];
- public function colorBlend( $mode, $color1, $color2 ){
- $ab = $color1->alpha; // backdrop
- $as = $color2->alpha; // source
- $r = array(); // result
-
- $ar = $as + $ab * (1 - $as);
- for( $i = 0; $i < 3; $i++ ){
+ $ar = $as + $ab * ( 1 - $as );
+ for ( $i = 0; $i < 3; $i++ ) {
$cb = $color1->rgb[$i] / 255;
$cs = $color2->rgb[$i] / 255;
$cr = call_user_func( $mode, $cb, $cs );
- if( $ar ){
- $cr = ($as * $cs + $ab * ($cb - $as * ($cb + $cs - $cr))) / $ar;
+ if ( $ar ) {
+ $cr = ( $as * $cs + $ab * ( $cb - $as * ( $cb + $cs - $cr ) ) ) / $ar;
}
- $r[$i] = $cr * 255;
+ $result[$i] = $cr * 255;
}
- return new Less_Tree_Color($r, $ar);
+ return new Less_Tree_Color( $result, $ar );
}
- public function multiply($color1 = null, $color2 = null ){
- if (!$color1 instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to multiply must be a color' . ($color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function multiply( $color1 = null, $color2 = null ) {
+ if ( !$color1 instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to multiply must be a color' . ( $color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- if (!$color2 instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The second argument to multiply must be a color' . ($color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ if ( !$color2 instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The second argument to multiply must be a color' . ( $color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- return $this->colorBlend( array($this,'colorBlendMultiply'), $color1, $color2 );
+ return $this->colorBlend( [ $this,'colorBlendMultiply' ], $color1, $color2 );
}
- private function colorBlendMultiply($cb, $cs){
+ private function colorBlendMultiply( $cb, $cs ) {
return $cb * $cs;
}
- public function screen($color1 = null, $color2 = null ){
- if (!$color1 instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to screen must be a color' . ($color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function screen( $color1 = null, $color2 = null ) {
+ if ( !$color1 instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to screen must be a color' . ( $color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- if (!$color2 instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The second argument to screen must be a color' . ($color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ if ( !$color2 instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The second argument to screen must be a color' . ( $color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- return $this->colorBlend( array($this,'colorBlendScreen'), $color1, $color2 );
+ return $this->colorBlend( [ $this,'colorBlendScreen' ], $color1, $color2 );
}
- private function colorBlendScreen( $cb, $cs){
+ private function colorBlendScreen( $cb, $cs ) {
return $cb + $cs - $cb * $cs;
}
- public function overlay($color1 = null, $color2 = null){
- if (!$color1 instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to overlay must be a color' . ($color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function overlay( $color1 = null, $color2 = null ) {
+ if ( !$color1 instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to overlay must be a color' . ( $color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- if (!$color2 instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The second argument to overlay must be a color' . ($color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ if ( !$color2 instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The second argument to overlay must be a color' . ( $color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- return $this->colorBlend( array($this,'colorBlendOverlay'), $color1, $color2 );
+ return $this->colorBlend( [ $this,'colorBlendOverlay' ], $color1, $color2 );
}
- private function colorBlendOverlay($cb, $cs ){
+ private function colorBlendOverlay( $cb, $cs ) {
$cb *= 2;
- return ($cb <= 1)
- ? $this->colorBlendMultiply($cb, $cs)
- : $this->colorBlendScreen($cb - 1, $cs);
+ return ( $cb <= 1 )
+ ? $this->colorBlendMultiply( $cb, $cs )
+ : $this->colorBlendScreen( $cb - 1, $cs );
}
- public function softlight($color1 = null, $color2 = null){
- if (!$color1 instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to softlight must be a color' . ($color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function softlight( $color1 = null, $color2 = null ) {
+ if ( !$color1 instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to softlight must be a color' . ( $color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- if (!$color2 instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The second argument to softlight must be a color' . ($color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ if ( !$color2 instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The second argument to softlight must be a color' . ( $color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- return $this->colorBlend( array($this,'colorBlendSoftlight'), $color1, $color2 );
+ return $this->colorBlend( [ $this,'colorBlendSoftlight' ], $color1, $color2 );
}
- private function colorBlendSoftlight($cb, $cs ){
+ private function colorBlendSoftlight( $cb, $cs ) {
$d = 1;
$e = $cb;
- if( $cs > 0.5 ){
+ if ( $cs > 0.5 ) {
$e = 1;
- $d = ($cb > 0.25) ? sqrt($cb)
- : ((16 * $cb - 12) * $cb + 4) * $cb;
+ $d = ( $cb > 0.25 ) ? sqrt( $cb )
+ : ( ( 16 * $cb - 12 ) * $cb + 4 ) * $cb;
}
- return $cb - (1 - 2 * $cs) * $e * ($d - $cb);
+ return $cb - ( 1 - 2 * $cs ) * $e * ( $d - $cb );
}
- public function hardlight($color1 = null, $color2 = null){
- if (!$color1 instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to hardlight must be a color' . ($color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function hardlight( $color1 = null, $color2 = null ) {
+ if ( !$color1 instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to hardlight must be a color' . ( $color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- if (!$color2 instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The second argument to hardlight must be a color' . ($color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ if ( !$color2 instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The second argument to hardlight must be a color' . ( $color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- return $this->colorBlend( array($this,'colorBlendHardlight'), $color1, $color2 );
+ return $this->colorBlend( [ $this,'colorBlendHardlight' ], $color1, $color2 );
}
- private function colorBlendHardlight( $cb, $cs ){
- return $this->colorBlendOverlay($cs, $cb);
+ private function colorBlendHardlight( $cb, $cs ) {
+ return $this->colorBlendOverlay( $cs, $cb );
}
- public function difference($color1 = null, $color2 = null) {
- if (!$color1 instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to difference must be a color' . ($color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function difference( $color1 = null, $color2 = null ) {
+ if ( !$color1 instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to difference must be a color' . ( $color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- if (!$color2 instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The second argument to difference must be a color' . ($color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ if ( !$color2 instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The second argument to difference must be a color' . ( $color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- return $this->colorBlend( array($this,'colorBlendDifference'), $color1, $color2 );
+ return $this->colorBlend( [ $this,'colorBlendDifference' ], $color1, $color2 );
}
- private function colorBlendDifference( $cb, $cs ){
- return abs($cb - $cs);
+ private function colorBlendDifference( $cb, $cs ) {
+ return abs( $cb - $cs );
}
- public function exclusion( $color1 = null, $color2 = null ){
- if (!$color1 instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to exclusion must be a color' . ($color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function exclusion( $color1 = null, $color2 = null ) {
+ if ( !$color1 instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to exclusion must be a color' . ( $color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- if (!$color2 instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The second argument to exclusion must be a color' . ($color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ if ( !$color2 instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The second argument to exclusion must be a color' . ( $color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- return $this->colorBlend( array($this,'colorBlendExclusion'), $color1, $color2 );
+ return $this->colorBlend( [ $this,'colorBlendExclusion' ], $color1, $color2 );
}
- private function colorBlendExclusion( $cb, $cs ){
+ private function colorBlendExclusion( $cb, $cs ) {
return $cb + $cs - 2 * $cb * $cs;
}
- public function average($color1 = null, $color2 = null){
- if (!$color1 instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to average must be a color' . ($color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function average( $color1 = null, $color2 = null ) {
+ if ( !$color1 instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to average must be a color' . ( $color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- if (!$color2 instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The second argument to average must be a color' . ($color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ if ( !$color2 instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The second argument to average must be a color' . ( $color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- return $this->colorBlend( array($this,'colorBlendAverage'), $color1, $color2 );
+ return $this->colorBlend( [ $this,'colorBlendAverage' ], $color1, $color2 );
}
// non-w3c functions:
- public function colorBlendAverage($cb, $cs ){
- return ($cb + $cs) / 2;
+ public function colorBlendAverage( $cb, $cs ) {
+ return ( $cb + $cs ) / 2;
}
- public function negation($color1 = null, $color2 = null ){
- if (!$color1 instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The first argument to negation must be a color' . ($color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ public function negation( $color1 = null, $color2 = null ) {
+ if ( !$color1 instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The first argument to negation must be a color' . ( $color1 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- if (!$color2 instanceof Less_Tree_Color) {
- throw new Less_Exception_Compiler('The second argument to negation must be a color' . ($color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '') );
+ if ( !$color2 instanceof Less_Tree_Color ) {
+ throw new Less_Exception_Compiler( 'The second argument to negation must be a color' . ( $color2 instanceof Less_Tree_Expression ? ' (did you forgot commas?)' : '' ) );
}
- return $this->colorBlend( array($this,'colorBlendNegation'), $color1, $color2 );
+ return $this->colorBlend( [ $this,'colorBlendNegation' ], $color1, $color2 );
}
- public function colorBlendNegation($cb, $cs){
- return 1 - abs($cb + $cs - 1);
+ public function colorBlendNegation( $cb, $cs ) {
+ return 1 - abs( $cb + $cs - 1 );
}
// ~ End of Color Blending
diff --git a/vendor/wikimedia/less.php/lib/Less/Less.php.combine b/vendor/wikimedia/less.php/lib/Less/Less.php.combine
old mode 100755
new mode 100644
diff --git a/vendor/wikimedia/less.php/lib/Less/Mime.php b/vendor/wikimedia/less.php/lib/Less/Mime.php
index 109ecd3f8..45a7bf3d1 100644
--- a/vendor/wikimedia/less.php/lib/Less/Mime.php
+++ b/vendor/wikimedia/less.php/lib/Less/Mime.php
@@ -1,41 +1,36 @@
'text/html',
- '.html'=> 'text/html',
- '.gif' => 'image/gif',
- '.jpg' => 'image/jpeg',
- '.jpeg'=> 'image/jpeg',
- '.png' => 'image/png',
- '.ttf' => 'application/x-font-ttf',
- '.otf' => 'application/x-font-otf',
- '.eot' => 'application/vnd.ms-fontobject',
- '.woff' => 'application/x-font-woff',
- '.svg' => 'image/svg+xml',
- );
+ private static $types = [
+ '.htm' => 'text/html',
+ '.html' => 'text/html',
+ '.gif' => 'image/gif',
+ '.jpg' => 'image/jpeg',
+ '.jpeg' => 'image/jpeg',
+ '.png' => 'image/png',
+ '.ttf' => 'application/x-font-ttf',
+ '.otf' => 'application/x-font-otf',
+ '.eot' => 'application/vnd.ms-fontobject',
+ '.woff' => 'application/x-font-woff',
+ '.svg' => 'image/svg+xml',
+ ];
- public static function lookup( $filepath ){
- $parts = explode('.',$filepath);
- $ext = '.'.strtolower(array_pop($parts));
+ public static function lookup( $filepath ) {
+ $parts = explode( '.', $filepath );
+ $ext = '.' . strtolower( array_pop( $parts ) );
- if( !isset(self::$_types[$ext]) ){
- return null;
- }
- return self::$_types[$ext];
+ return self::$types[$ext] ?? null;
}
- public static function charsets_lookup( $type = null ){
+ public static function charsets_lookup( $type = null ) {
// assumes all text types are UTF-8
- return $type && preg_match('/^text\//',$type) ? 'UTF-8' : '';
+ return $type && preg_match( '/^text\//', $type ) ? 'UTF-8' : '';
}
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Output.php b/vendor/wikimedia/less.php/lib/Less/Output.php
index f1b2b2a99..be6c160f3 100644
--- a/vendor/wikimedia/less.php/lib/Less/Output.php
+++ b/vendor/wikimedia/less.php/lib/Less/Output.php
@@ -1,49 +1,46 @@
strs[] = $chunk;
}
/**
* Is the output empty?
*
- * @return boolean
+ * @return bool
*/
- public function isEmpty(){
- return count($this->strs) === 0;
+ public function isEmpty() {
+ return count( $this->strs ) === 0;
}
-
/**
* Converts the output to string
*
* @return string
*/
- public function toString(){
- return implode('',$this->strs);
+ public function toString() {
+ return implode( '', $this->strs );
}
-}
\ No newline at end of file
+}
diff --git a/vendor/wikimedia/less.php/lib/Less/Output/Mapped.php b/vendor/wikimedia/less.php/lib/Less/Output/Mapped.php
index 884490a20..ece517204 100644
--- a/vendor/wikimedia/less.php/lib/Less/Output/Mapped.php
+++ b/vendor/wikimedia/less.php/lib/Less/Output/Mapped.php
@@ -1,10 +1,8 @@
contentsMap = $contentsMap;
$this->generator = $generator;
}
@@ -52,71 +50,68 @@ class Less_Output_Mapped extends Less_Output {
* The $index for less.php may be different from less.js since less.php does not chunkify inputs
*
* @param string $chunk
- * @param string $fileInfo
- * @param integer $index
+ * @param array|null $fileInfo
+ * @param int $index
* @param mixed $mapLines
*/
- public function add($chunk, $fileInfo = null, $index = 0, $mapLines = null){
-
- //ignore adding empty strings
- if( $chunk === '' ){
+ public function add( $chunk, $fileInfo = null, $index = 0, $mapLines = null ) {
+ // ignore adding empty strings
+ if ( $chunk === '' ) {
return;
}
-
- $sourceLines = array();
+ $sourceLines = [];
$sourceColumns = ' ';
-
- if( $fileInfo ){
+ if ( $fileInfo ) {
$url = $fileInfo['currentUri'];
- if( isset($this->contentsMap[$url]) ){
- $inputSource = substr($this->contentsMap[$url], 0, $index);
- $sourceLines = explode("\n", $inputSource);
- $sourceColumns = end($sourceLines);
- }else{
- throw new Exception('Filename '.$url.' not in contentsMap');
+ if ( isset( $this->contentsMap[$url] ) ) {
+ $inputSource = substr( $this->contentsMap[$url], 0, $index );
+ $sourceLines = explode( "\n", $inputSource );
+ $sourceColumns = end( $sourceLines );
+ } else {
+ throw new Exception( 'Filename ' . $url . ' not in contentsMap' );
}
}
- $lines = explode("\n", $chunk);
- $columns = end($lines);
+ $lines = explode( "\n", $chunk );
+ $columns = end( $lines );
- if($fileInfo){
+ if ( $fileInfo ) {
- if(!$mapLines){
+ if ( !$mapLines ) {
$this->generator->addMapping(
$this->lineNumber + 1, // generated_line
$this->column, // generated_column
- count($sourceLines), // original_line
- strlen($sourceColumns), // original_column
+ count( $sourceLines ), // original_line
+ strlen( $sourceColumns ), // original_column
$fileInfo
);
- }else{
- for($i = 0, $count = count($lines); $i < $count; $i++){
+ } else {
+ for ( $i = 0, $count = count( $lines ); $i < $count; $i++ ) {
$this->generator->addMapping(
$this->lineNumber + $i + 1, // generated_line
$i === 0 ? $this->column : 0, // generated_column
- count($sourceLines) + $i, // original_line
- $i === 0 ? strlen($sourceColumns) : 0, // original_column
+ count( $sourceLines ) + $i, // original_line
+ $i === 0 ? strlen( $sourceColumns ) : 0, // original_column
$fileInfo
);
}
}
}
- if(count($lines) === 1){
- $this->column += strlen($columns);
- }else{
- $this->lineNumber += count($lines) - 1;
- $this->column = strlen($columns);
+ if ( count( $lines ) === 1 ) {
+ $this->column += strlen( $columns );
+ } else {
+ $this->lineNumber += count( $lines ) - 1;
+ $this->column = strlen( $columns );
}
// add only chunk
- parent::add($chunk);
+ parent::add( $chunk );
}
-}
\ No newline at end of file
+}
diff --git a/vendor/wikimedia/less.php/lib/Less/Parser.php b/vendor/wikimedia/less.php/lib/Less/Parser.php
index 1c3ad5f12..b05bf1472 100644
--- a/vendor/wikimedia/less.php/lib/Less/Parser.php
+++ b/vendor/wikimedia/less.php/lib/Less/Parser.php
@@ -1,21 +1,14 @@
false, // option - whether to compress
'strictUnits' => false, // whether units need to evaluate correctly
'strictMath' => false, // whether math has to be within parenthesis
@@ -23,7 +16,7 @@ class Less_Parser{
'urlArgs' => '', // whether to add args into url tokens
'numPrecision' => 8,
- 'import_dirs' => array(),
+ 'import_dirs' => [],
'import_callback' => null,
'cache_dir' => null,
'cache_method' => 'php', // false, 'serialize', 'php', 'var_export', 'callback';
@@ -37,17 +30,17 @@ class Less_Parser{
'indentation' => ' ',
- 'plugins' => array(),
+ 'plugins' => [],
- );
-
- public static $options = array();
+ ];
+ /** @var array{compress:bool,strictUnits:bool,strictMath:bool,numPrecision:int,import_dirs:array,import_callback:null|callable,indentation:string} */
+ public static $options = [];
private $input; // Less input string
private $input_len; // input string length
private $pos; // current index in `input`
- private $saveStack = array(); // holds state for backtracking
+ private $saveStack = []; // holds state for backtracking
private $furthest;
private $mb_internal_encoding = ''; // for remember exists value of mbstring.internal_encoding
@@ -56,9 +49,9 @@ class Less_Parser{
*/
private $env;
- protected $rules = array();
+ protected $rules = [];
- private static $imports = array();
+ private static $imports = [];
public static $has_extends = false;
@@ -69,51 +62,46 @@ class Less_Parser{
*
* @var array
*/
- public static $contentsMap = array();
-
+ public static $contentsMap = [];
/**
* @param Less_Environment|array|null $env
*/
- public function __construct( $env = null ){
-
+ public function __construct( $env = null ) {
// Top parser on an import tree must be sure there is one "env"
// which will then be passed around by reference.
- if( $env instanceof Less_Environment ){
+ if ( $env instanceof Less_Environment ) {
$this->env = $env;
- }else{
- $this->SetOptions(Less_Parser::$default_options);
+ } else {
+ $this->SetOptions( self::$default_options );
$this->Reset( $env );
}
// mbstring.func_overload > 1 bugfix
// The encoding value must be set for each source file,
// therefore, to conserve resources and improve the speed of this design is taken here
- if (ini_get('mbstring.func_overload')) {
- $this->mb_internal_encoding = ini_get('mbstring.internal_encoding');
- @ini_set('mbstring.internal_encoding', 'ascii');
+ if ( ini_get( 'mbstring.func_overload' ) ) {
+ $this->mb_internal_encoding = ini_get( 'mbstring.internal_encoding' );
+ @ini_set( 'mbstring.internal_encoding', 'ascii' );
}
-
}
-
/**
* Reset the parser state completely
- *
*/
- public function Reset( $options = null ){
- $this->rules = array();
- self::$imports = array();
+ public function Reset( $options = null ) {
+ $this->rules = [];
+ self::$imports = [];
self::$has_extends = false;
- self::$imports = array();
- self::$contentsMap = array();
+ self::$imports = [];
+ self::$contentsMap = [];
- $this->env = new Less_Environment($options);
+ $this->env = new Less_Environment();
- //set new options
- if( is_array($options) ){
- $this->SetOptions(Less_Parser::$default_options);
- $this->SetOptions($options);
+ // set new options
+ if ( is_array( $options ) ) {
+ $this->SetOptions( self::$default_options );
+ $this->SetOptions( $options );
}
$this->env->Init();
@@ -122,174 +110,163 @@ class Less_Parser{
/**
* Set one or more compiler options
* options: import_dirs, cache_dir, cache_method
- *
*/
- public function SetOptions( $options ){
- foreach($options as $option => $value){
- $this->SetOption($option,$value);
+ public function SetOptions( $options ) {
+ foreach ( $options as $option => $value ) {
+ $this->SetOption( $option, $value );
}
}
/**
* Set one compiler option
- *
*/
- public function SetOption($option,$value){
-
- switch($option){
+ public function SetOption( $option, $value ) {
+ switch ( $option ) {
case 'import_dirs':
- $this->SetImportDirs($value);
- return;
+ $this->SetImportDirs( $value );
+ return;
case 'cache_dir':
- if( is_string($value) ){
- Less_Cache::SetCacheDir($value);
+ if ( is_string( $value ) ) {
+ Less_Cache::SetCacheDir( $value );
Less_Cache::CheckCacheDir();
}
- return;
+ return;
}
- Less_Parser::$options[$option] = $value;
+ self::$options[$option] = $value;
}
/**
* Registers a new custom function
*
- * @param string $name function name
- * @param callable $callback callback
+ * @param string $name function name
+ * @param callable $callback callback
*/
- public function registerFunction($name, $callback) {
+ public function registerFunction( $name, $callback ) {
$this->env->functions[$name] = $callback;
}
/**
* Removed an already registered function
*
- * @param string $name function name
+ * @param string $name function name
*/
- public function unregisterFunction($name) {
- if( isset($this->env->functions[$name]) )
- unset($this->env->functions[$name]);
+ public function unregisterFunction( $name ) {
+ if ( isset( $this->env->functions[$name] ) ) {
+ unset( $this->env->functions[$name] );
+ }
}
-
/**
* Get the current css buffer
*
* @return string
*/
- public function getCss(){
-
- $precision = ini_get('precision');
- @ini_set('precision',16);
- $locale = setlocale(LC_NUMERIC, 0);
- setlocale(LC_NUMERIC, "C");
+ public function getCss() {
+ $precision = ini_get( 'precision' );
+ @ini_set( 'precision', '16' );
+ $locale = setlocale( LC_NUMERIC, 0 );
+ setlocale( LC_NUMERIC, "C" );
try {
-
- $root = new Less_Tree_Ruleset(array(), $this->rules );
+ $root = new Less_Tree_Ruleset( null, $this->rules );
$root->root = true;
$root->firstRoot = true;
-
- $this->PreVisitors($root);
+ $this->PreVisitors( $root );
self::$has_extends = false;
- $evaldRoot = $root->compile($this->env);
+ $evaldRoot = $root->compile( $this->env );
+ $this->PostVisitors( $evaldRoot );
-
- $this->PostVisitors($evaldRoot);
-
- if( Less_Parser::$options['sourceMap'] ){
- $generator = new Less_SourceMap_Generator($evaldRoot, Less_Parser::$contentsMap, Less_Parser::$options );
+ if ( self::$options['sourceMap'] ) {
+ $generator = new Less_SourceMap_Generator( $evaldRoot, self::$contentsMap, self::$options );
// will also save file
// FIXME: should happen somewhere else?
$css = $generator->generateCSS();
- }else{
+ } else {
$css = $evaldRoot->toCSS();
}
- if( Less_Parser::$options['compress'] ){
- $css = preg_replace('/(^(\s)+)|((\s)+$)/', '', $css);
+ if ( self::$options['compress'] ) {
+ $css = preg_replace( '/(^(\s)+)|((\s)+$)/', '', $css );
}
- } catch (Exception $exc) {
+ } catch ( Exception $exc ) {
// Intentional fall-through so we can reset environment
}
- //reset php settings
- @ini_set('precision',$precision);
- setlocale(LC_NUMERIC, $locale);
+ // reset php settings
+ @ini_set( 'precision', $precision );
+ setlocale( LC_NUMERIC, $locale );
// If you previously defined $this->mb_internal_encoding
// is required to return the encoding as it was before
- if ($this->mb_internal_encoding != '') {
- @ini_set("mbstring.internal_encoding", $this->mb_internal_encoding);
+ if ( $this->mb_internal_encoding != '' ) {
+ @ini_set( "mbstring.internal_encoding", $this->mb_internal_encoding );
$this->mb_internal_encoding = '';
}
// Rethrow exception after we handled resetting the environment
- if (!empty($exc)) {
+ if ( !empty( $exc ) ) {
throw $exc;
}
return $css;
}
- public function findValueOf($varName)
- {
- foreach($this->rules as $rule){
- if(isset($rule->variable) && ($rule->variable == true) && (str_replace("@","",$rule->name) == $varName)){
- return $this->getVariableValue($rule);
+ public function findValueOf( $varName ) {
+ foreach ( $this->rules as $rule ) {
+ if ( isset( $rule->variable ) && ( $rule->variable == true ) && ( str_replace( "@", "", $rule->name ) == $varName ) ) {
+ return $this->getVariableValue( $rule );
}
}
return null;
}
/**
- *
- * this function gets the private rules variable and returns an array of the found variables
- * it uses a helper method getVariableValue() that contains the logic ot fetch the value from the rule object
+ * Gets the private rules variable and returns an array of the found variables
+ * it uses a helper method getVariableValue() that contains the logic ot fetch the value
+ * from the rule object
*
* @return array
*/
- public function getVariables()
- {
- $variables = array();
+ public function getVariables() {
+ $variables = [];
- $not_variable_type = array(
+ $not_variable_type = [
'Comment', // this include less comments ( // ) and css comments (/* */)
'Import', // do not search variables in included files @import
'Ruleset', // selectors (.someclass, #someid, …)
'Operation', //
- );
+ ];
// @TODO run compilation if not runned yet
- foreach ($this->rules as $key => $rule) {
- if (in_array($rule->type, $not_variable_type)) {
+ foreach ( $this->rules as $key => $rule ) {
+ if ( in_array( $rule->type, $not_variable_type ) ) {
continue;
}
// Note: it seems rule->type is always Rule when variable = true
- if ($rule->type == 'Rule' && $rule->variable) {
- $variables[$rule->name] = $this->getVariableValue($rule);
+ if ( $rule->type == 'Rule' && $rule->variable ) {
+ $variables[$rule->name] = $this->getVariableValue( $rule );
} else {
- if ($rule->type == 'Comment') {
- $variables[] = $this->getVariableValue($rule);
+ if ( $rule->type == 'Comment' ) {
+ $variables[] = $this->getVariableValue( $rule );
}
}
}
return $variables;
}
- public function findVarByName($var_name)
- {
- foreach($this->rules as $rule){
- if(isset($rule->variable) && ($rule->variable == true)){
- if($rule->name == $var_name){
- return $this->getVariableValue($rule);
+ public function findVarByName( $var_name ) {
+ foreach ( $this->rules as $rule ) {
+ if ( isset( $rule->variable ) && ( $rule->variable == true ) ) {
+ if ( $rule->name == $var_name ) {
+ return $this->getVariableValue( $rule );
}
}
}
@@ -297,411 +274,381 @@ class Less_Parser{
}
/**
- *
* This method gets the value of the less variable from the rules object.
* Since the objects vary here we add the logic for extracting the css/less value.
*
- * @param $var
- *
- * @return bool|string
+ * @param Less_Tree $var
+ * @return string
*/
- private function getVariableValue($var)
- {
- if (!is_a($var, 'Less_Tree')) {
- throw new Exception('var is not a Less_Tree object');
- }
-
- switch ($var->type) {
- case 'Color':
- return $this->rgb2html($var->rgb);
- case 'Unit':
- return $var->value. $var->unit->numerator[0];
- case 'Variable':
- return $this->findVarByName($var->name);
- case 'Keyword':
+ private function getVariableValue( Less_Tree $var ) {
+ switch ( get_class( $var ) ) {
+ case Less_Tree_Color::class:
+ return $this->rgb2html( $var->rgb );
+ case Less_Tree_Variable::class:
+ return $this->findVarByName( $var->name );
+ case Less_Tree_Keyword::class:
return $var->value;
- case 'Rule':
- return $this->getVariableValue($var->value);
- case 'Value':
+ case Less_Tree_Url::class:
+ // Based on Less_Tree_Url::genCSS()
+ // Recurse to serialize the Less_Tree_Quoted value
+ return 'url(' . $this->getVariableValue( $var->value ) . ')';
+ case Less_Tree_Rule::class:
+ return $this->getVariableValue( $var->value );
+ case Less_Tree_Value::class:
$value = '';
- foreach ($var->value as $sub_value) {
- $value .= $this->getVariableValue($sub_value).' ';
+ foreach ( $var->value as $sub_value ) {
+ $value .= $this->getVariableValue( $sub_value ) . ' ';
}
return $value;
- case 'Quoted':
- return $var->quote.$var->value.$var->quote;
- case 'Dimension':
+ case Less_Tree_Quoted::class:
+ return $var->quote . $var->value . $var->quote;
+ case Less_Tree_Dimension::class:
$value = $var->value;
- if ($var->unit && $var->unit->numerator) {
+ if ( $var->unit && $var->unit->numerator ) {
$value .= $var->unit->numerator[0];
}
return $value;
- case 'Expression':
- $value = "";
- foreach($var->value as $item) {
- $value .= $this->getVariableValue($item)." ";
+ case Less_Tree_Expression::class:
+ $value = '';
+ foreach ( $var->value as $item ) {
+ $value .= $this->getVariableValue( $item ) . " ";
}
return $value;
- case 'Operation':
- throw new Exception('getVariables() require Less to be compiled. please use $parser->getCss() before calling getVariables()');
- case 'Comment':
- case 'Import':
- case 'Ruleset':
+ case Less_Tree_Operation::class:
+ throw new Exception( 'getVariables() require Less to be compiled. please use $parser->getCss() before calling getVariables()' );
+ case Less_Tree_Unit::class:
+ case Less_Tree_Comment::class:
+ case Less_Tree_Import::class:
+ case Less_Tree_Ruleset::class:
default:
- throw new Exception("type missing in switch/case getVariableValue for ".$var->type);
+ throw new Exception( "type missing in switch/case getVariableValue for " . $var->type );
}
- return false;
}
- private function rgb2html($r, $g=-1, $b=-1)
- {
- if (is_array($r) && sizeof($r) == 3)
- list($r, $g, $b) = $r;
+ private function rgb2html( $r, $g = -1, $b = -1 ) {
+ if ( is_array( $r ) && count( $r ) == 3 ) {
+ list( $r, $g, $b ) = $r;
+ }
- $r = intval($r); $g = intval($g);
- $b = intval($b);
+ $r = intval( $r );
+$g = intval( $g );
+ $b = intval( $b );
- $r = dechex($r<0?0:($r>255?255:$r));
- $g = dechex($g<0?0:($g>255?255:$g));
- $b = dechex($b<0?0:($b>255?255:$b));
+ $r = dechex( $r < 0 ? 0 : ( $r > 255 ? 255 : $r ) );
+ $g = dechex( $g < 0 ? 0 : ( $g > 255 ? 255 : $g ) );
+ $b = dechex( $b < 0 ? 0 : ( $b > 255 ? 255 : $b ) );
- $color = (strlen($r) < 2?'0':'').$r;
- $color .= (strlen($g) < 2?'0':'').$g;
- $color .= (strlen($b) < 2?'0':'').$b;
- return '#'.$color;
+ $color = ( strlen( $r ) < 2 ? '0' : '' ) . $r;
+ $color .= ( strlen( $g ) < 2 ? '0' : '' ) . $g;
+ $color .= ( strlen( $b ) < 2 ? '0' : '' ) . $b;
+ return '#' . $color;
}
/**
* Run pre-compile visitors
- *
*/
- private function PreVisitors($root){
-
- if( Less_Parser::$options['plugins'] ){
- foreach(Less_Parser::$options['plugins'] as $plugin){
- if( !empty($plugin->isPreEvalVisitor) ){
- $plugin->run($root);
+ private function PreVisitors( $root ) {
+ if ( self::$options['plugins'] ) {
+ foreach ( self::$options['plugins'] as $plugin ) {
+ if ( !empty( $plugin->isPreEvalVisitor ) ) {
+ $plugin->run( $root );
}
}
}
}
-
/**
* Run post-compile visitors
- *
*/
- private function PostVisitors($evaldRoot){
-
- $visitors = array();
+ private function PostVisitors( $evaldRoot ) {
+ $visitors = [];
$visitors[] = new Less_Visitor_joinSelector();
- if( self::$has_extends ){
+ if ( self::$has_extends ) {
$visitors[] = new Less_Visitor_processExtends();
}
$visitors[] = new Less_Visitor_toCSS();
-
- if( Less_Parser::$options['plugins'] ){
- foreach(Less_Parser::$options['plugins'] as $plugin){
- if( property_exists($plugin,'isPreEvalVisitor') && $plugin->isPreEvalVisitor ){
+ if ( self::$options['plugins'] ) {
+ foreach ( self::$options['plugins'] as $plugin ) {
+ if ( property_exists( $plugin, 'isPreEvalVisitor' ) && $plugin->isPreEvalVisitor ) {
continue;
}
- if( property_exists($plugin,'isPreVisitor') && $plugin->isPreVisitor ){
- array_unshift( $visitors, $plugin);
- }else{
+ if ( property_exists( $plugin, 'isPreVisitor' ) && $plugin->isPreVisitor ) {
+ array_unshift( $visitors, $plugin );
+ } else {
$visitors[] = $plugin;
}
}
}
-
- for($i = 0; $i < count($visitors); $i++ ){
- $visitors[$i]->run($evaldRoot);
+ for ( $i = 0; $i < count( $visitors ); $i++ ) {
+ $visitors[$i]->run( $evaldRoot );
}
-
}
-
/**
- * Parse a Less string into css
+ * Parse a Less string
*
+ * @throws Less_Exception_Parser If the compiler encounters invalid syntax
* @param string $str The string to convert
- * @param string $uri_root The url of the file
- * @return Less_Tree_Ruleset|Less_Parser
+ * @param string|null $file_uri The url of the file
+ * @return Less_Parser
*/
- public function parse( $str, $file_uri = null ){
-
- if( !$file_uri ){
+ public function parse( $str, $file_uri = null ) {
+ if ( !$file_uri ) {
$uri_root = '';
- $filename = 'anonymous-file-'.Less_Parser::$next_id++.'.less';
- }else{
- $file_uri = self::WinPath($file_uri);
+ $filename = 'anonymous-file-' . self::$next_id++ . '.less';
+ } else {
+ $file_uri = self::WinPath( $file_uri );
$filename = $file_uri;
- $uri_root = dirname($file_uri);
+ $uri_root = dirname( $file_uri );
}
$previousFileInfo = $this->env->currentFileInfo;
- $uri_root = self::WinPath($uri_root);
- $this->SetFileInfo($filename, $uri_root);
+ $uri_root = self::WinPath( $uri_root );
+ $this->SetFileInfo( $filename, $uri_root );
$this->input = $str;
$this->_parse();
- if( $previousFileInfo ){
+ if ( $previousFileInfo ) {
$this->env->currentFileInfo = $previousFileInfo;
}
return $this;
}
-
/**
* Parse a Less string from a given file
*
- * @throws Less_Exception_Parser
+ * @throws Less_Exception_Parser If the compiler encounters invalid syntax
* @param string $filename The file to parse
* @param string $uri_root The url of the file
* @param bool $returnRoot Indicates whether the return value should be a css string a root node
* @return Less_Tree_Ruleset|Less_Parser
*/
- public function parseFile( $filename, $uri_root = '', $returnRoot = false){
-
- if( !file_exists($filename) ){
- $this->Error(sprintf('File `%s` not found.', $filename));
+ public function parseFile( $filename, $uri_root = '', $returnRoot = false ) {
+ if ( !file_exists( $filename ) ) {
+ $this->Error( sprintf( 'File `%s` not found.', $filename ) );
}
-
// fix uri_root?
// Instead of The mixture of file path for the first argument and directory path for the second argument has bee
- if( !$returnRoot && !empty($uri_root) && basename($uri_root) == basename($filename) ){
- $uri_root = dirname($uri_root);
+ if ( !$returnRoot && !empty( $uri_root ) && basename( $uri_root ) == basename( $filename ) ) {
+ $uri_root = dirname( $uri_root );
}
-
$previousFileInfo = $this->env->currentFileInfo;
-
- if( $filename ){
- $filename = self::AbsPath($filename, true);
+ if ( $filename ) {
+ $filename = self::AbsPath( $filename, true );
}
- $uri_root = self::WinPath($uri_root);
+ $uri_root = self::WinPath( $uri_root );
- $this->SetFileInfo($filename, $uri_root);
+ $this->SetFileInfo( $filename, $uri_root );
- self::AddParsedFile($filename);
+ self::AddParsedFile( $filename );
- if( $returnRoot ){
+ if ( $returnRoot ) {
$rules = $this->GetRules( $filename );
- $return = new Less_Tree_Ruleset(array(), $rules );
- }else{
+ $return = new Less_Tree_Ruleset( null, $rules );
+ } else {
$this->_parse( $filename );
$return = $this;
}
- if( $previousFileInfo ){
+ if ( $previousFileInfo ) {
$this->env->currentFileInfo = $previousFileInfo;
}
return $return;
}
-
/**
* Allows a user to set variables values
* @param array $vars
* @return Less_Parser
*/
- public function ModifyVars( $vars ){
-
- $this->input = Less_Parser::serializeVars( $vars );
+ public function ModifyVars( $vars ) {
+ $this->input = self::serializeVars( $vars );
$this->_parse();
return $this;
}
-
/**
* @param string $filename
+ * @param string $uri_root
*/
- public function SetFileInfo( $filename, $uri_root = ''){
+ public function SetFileInfo( $filename, $uri_root = '' ) {
+ $filename = Less_Environment::normalizePath( $filename );
+ $dirname = preg_replace( '/[^\/\\\\]*$/', '', $filename );
- $filename = Less_Environment::normalizePath($filename);
- $dirname = preg_replace('/[^\/\\\\]*$/','',$filename);
-
- if( !empty($uri_root) ){
- $uri_root = rtrim($uri_root,'/').'/';
+ if ( !empty( $uri_root ) ) {
+ $uri_root = rtrim( $uri_root, '/' ) . '/';
}
- $currentFileInfo = array();
+ $currentFileInfo = [];
- //entry info
- if( isset($this->env->currentFileInfo) ){
+ // entry info
+ if ( isset( $this->env->currentFileInfo ) ) {
$currentFileInfo['entryPath'] = $this->env->currentFileInfo['entryPath'];
$currentFileInfo['entryUri'] = $this->env->currentFileInfo['entryUri'];
$currentFileInfo['rootpath'] = $this->env->currentFileInfo['rootpath'];
- }else{
+ } else {
$currentFileInfo['entryPath'] = $dirname;
$currentFileInfo['entryUri'] = $uri_root;
$currentFileInfo['rootpath'] = $dirname;
}
$currentFileInfo['currentDirectory'] = $dirname;
- $currentFileInfo['currentUri'] = $uri_root.basename($filename);
+ $currentFileInfo['currentUri'] = $uri_root . basename( $filename );
$currentFileInfo['filename'] = $filename;
$currentFileInfo['uri_root'] = $uri_root;
-
- //inherit reference
- if( isset($this->env->currentFileInfo['reference']) && $this->env->currentFileInfo['reference'] ){
+ // inherit reference
+ if ( isset( $this->env->currentFileInfo['reference'] ) && $this->env->currentFileInfo['reference'] ) {
$currentFileInfo['reference'] = true;
}
$this->env->currentFileInfo = $currentFileInfo;
}
-
/**
* @deprecated 1.5.1.2
- *
*/
- public function SetCacheDir( $dir ){
-
- if( !file_exists($dir) ){
- if( mkdir($dir) ){
+ public function SetCacheDir( $dir ) {
+ if ( !file_exists( $dir ) ) {
+ if ( mkdir( $dir ) ) {
return true;
}
- throw new Less_Exception_Parser('Less.php cache directory couldn\'t be created: '.$dir);
+ throw new Less_Exception_Parser( 'Less.php cache directory couldn\'t be created: ' . $dir );
- }elseif( !is_dir($dir) ){
- throw new Less_Exception_Parser('Less.php cache directory doesn\'t exist: '.$dir);
+ } elseif ( !is_dir( $dir ) ) {
+ throw new Less_Exception_Parser( 'Less.php cache directory doesn\'t exist: ' . $dir );
- }elseif( !is_writable($dir) ){
- throw new Less_Exception_Parser('Less.php cache directory isn\'t writable: '.$dir);
+ } elseif ( !is_writable( $dir ) ) {
+ throw new Less_Exception_Parser( 'Less.php cache directory isn\'t writable: ' . $dir );
- }else{
- $dir = self::WinPath($dir);
- Less_Cache::$cache_dir = rtrim($dir,'/').'/';
+ } else {
+ $dir = self::WinPath( $dir );
+ Less_Cache::$cache_dir = rtrim( $dir, '/' ) . '/';
return true;
}
}
-
/**
* Set a list of directories or callbacks the parser should use for determining import paths
*
* @param array $dirs
*/
- public function SetImportDirs( $dirs ){
- Less_Parser::$options['import_dirs'] = array();
+ public function SetImportDirs( $dirs ) {
+ self::$options['import_dirs'] = [];
- foreach($dirs as $path => $uri_root){
+ foreach ( $dirs as $path => $uri_root ) {
- $path = self::WinPath($path);
- if( !empty($path) ){
- $path = rtrim($path,'/').'/';
+ $path = self::WinPath( $path );
+ if ( !empty( $path ) ) {
+ $path = rtrim( $path, '/' ) . '/';
}
- if ( !is_callable($uri_root) ){
- $uri_root = self::WinPath($uri_root);
- if( !empty($uri_root) ){
- $uri_root = rtrim($uri_root,'/').'/';
+ if ( !is_callable( $uri_root ) ) {
+ $uri_root = self::WinPath( $uri_root );
+ if ( !empty( $uri_root ) ) {
+ $uri_root = rtrim( $uri_root, '/' ) . '/';
}
}
- Less_Parser::$options['import_dirs'][$path] = $uri_root;
+ self::$options['import_dirs'][$path] = $uri_root;
}
}
/**
- * @param string $file_path
+ * @param string|null $file_path
*/
- private function _parse( $file_path = null ){
- $this->rules = array_merge($this->rules, $this->GetRules( $file_path ));
+ private function _parse( $file_path = null ) {
+ $this->rules = array_merge( $this->rules, $this->GetRules( $file_path ) );
}
-
/**
* Return the results of parsePrimary for $file_path
* Use cache and save cached results if possible
*
* @param string|null $file_path
*/
- private function GetRules( $file_path ){
-
- $this->SetInput($file_path);
+ private function GetRules( $file_path ) {
+ $this->SetInput( $file_path );
$cache_file = $this->CacheFile( $file_path );
- if( $cache_file ){
- if( Less_Parser::$options['cache_method'] == 'callback' ){
- if( is_callable(Less_Parser::$options['cache_callback_get']) ){
+ if ( $cache_file ) {
+ if ( self::$options['cache_method'] == 'callback' ) {
+ if ( is_callable( self::$options['cache_callback_get'] ) ) {
$cache = call_user_func_array(
- Less_Parser::$options['cache_callback_get'],
- array($this, $file_path, $cache_file)
+ self::$options['cache_callback_get'],
+ [ $this, $file_path, $cache_file ]
);
- if( $cache ){
+ if ( $cache ) {
$this->UnsetInput();
return $cache;
}
}
- }elseif( file_exists($cache_file) ){
- switch(Less_Parser::$options['cache_method']){
+ } elseif ( file_exists( $cache_file ) ) {
+ switch ( self::$options['cache_method'] ) {
// Using serialize
// Faster but uses more memory
case 'serialize':
- $cache = unserialize(file_get_contents($cache_file));
- if( $cache ){
- touch($cache_file);
+ $cache = unserialize( file_get_contents( $cache_file ) );
+ if ( $cache ) {
+ touch( $cache_file );
$this->UnsetInput();
return $cache;
}
break;
-
// Using generated php code
case 'var_export':
case 'php':
$this->UnsetInput();
- return include($cache_file);
+ return include $cache_file;
}
}
}
$rules = $this->parsePrimary();
- if( $this->pos < $this->input_len ){
- throw new Less_Exception_Chunk($this->input, null, $this->furthest, $this->env->currentFileInfo);
+ if ( $this->pos < $this->input_len ) {
+ throw new Less_Exception_Chunk( $this->input, null, $this->furthest, $this->env->currentFileInfo );
}
$this->UnsetInput();
-
- //save the cache
- if( $cache_file ){
- if( Less_Parser::$options['cache_method'] == 'callback' ){
- if( is_callable(Less_Parser::$options['cache_callback_set']) ){
+ // save the cache
+ if ( $cache_file ) {
+ if ( self::$options['cache_method'] == 'callback' ) {
+ if ( is_callable( self::$options['cache_callback_set'] ) ) {
call_user_func_array(
- Less_Parser::$options['cache_callback_set'],
- array($this, $file_path, $cache_file, $rules)
+ self::$options['cache_callback_set'],
+ [ $this, $file_path, $cache_file, $rules ]
);
}
- }else{
- //msg('write cache file');
- switch(Less_Parser::$options['cache_method']){
+ } else {
+ switch ( self::$options['cache_method'] ) {
case 'serialize':
- file_put_contents( $cache_file, serialize($rules) );
+ file_put_contents( $cache_file, serialize( $rules ) );
break;
case 'php':
- file_put_contents( $cache_file, '' );
+ // Mask PHP open tag to avoid breaking Doxygen
+ file_put_contents( $cache_file, '<' . '?php return ' . self::ArgString( $rules ) . '; ?>' );
break;
case 'var_export':
- //Requires __set_state()
- file_put_contents( $cache_file, '' );
+ // Requires __set_state()
+ file_put_contents( $cache_file, '<' . '?php return ' . var_export( $rules, true ) . '; ?>' );
break;
}
@@ -712,135 +659,126 @@ class Less_Parser{
return $rules;
}
-
/**
* Set up the input buffer
- *
*/
- public function SetInput( $file_path ){
-
- if( $file_path ){
+ public function SetInput( $file_path ) {
+ if ( $file_path ) {
$this->input = file_get_contents( $file_path );
}
$this->pos = $this->furthest = 0;
// Remove potential UTF Byte Order Mark
- $this->input = preg_replace('/\\G\xEF\xBB\xBF/', '', $this->input);
- $this->input_len = strlen($this->input);
+ $this->input = preg_replace( '/\\G\xEF\xBB\xBF/', '', $this->input );
+ $this->input_len = strlen( $this->input );
-
- if( Less_Parser::$options['sourceMap'] && $this->env->currentFileInfo ){
+ if ( self::$options['sourceMap'] && $this->env->currentFileInfo ) {
$uri = $this->env->currentFileInfo['currentUri'];
- Less_Parser::$contentsMap[$uri] = $this->input;
+ self::$contentsMap[$uri] = $this->input;
}
-
}
-
/**
* Free up some memory
- *
*/
- public function UnsetInput(){
- unset($this->input, $this->pos, $this->input_len, $this->furthest);
- $this->saveStack = array();
+ public function UnsetInput() {
+ $this->input = $this->pos = $this->input_len = $this->furthest = null;
+ $this->saveStack = [];
}
+ public function CacheFile( $file_path ) {
+ if ( $file_path && $this->CacheEnabled() ) {
- public function CacheFile( $file_path ){
+ $env = get_object_vars( $this->env );
+ unset( $env['frames'] );
- if( $file_path && $this->CacheEnabled() ){
-
- $env = get_object_vars($this->env);
- unset($env['frames']);
-
- $parts = array();
+ $parts = [];
$parts[] = $file_path;
$parts[] = filesize( $file_path );
$parts[] = filemtime( $file_path );
$parts[] = $env;
$parts[] = Less_Version::cache_version;
- $parts[] = Less_Parser::$options['cache_method'];
- return Less_Cache::$cache_dir . Less_Cache::$prefix . base_convert( sha1(json_encode($parts) ), 16, 36) . '.lesscache';
+ $parts[] = self::$options['cache_method'];
+ return Less_Cache::$cache_dir . Less_Cache::$prefix . base_convert( sha1( json_encode( $parts ) ), 16, 36 ) . '.lesscache';
}
}
-
- static function AddParsedFile($file){
+ static function AddParsedFile( $file ) {
self::$imports[] = $file;
}
- static function AllParsedFiles(){
+ static function AllParsedFiles() {
return self::$imports;
}
/**
* @param string $file
*/
- static function FileParsed($file){
- return in_array($file,self::$imports);
+ static function FileParsed( $file ) {
+ return in_array( $file, self::$imports );
}
-
function save() {
$this->saveStack[] = $this->pos;
}
private function restore() {
- $this->pos = array_pop($this->saveStack);
+ if ( $this->pos > $this->furthest ) {
+ $this->furthest = $this->pos;
+ }
+ $this->pos = array_pop( $this->saveStack );
}
- private function forget(){
- array_pop($this->saveStack);
+ private function forget() {
+ array_pop( $this->saveStack );
}
/**
* Determine if the character at the specified offset from the current position is a white space.
*
* @param int $offset
- *
* @return bool
*/
- private function isWhitespace($offset = 0) {
- return strpos(" \t\n\r\v\f", $this->input[$this->pos + $offset]) !== false;
+ private function isWhitespace( $offset = 0 ) {
+ // @phan-suppress-next-line PhanParamSuspiciousOrder False positive
+ return strpos( " \t\n\r\v\f", $this->input[$this->pos + $offset] ) !== false;
}
/**
* Parse from a token, regexp or string, and move forward if match
*
* @param array $toks
- * @return array
+ * @return null|string|array|Less_Tree
*/
- private function match($toks){
-
+ private function matcher( $toks ) {
// The match is confirmed, add the match length to `this::pos`,
// and consume any extra white-space characters (' ' || '\n')
// which come after that. The reason for this is that LeSS's
// grammar is mostly white-space insensitive.
//
- foreach($toks as $tok){
+ foreach ( $toks as $tok ) {
$char = $tok[0];
- if( $char === '/' ){
- $match = $this->MatchReg($tok);
+ if ( $char === '/' ) {
+ $match = $this->MatchReg( $tok );
- if( $match ){
- return count($match) === 1 ? $match[0] : $match;
+ if ( $match ) {
+ return count( $match ) === 1 ? $match[0] : $match;
}
- }elseif( $char === '#' ){
- $match = $this->MatchChar($tok[1]);
+ } elseif ( $char === '#' ) {
+ $match = $this->MatchChar( $tok[1] );
- }else{
+ } else {
// Non-terminal, match using a function call
$match = $this->$tok();
}
- if( $match ){
+ if ( $match ) {
return $match;
}
}
@@ -848,85 +786,86 @@ class Less_Parser{
/**
* @param string[] $toks
- *
- * @return string
+ * @return null|string|array|Less_Tree
*/
- private function MatchFuncs($toks){
-
- if( $this->pos < $this->input_len ){
- foreach($toks as $tok){
+ private function MatchFuncs( $toks ) {
+ if ( $this->pos < $this->input_len ) {
+ foreach ( $toks as $tok ) {
$match = $this->$tok();
- if( $match ){
+ if ( $match ) {
return $match;
}
}
}
-
}
- // Match a single character in the input,
- private function MatchChar($tok){
- if( ($this->pos < $this->input_len) && ($this->input[$this->pos] === $tok) ){
- $this->skipWhitespace(1);
+ /**
+ * Match a single character in the input.
+ *
+ * @param string $tok
+ * @see less-2.5.3.js#parserInput.$char
+ */
+ private function MatchChar( $tok ) {
+ if ( ( $this->pos < $this->input_len ) && ( $this->input[$this->pos] === $tok ) ) {
+ $this->skipWhitespace( 1 );
return $tok;
}
}
- // Match a regexp from the current start point
- private function MatchReg($tok){
-
- if( preg_match($tok, $this->input, $match, 0, $this->pos) ){
- $this->skipWhitespace(strlen($match[0]));
+ /**
+ * Match a regexp from the current start point
+ *
+ * @return array|null
+ */
+ private function MatchReg( $tok ) {
+ if ( preg_match( $tok, $this->input, $match, 0, $this->pos ) ) {
+ $this->skipWhitespace( strlen( $match[0] ) );
return $match;
}
}
-
/**
* Same as match(), but don't change the state of the parser,
* just return the match.
*
* @param string $tok
- * @return integer
+ * @return int|false
*/
- public function PeekReg($tok){
- return preg_match($tok, $this->input, $match, 0, $this->pos);
+ public function PeekReg( $tok ) {
+ return preg_match( $tok, $this->input, $match, 0, $this->pos );
}
/**
* @param string $tok
*/
- public function PeekChar($tok){
- //return ($this->input[$this->pos] === $tok );
- return ($this->pos < $this->input_len) && ($this->input[$this->pos] === $tok );
+ public function PeekChar( $tok ) {
+ return ( $this->pos < $this->input_len ) && ( $this->input[$this->pos] === $tok );
}
-
/**
- * @param integer $length
+ * @param int $length
+ * @see less-2.5.3.js#skipWhitespace
*/
- public function skipWhitespace($length){
-
+ public function skipWhitespace( $length ) {
$this->pos += $length;
- for(; $this->pos < $this->input_len; $this->pos++ ){
+ for ( ; $this->pos < $this->input_len; $this->pos++ ) {
$c = $this->input[$this->pos];
- if( ($c !== "\n") && ($c !== "\r") && ($c !== "\t") && ($c !== ' ') ){
+ if ( ( $c !== "\n" ) && ( $c !== "\r" ) && ( $c !== "\t" ) && ( $c !== ' ' ) ) {
break;
}
}
}
-
/**
* @param string $tok
* @param string|null $msg
*/
- public function expect($tok, $msg = NULL) {
- $result = $this->match( array($tok) );
- if (!$result) {
- $this->Error( $msg ? "Expected '" . $tok . "' got '" . $this->input[$this->pos] . "'" : $msg );
+ public function expect( $tok, $msg = null ) {
+ $result = $this->matcher( [ $tok ] );
+ if ( !$result ) {
+ $this->Error( $msg ? "Expected '" . $tok . "' got '" . $this->input[$this->pos] . "'" : $msg );
} else {
return $result;
}
@@ -934,13 +873,14 @@ class Less_Parser{
/**
* @param string $tok
+ * @param string|null $msg
*/
- public function expectChar($tok, $msg = null ){
- $result = $this->MatchChar($tok);
- if( !$result ){
- $msg = $msg ? $msg : "Expected '" . $tok . "' got '" . $this->input[$this->pos] . "'";
+ public function expectChar( $tok, $msg = null ) {
+ $result = $this->MatchChar( $tok );
+ if ( !$result ) {
+ $msg = $msg ?: "Expected '" . $tok . "' got '" . $this->input[$this->pos] . "'";
$this->Error( $msg );
- }else{
+ } else {
return $result;
}
}
@@ -990,31 +930,40 @@ class Less_Parser{
// Only at one point is the primary rule not called from the
// block rule: at the root level.
//
- private function parsePrimary(){
- $root = array();
+ // @see less-2.5.3.js#parsers.primary
+ private function parsePrimary() {
+ $root = [];
- while( true ){
+ while ( true ) {
- if( $this->pos >= $this->input_len ){
+ if ( $this->pos >= $this->input_len ) {
break;
}
- $node = $this->parseExtend(true);
- if( $node ){
- $root = array_merge($root,$node);
+ $node = $this->parseExtend( true );
+ if ( $node ) {
+ $root = array_merge( $root, $node );
continue;
}
- //$node = $this->MatchFuncs( array( 'parseMixinDefinition', 'parseRule', 'parseRuleset', 'parseMixinCall', 'parseComment', 'parseDirective'));
- $node = $this->MatchFuncs( array( 'parseMixinDefinition', 'parseNameValue', 'parseRule', 'parseRuleset', 'parseMixinCall', 'parseComment', 'parseRulesetCall', 'parseDirective'));
+ $node = $this->MatchFuncs( [
+ 'parseMixinDefinition',
+ 'parseNameValue',
+ 'parseRule',
+ 'parseRuleset',
+ 'parseMixinCall',
+ 'parseComment',
+ 'parseRulesetCall',
+ 'parseDirective'
+ ] );
- if( $node ){
+ if ( $node ) {
$root[] = $node;
- }elseif( !$this->MatchReg('/\\G[\s\n;]+/') ){
+ } elseif ( !$this->MatchReg( '/\\G[\s\n;]+/' ) ) {
break;
}
- if( $this->PeekChar('}') ){
+ if ( $this->PeekChar( '}' ) ) {
break;
}
}
@@ -1022,35 +971,32 @@ class Less_Parser{
return $root;
}
-
-
// We create a Comment node for CSS comments `/* */`,
// but keep the LeSS comments `//` silent, by just skipping
// over them.
- private function parseComment(){
-
- if( $this->input[$this->pos] !== '/' ){
+ private function parseComment() {
+ if ( $this->input[$this->pos] !== '/' ) {
return;
}
- if( $this->input[$this->pos+1] === '/' ){
- $match = $this->MatchReg('/\\G\/\/.*/');
- return $this->NewObj4('Less_Tree_Comment',array($match[0], true, $this->pos, $this->env->currentFileInfo));
+ if ( $this->input[$this->pos + 1] === '/' ) {
+ $match = $this->MatchReg( '/\\G\/\/.*/' );
+ return $this->NewObj( 'Less_Tree_Comment', [ $match[0], true, $this->pos, $this->env->currentFileInfo ] );
}
- //$comment = $this->MatchReg('/\\G\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/');
- $comment = $this->MatchReg('/\\G\/\*(?s).*?\*+\/\n?/');//not the same as less.js to prevent fatal errors
- if( $comment ){
- return $this->NewObj4('Less_Tree_Comment',array($comment[0], false, $this->pos, $this->env->currentFileInfo));
+ // $comment = $this->MatchReg('/\\G\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/');
+ $comment = $this->MatchReg( '/\\G\/\*(?s).*?\*+\/\n?/' );// not the same as less.js to prevent fatal errors
+ if ( $comment ) {
+ return $this->NewObj( 'Less_Tree_Comment', [ $comment[0], false, $this->pos, $this->env->currentFileInfo ] );
}
}
- private function parseComments(){
- $comments = array();
+ private function parseComments() {
+ $comments = [];
- while( $this->pos < $this->input_len ){
+ while ( $this->pos < $this->input_len ) {
$comment = $this->parseComment();
- if( !$comment ){
+ if ( !$comment ) {
break;
}
@@ -1060,43 +1006,41 @@ class Less_Parser{
return $comments;
}
-
-
- //
- // A string, which supports escaping " and '
- //
- // "milky way" 'he\'s the one!'
- //
+ /**
+ * A string, which supports escaping " and '
+ *
+ * "milky way" 'he\'s the one!'
+ *
+ * @return Less_Tree_Quoted|null
+ */
private function parseEntitiesQuoted() {
$j = $this->pos;
$e = false;
$index = $this->pos;
- if( $this->input[$this->pos] === '~' ){
+ if ( $this->input[$this->pos] === '~' ) {
$j++;
$e = true; // Escaped strings
}
$char = $this->input[$j];
- if( $char !== '"' && $char !== "'" ){
+ if ( $char !== '"' && $char !== "'" ) {
return;
}
- if ($e) {
- $this->MatchChar('~');
+ if ( $e ) {
+ $this->MatchChar( '~' );
}
-
- $matched = $this->MatchQuoted($char, $j+1);
- if( $matched === false ){
+ $matched = $this->MatchQuoted( $char, $j + 1 );
+ if ( $matched === false ) {
return;
}
- $quoted = $char.$matched.$char;
- return $this->NewObj5('Less_Tree_Quoted',array($quoted, $matched, $e, $index, $this->env->currentFileInfo) );
+ $quoted = $char . $matched . $char;
+ return $this->NewObj( 'Less_Tree_Quoted', [ $quoted, $matched, $e, $index, $this->env->currentFileInfo ] );
}
-
/**
* When PCRE JIT is enabled in php, regular expressions don't work for matching quoted strings
*
@@ -1104,26 +1048,25 @@ class Less_Parser{
* $regex = '/\\G"((?:[^"\\\\\r\n]|\\\\.|\\\\\r\n|\\\\[\n\r\f])*)"/';
*
*/
- private function MatchQuoted($quote_char, $i){
-
+ private function MatchQuoted( $quote_char, $i ) {
$matched = '';
- while( $i < $this->input_len ){
+ while ( $i < $this->input_len ) {
$c = $this->input[$i];
- //escaped character
- if( $c === '\\' ){
- $matched .= $c . $this->input[$i+1];
+ // escaped character
+ if ( $c === '\\' ) {
+ $matched .= $c . $this->input[$i + 1];
$i += 2;
continue;
}
- if( $c === $quote_char ){
- $this->pos = $i+1;
- $this->skipWhitespace(0);
+ if ( $c === $quote_char ) {
+ $this->pos = $i + 1;
+ $this->skipWhitespace( 0 );
return $matched;
}
- if( $c === "\r" || $c === "\n" ){
+ if ( $c === "\r" || $c === "\n" ) {
return false;
}
@@ -1134,37 +1077,37 @@ class Less_Parser{
return false;
}
-
- //
- // A catch-all word, such as:
- //
- // black border-collapse
- //
- private function parseEntitiesKeyword(){
-
- //$k = $this->MatchReg('/\\G[_A-Za-z-][_A-Za-z0-9-]*/');
- $k = $this->MatchReg('/\\G%|\\G[_A-Za-z-][_A-Za-z0-9-]*/');
- if( $k ){
+ /**
+ * A catch-all word, such as:
+ *
+ * black border-collapse
+ *
+ * @return Less_Tree_Keyword|Less_Tree_Color|null
+ */
+ private function parseEntitiesKeyword() {
+ // $k = $this->MatchReg('/\\G[_A-Za-z-][_A-Za-z0-9-]*/');
+ $k = $this->MatchReg( '/\\G%|\\G[_A-Za-z-][_A-Za-z0-9-]*/' );
+ if ( $k ) {
$k = $k[0];
- $color = $this->fromKeyword($k);
- if( $color ){
+ $color = $this->fromKeyword( $k );
+ if ( $color ) {
return $color;
}
- return $this->NewObj1('Less_Tree_Keyword',$k);
+ return $this->NewObj( 'Less_Tree_Keyword', [ $k ] );
}
}
// duplicate of Less_Tree_Color::FromKeyword
- private function FromKeyword( $keyword ){
- $keyword = strtolower($keyword);
+ private function FromKeyword( $keyword ) {
+ $keyword = strtolower( $keyword );
- if( Less_Colors::hasOwnProperty($keyword) ){
+ if ( Less_Colors::hasOwnProperty( $keyword ) ) {
// detect named color
- return $this->NewObj1('Less_Tree_Color',substr(Less_Colors::color($keyword), 1));
+ return $this->NewObj( 'Less_Tree_Color', [ substr( Less_Colors::color( $keyword ), 1 ) ] );
}
- if( $keyword === 'transparent' ){
- return $this->NewObj3('Less_Tree_Color', array( array(0, 0, 0), 0, true));
+ if ( $keyword === 'transparent' ) {
+ return $this->NewObj( 'Less_Tree_Color', [ [ 0, 0, 0 ], 0, true ] );
}
}
@@ -1178,86 +1121,89 @@ class Less_Parser{
//
// The arguments are parsed with the `entities.arguments` parser.
//
- private function parseEntitiesCall(){
+ private function parseEntitiesCall() {
$index = $this->pos;
- if( !preg_match('/\\G([\w-]+|%|progid:[\w\.]+)\(/', $this->input, $name,0,$this->pos) ){
+ if ( !preg_match( '/\\G([\w-]+|%|progid:[\w\.]+)\(/', $this->input, $name, 0, $this->pos ) ) {
return;
}
$name = $name[1];
- $nameLC = strtolower($name);
+ $nameLC = strtolower( $name );
- if ($nameLC === 'url') {
+ if ( $nameLC === 'url' ) {
return null;
}
- $this->pos += strlen($name);
+ $this->pos += strlen( $name );
- if( $nameLC === 'alpha' ){
+ if ( $nameLC === 'alpha' ) {
$alpha_ret = $this->parseAlpha();
- if( $alpha_ret ){
+ if ( $alpha_ret ) {
return $alpha_ret;
}
}
- $this->MatchChar('('); // Parse the '(' and consume whitespace.
+ $this->MatchChar( '(' ); // Parse the '(' and consume whitespace.
$args = $this->parseEntitiesArguments();
- if( !$this->MatchChar(')') ){
+ if ( !$this->MatchChar( ')' ) ) {
return;
}
- if ($name) {
- return $this->NewObj4('Less_Tree_Call',array($name, $args, $index, $this->env->currentFileInfo) );
+ if ( $name ) {
+ return $this->NewObj( 'Less_Tree_Call', [ $name, $args, $index, $this->env->currentFileInfo ] );
}
}
/**
* Parse a list of arguments
*
- * @return array
+ * @return array
*/
- private function parseEntitiesArguments(){
-
- $args = array();
- while( true ){
- $arg = $this->MatchFuncs( array('parseEntitiesAssignment','parseExpression') );
- if( !$arg ){
+ private function parseEntitiesArguments() {
+ $args = [];
+ while ( true ) {
+ $arg = $this->MatchFuncs( [ 'parseEntitiesAssignment', 'parseExpression' ] );
+ if ( !$arg ) {
break;
}
$args[] = $arg;
- if( !$this->MatchChar(',') ){
+ if ( !$this->MatchChar( ',' ) ) {
break;
}
}
return $args;
}
- private function parseEntitiesLiteral(){
- return $this->MatchFuncs( array('parseEntitiesDimension','parseEntitiesColor','parseEntitiesQuoted','parseUnicodeDescriptor') );
+ /** @return Less_Tree_Dimension|Less_Tree_Color|Less_Tree_Quoted|Less_Tree_UnicodeDescriptor|null */
+ private function parseEntitiesLiteral() {
+ return $this->MatchFuncs( [ 'parseEntitiesDimension','parseEntitiesColor','parseEntitiesQuoted','parseUnicodeDescriptor' ] );
}
- // Assignments are argument entities for calls.
- // They are present in ie filter properties as shown below.
- //
- // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )
- //
+ /**
+ * Assignments are argument entities for calls.
+ *
+ * They are present in IE filter properties as shown below.
+ *
+ * filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )
+ *
+ * @return Less_Tree_Assignment|null
+ */
private function parseEntitiesAssignment() {
-
- $key = $this->MatchReg('/\\G\w+(?=\s?=)/');
- if( !$key ){
+ $key = $this->MatchReg( '/\\G\w+(?=\s?=)/' );
+ if ( !$key ) {
return;
}
- if( !$this->MatchChar('=') ){
+ if ( !$this->MatchChar( '=' ) ) {
return;
}
$value = $this->parseEntity();
- if( $value ){
- return $this->NewObj2('Less_Tree_Assignment',array($key[0], $value));
+ if ( $value ) {
+ return $this->NewObj( 'Less_Tree_Assignment', [ $key[0], $value ] );
}
}
@@ -1268,196 +1214,197 @@ class Less_Parser{
// standard function calls. The difference is that the argument doesn't have
// to be enclosed within a string, so it can't be parsed as an Expression.
//
- private function parseEntitiesUrl(){
-
-
- if( $this->input[$this->pos] !== 'u' || !$this->matchReg('/\\Gurl\(/') ){
+ private function parseEntitiesUrl() {
+ if ( $this->input[$this->pos] !== 'u' || !$this->matchReg( '/\\Gurl\(/' ) ) {
return;
}
- $value = $this->match( array('parseEntitiesQuoted','parseEntitiesVariable','/\\Gdata\:.*?[^\)]+/','/\\G(?:(?:\\\\[\(\)\'"])|[^\(\)\'"])+/') );
- if( !$value ){
+ $value = $this->matcher( [ 'parseEntitiesQuoted','parseEntitiesVariable','/\\Gdata\:.*?[^\)]+/','/\\G(?:(?:\\\\[\(\)\'"])|[^\(\)\'"])+/' ] );
+ if ( !$value ) {
$value = '';
}
+ $this->expectChar( ')' );
- $this->expectChar(')');
-
-
- if( isset($value->value) || $value instanceof Less_Tree_Variable ){
- return $this->NewObj2('Less_Tree_Url',array($value, $this->env->currentFileInfo));
+ // @phan-suppress-next-line PhanUndeclaredProperty
+ if ( isset( $value->value ) || $value instanceof Less_Tree_Variable ) {
+ return $this->NewObj( 'Less_Tree_Url', [ $value, $this->env->currentFileInfo ] );
}
- return $this->NewObj2('Less_Tree_Url', array( $this->NewObj1('Less_Tree_Anonymous',$value), $this->env->currentFileInfo) );
+ return $this->NewObj( 'Less_Tree_Url', [ $this->NewObj( 'Less_Tree_Anonymous', [ $value ] ), $this->env->currentFileInfo ] );
}
-
- //
- // A Variable entity, such as `@fink`, in
- //
- // width: @fink + 2px
- //
- // We use a different parser for variable definitions,
- // see `parsers.variable`.
- //
- private function parseEntitiesVariable(){
+ /**
+ * A Variable entity, such as `@fink`, in
+ *
+ * width: @fink + 2px
+ *
+ * We use a different parser for variable definitions,
+ * see `parsers.variable`.
+ *
+ * @return Less_Tree_Variable|null
+ */
+ private function parseEntitiesVariable() {
$index = $this->pos;
- if ($this->PeekChar('@') && ($name = $this->MatchReg('/\\G@@?[\w-]+/'))) {
- return $this->NewObj3('Less_Tree_Variable', array( $name[0], $index, $this->env->currentFileInfo));
+ if ( $this->PeekChar( '@' ) && ( $name = $this->MatchReg( '/\\G@@?[\w-]+/' ) ) ) {
+ return $this->NewObj( 'Less_Tree_Variable', [ $name[0], $index, $this->env->currentFileInfo ] );
}
}
-
- // A variable entity using the protective {} e.g. @{var}
+ /**
+ * A variable entity using the protective `{}` e.g. `@{var}`.
+ *
+ * @return Less_Tree_Variable|null
+ */
private function parseEntitiesVariableCurly() {
$index = $this->pos;
- if( $this->input_len > ($this->pos+1) && $this->input[$this->pos] === '@' && ($curly = $this->MatchReg('/\\G@\{([\w-]+)\}/')) ){
- return $this->NewObj3('Less_Tree_Variable',array('@'.$curly[1], $index, $this->env->currentFileInfo));
+ if ( $this->input_len > ( $this->pos + 1 ) && $this->input[$this->pos] === '@' && ( $curly = $this->MatchReg( '/\\G@\{([\w-]+)\}/' ) ) ) {
+ return $this->NewObj( 'Less_Tree_Variable', [ '@' . $curly[1], $index, $this->env->currentFileInfo ] );
}
}
- //
- // A Hexadecimal color
- //
- // #4F3C2F
- //
- // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
- //
- private function parseEntitiesColor(){
- if ($this->PeekChar('#') && ($rgb = $this->MatchReg('/\\G#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/'))) {
- return $this->NewObj1('Less_Tree_Color',$rgb[1]);
+ /**
+ * A Hexadecimal color
+ *
+ * #4F3C2F
+ *
+ * `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+ *
+ * @return Less_Tree_Color|null
+ */
+ private function parseEntitiesColor() {
+ if ( $this->PeekChar( '#' ) && ( $rgb = $this->MatchReg( '/\\G#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/' ) ) ) {
+ return $this->NewObj( 'Less_Tree_Color', [ $rgb[1] ] );
}
}
- //
- // A Dimension, that is, a number and a unit
- //
- // 0.5em 95%
- //
- private function parseEntitiesDimension(){
+ /**
+ * A Dimension, that is, a number and a unit
+ *
+ * 0.5em 95%
+ *
+ * @return Less_Tree_Dimension|null
+ */
+ private function parseEntitiesDimension() {
+ $c = @ord( $this->input[$this->pos] );
- $c = @ord($this->input[$this->pos]);
-
- //Is the first char of the dimension 0-9, '.', '+' or '-'
- if (($c > 57 || $c < 43) || $c === 47 || $c == 44){
+ // Is the first char of the dimension 0-9, '.', '+' or '-'
+ if ( ( $c > 57 || $c < 43 ) || $c === 47 || $c == 44 ) {
return;
}
- $value = $this->MatchReg('/\\G([+-]?\d*\.?\d+)(%|[a-z]+)?/');
- if( $value ){
-
- if( isset($value[2]) ){
- return $this->NewObj2('Less_Tree_Dimension', array($value[1],$value[2]));
+ $value = $this->MatchReg( '/\\G([+-]?\d*\.?\d+)(%|[a-z]+)?/' );
+ if ( $value ) {
+ if ( isset( $value[2] ) ) {
+ return $this->NewObj( 'Less_Tree_Dimension', [ $value[1],$value[2] ] );
}
- return $this->NewObj1('Less_Tree_Dimension',$value[1]);
+ return $this->NewObj( 'Less_Tree_Dimension', [ $value[1] ] );
}
}
-
- //
- // A unicode descriptor, as is used in unicode-range
- //
- // U+0?? or U+00A1-00A9
- //
+ /**
+ * A unicode descriptor, as is used in unicode-range
+ *
+ * U+0?? or U+00A1-00A9
+ *
+ * @return Less_Tree_UnicodeDescriptor|null
+ */
function parseUnicodeDescriptor() {
- $ud = $this->MatchReg('/\\G(U\+[0-9a-fA-F?]+)(\-[0-9a-fA-F?]+)?/');
- if( $ud ){
- return $this->NewObj1('Less_Tree_UnicodeDescriptor', $ud[0]);
+ $ud = $this->MatchReg( '/\\G(U\+[0-9a-fA-F?]+)(\-[0-9a-fA-F?]+)?/' );
+ if ( $ud ) {
+ return $this->NewObj( 'Less_Tree_UnicodeDescriptor', [ $ud[0] ] );
}
}
-
//
// JavaScript code to be evaluated
//
// `window.location.href`
//
- private function parseEntitiesJavascript(){
+ private function parseEntitiesJavascript() {
$e = false;
$j = $this->pos;
- if( $this->input[$j] === '~' ){
+ if ( $this->input[$j] === '~' ) {
$j++;
$e = true;
}
- if( $this->input[$j] !== '`' ){
+ if ( $this->input[$j] !== '`' ) {
return;
}
- if( $e ){
- $this->MatchChar('~');
+ if ( $e ) {
+ $this->MatchChar( '~' );
}
- $str = $this->MatchReg('/\\G`([^`]*)`/');
- if( $str ){
- return $this->NewObj3('Less_Tree_Javascript', array($str[1], $this->pos, $e));
+ $str = $this->MatchReg( '/\\G`([^`]*)`/' );
+ if ( $str ) {
+ return $this->NewObj( 'Less_Tree_Javascript', [ $str[1], $this->pos, $e ] );
}
}
-
//
// The variable part of a variable definition. Used in the `rule` parser
//
// @fink:
//
- private function parseVariable(){
- if ($this->PeekChar('@') && ($name = $this->MatchReg('/\\G(@[\w-]+)\s*:/'))) {
+ private function parseVariable() {
+ if ( $this->PeekChar( '@' ) && ( $name = $this->MatchReg( '/\\G(@[\w-]+)\s*:/' ) ) ) {
return $name[1];
}
}
-
//
// The variable part of a variable definition. Used in the `rule` parser
//
// @fink();
//
- private function parseRulesetCall(){
-
- if( $this->input[$this->pos] === '@' && ($name = $this->MatchReg('/\\G(@[\w-]+)\s*\(\s*\)\s*;/')) ){
- return $this->NewObj1('Less_Tree_RulesetCall', $name[1] );
+ private function parseRulesetCall() {
+ if ( $this->input[$this->pos] === '@' && ( $name = $this->MatchReg( '/\\G(@[\w-]+)\s*\(\s*\)\s*;/' ) ) ) {
+ return $this->NewObj( 'Less_Tree_RulesetCall', [ $name[1] ] );
}
}
-
//
// extend syntax - used to extend selectors
//
- function parseExtend($isRule = false){
-
+ function parseExtend( $isRule = false ) {
$index = $this->pos;
- $extendList = array();
+ $extendList = [];
+ if ( !$this->MatchReg( $isRule ? '/\\G&:extend\(/' : '/\\G:extend\(/' ) ) {
+ return;
+ }
- if( !$this->MatchReg( $isRule ? '/\\G&:extend\(/' : '/\\G:extend\(/' ) ){ return; }
-
- do{
+ do {
$option = null;
- $elements = array();
- while( true ){
- $option = $this->MatchReg('/\\G(all)(?=\s*(\)|,))/');
- if( $option ){ break; }
+ $elements = [];
+ while ( true ) {
+ $option = $this->MatchReg( '/\\G(all)(?=\s*(\)|,))/' );
+ if ( $option ) { break;
+ }
$e = $this->parseElement();
- if( !$e ){ break; }
+ if ( !$e ) {
+ break;
+ }
$elements[] = $e;
}
- if( $option ){
+ if ( $option ) {
$option = $option[1];
}
- $extendList[] = $this->NewObj3('Less_Tree_Extend', array( $this->NewObj1('Less_Tree_Selector',$elements), $option, $index ));
+ $extendList[] = $this->NewObj( 'Less_Tree_Extend', [ $this->NewObj( 'Less_Tree_Selector', [ $elements ] ), $option, $index ] );
- }while( $this->MatchChar(",") );
+ } while ( $this->MatchChar( "," ) );
- $this->expect('/\\G\)/');
+ $this->expect( '/\\G\)/' );
- if( $isRule ){
- $this->expect('/\\G;/');
+ if ( $isRule ) {
+ $this->expect( '/\\G;/' );
}
return $extendList;
}
-
//
// A Mixin call, with an optional argument list
//
@@ -1469,10 +1416,9 @@ class Less_Parser{
// namespaced, but we only support the child and descendant
// selector for now.
//
- private function parseMixinCall(){
-
+ private function parseMixinCall() {
$char = $this->input[$this->pos];
- if( $char !== '.' && $char !== '#' ){
+ if ( $char !== '.' && $char !== '#' ) {
return;
}
@@ -1481,110 +1427,106 @@ class Less_Parser{
$elements = $this->parseMixinCallElements();
- if( $elements ){
+ if ( $elements ) {
- if( $this->MatchChar('(') ){
- $returned = $this->parseMixinArgs(true);
+ if ( $this->MatchChar( '(' ) ) {
+ $returned = $this->parseMixinArgs( true );
$args = $returned['args'];
- $this->expectChar(')');
- }else{
- $args = array();
+ $this->expectChar( ')' );
+ } else {
+ $args = [];
}
$important = $this->parseImportant();
- if( $this->parseEnd() ){
+ if ( $this->parseEnd() ) {
$this->forget();
- return $this->NewObj5('Less_Tree_Mixin_Call', array( $elements, $args, $index, $this->env->currentFileInfo, $important));
+ return $this->NewObj( 'Less_Tree_Mixin_Call', [ $elements, $args, $index, $this->env->currentFileInfo, $important ] );
}
}
$this->restore();
}
-
- private function parseMixinCallElements(){
- $elements = array();
+ private function parseMixinCallElements() {
+ $elements = [];
$c = null;
- while( true ){
+ while ( true ) {
$elemIndex = $this->pos;
- $e = $this->MatchReg('/\\G[#.](?:[\w-]|\\\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/');
- if( !$e ){
+ $e = $this->MatchReg( '/\\G[#.](?:[\w-]|\\\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/' );
+ if ( !$e ) {
break;
}
- $elements[] = $this->NewObj4('Less_Tree_Element', array($c, $e[0], $elemIndex, $this->env->currentFileInfo));
- $c = $this->MatchChar('>');
+ $elements[] = $this->NewObj( 'Less_Tree_Element', [ $c, $e[0], $elemIndex, $this->env->currentFileInfo ] );
+ $c = $this->MatchChar( '>' );
}
return $elements;
}
-
-
/**
- * @param boolean $isCall
+ * @param bool $isCall
*/
- private function parseMixinArgs( $isCall ){
- $expressions = array();
- $argsSemiColon = array();
+ private function parseMixinArgs( $isCall ) {
+ $expressions = [];
+ $argsSemiColon = [];
$isSemiColonSeperated = null;
- $argsComma = array();
+ $argsComma = [];
$expressionContainsNamed = null;
$name = null;
- $returner = array('args'=>array(), 'variadic'=> false);
+ $returner = [ 'args' => [], 'variadic' => false ];
$this->save();
- while( true ){
- if( $isCall ){
- $arg = $this->MatchFuncs( array( 'parseDetachedRuleset','parseExpression' ) );
+ while ( true ) {
+ if ( $isCall ) {
+ $arg = $this->MatchFuncs( [ 'parseDetachedRuleset', 'parseExpression' ] );
} else {
$this->parseComments();
- if( $this->input[ $this->pos ] === '.' && $this->MatchReg('/\\G\.{3}/') ){
+ if ( $this->input[ $this->pos ] === '.' && $this->MatchReg( '/\\G\.{3}/' ) ) {
$returner['variadic'] = true;
- if( $this->MatchChar(";") && !$isSemiColonSeperated ){
+ if ( $this->MatchChar( ";" ) && !$isSemiColonSeperated ) {
$isSemiColonSeperated = true;
}
- if( $isSemiColonSeperated ){
- $argsSemiColon[] = array('variadic'=>true);
- }else{
- $argsComma[] = array('variadic'=>true);
+ if ( $isSemiColonSeperated ) {
+ $argsSemiColon[] = [ 'variadic' => true ];
+ } else {
+ $argsComma[] = [ 'variadic' => true ];
}
break;
}
- $arg = $this->MatchFuncs( array('parseEntitiesVariable','parseEntitiesLiteral','parseEntitiesKeyword') );
+ $arg = $this->MatchFuncs( [ 'parseEntitiesVariable', 'parseEntitiesLiteral', 'parseEntitiesKeyword' ] );
}
+ '@phan-var Less_Tree_DetachedRuleset|Less_Tree_Expression|Less_Tree_Variable|Less_Tree_Dimension|Less_Tree_Color|Less_Tree_Quoted|Less_Tree_UnicodeDescriptor|Less_Tree_Keyword|null $arg';
- if( !$arg ){
+ if ( !$arg ) {
break;
}
-
$nameLoop = null;
- if( $arg instanceof Less_Tree_Expression ){
+ if ( $arg instanceof Less_Tree_Expression ) {
$arg->throwAwayComments();
}
$value = $arg;
$val = null;
- if( $isCall ){
+ if ( $isCall ) {
// Variable
- if( property_exists($arg,'value') && count($arg->value) == 1 ){
+ if ( property_exists( $arg, 'value' ) && count( $arg->value ) == 1 ) {
$val = $arg->value[0];
}
} else {
$val = $arg;
}
+ if ( $val instanceof Less_Tree_Variable ) {
- if( $val instanceof Less_Tree_Variable ){
-
- if( $this->MatchChar(':') ){
- if( $expressions ){
- if( $isSemiColonSeperated ){
- $this->Error('Cannot mix ; and , as delimiter types');
+ if ( $this->MatchChar( ':' ) ) {
+ if ( $expressions ) {
+ if ( $isSemiColonSeperated ) {
+ $this->Error( 'Cannot mix ; and , as delimiter types' );
}
$expressionContainsNamed = true;
}
@@ -1593,77 +1535,75 @@ class Less_Parser{
// However if we do want to add it, there is nothing blocking it, just don't error
// and remove isCall dependency below
$value = null;
- if( $isCall ){
+ if ( $isCall ) {
$value = $this->parseDetachedRuleset();
}
- if( !$value ){
+ if ( !$value ) {
$value = $this->parseExpression();
}
- if( !$value ){
- if( $isCall ){
- $this->Error('could not understand value for named argument');
+ if ( !$value ) {
+ if ( $isCall ) {
+ $this->Error( 'could not understand value for named argument' );
} else {
$this->restore();
- $returner['args'] = array();
+ $returner['args'] = [];
return $returner;
}
}
- $nameLoop = ($name = $val->name);
- }elseif( !$isCall && $this->MatchReg('/\\G\.{3}/') ){
+ $nameLoop = ( $name = $val->name );
+ } elseif ( !$isCall && $this->MatchReg( '/\\G\.{3}/' ) ) {
$returner['variadic'] = true;
- if( $this->MatchChar(";") && !$isSemiColonSeperated ){
+ if ( $this->MatchChar( ";" ) && !$isSemiColonSeperated ) {
$isSemiColonSeperated = true;
}
- if( $isSemiColonSeperated ){
- $argsSemiColon[] = array('name'=> $arg->name, 'variadic' => true);
- }else{
- $argsComma[] = array('name'=> $arg->name, 'variadic' => true);
+ if ( $isSemiColonSeperated ) {
+ $argsSemiColon[] = [ 'name' => $arg->name, 'variadic' => true ];
+ } else {
+ $argsComma[] = [ 'name' => $arg->name, 'variadic' => true ];
}
break;
- }elseif( !$isCall ){
+ } elseif ( !$isCall ) {
$name = $nameLoop = $val->name;
$value = null;
}
}
- if( $value ){
+ if ( $value ) {
$expressions[] = $value;
}
- $argsComma[] = array('name'=>$nameLoop, 'value'=>$value );
+ $argsComma[] = [ 'name' => $nameLoop, 'value' => $value ];
- if( $this->MatchChar(',') ){
+ if ( $this->MatchChar( ',' ) ) {
continue;
}
- if( $this->MatchChar(';') || $isSemiColonSeperated ){
+ if ( $this->MatchChar( ';' ) || $isSemiColonSeperated ) {
- if( $expressionContainsNamed ){
- $this->Error('Cannot mix ; and , as delimiter types');
+ if ( $expressionContainsNamed ) {
+ $this->Error( 'Cannot mix ; and , as delimiter types' );
}
$isSemiColonSeperated = true;
- if( count($expressions) > 1 ){
- $value = $this->NewObj1('Less_Tree_Value', $expressions);
+ if ( count( $expressions ) > 1 ) {
+ $value = $this->NewObj( 'Less_Tree_Value', [ $expressions ] );
}
- $argsSemiColon[] = array('name'=>$name, 'value'=>$value );
+ $argsSemiColon[] = [ 'name' => $name, 'value' => $value ];
$name = null;
- $expressions = array();
+ $expressions = [];
$expressionContainsNamed = false;
}
}
$this->forget();
- $returner['args'] = ($isSemiColonSeperated ? $argsSemiColon : $argsComma);
+ $returner['args'] = ( $isSemiColonSeperated ? $argsSemiColon : $argsComma );
return $returner;
}
-
-
//
// A Mixin definition, with a list of parameters
//
@@ -1683,52 +1623,50 @@ class Less_Parser{
// Once we've got our params list, and a closing `)`, we parse
// the `{...}` block.
//
- private function parseMixinDefinition(){
+ private function parseMixinDefinition() {
$cond = null;
$char = $this->input[$this->pos];
- if( ($char !== '.' && $char !== '#') || ($char === '{' && $this->PeekReg('/\\G[^{]*\}/')) ){
+ // TODO: Less.js doesn't limit this to $char == '{'.
+ if ( ( $char !== '.' && $char !== '#' ) || ( $char === '{' && $this->PeekReg( '/\\G[^{]*\}/' ) ) ) {
return;
}
$this->save();
- $match = $this->MatchReg('/\\G([#.](?:[\w-]|\\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/');
- if( $match ){
+ $match = $this->MatchReg( '/\\G([#.](?:[\w-]|\\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/' );
+ if ( $match ) {
$name = $match[1];
$argInfo = $this->parseMixinArgs( false );
$params = $argInfo['args'];
$variadic = $argInfo['variadic'];
-
// .mixincall("@{a}");
// looks a bit like a mixin definition..
// also
// .mixincall(@a: {rule: set;});
// so we have to be nice and restore
- if( !$this->MatchChar(')') ){
- $this->furthest = $this->pos;
+ if ( !$this->MatchChar( ')' ) ) {
$this->restore();
return;
}
-
$this->parseComments();
- if ($this->MatchReg('/\\Gwhen/')) { // Guard
- $cond = $this->expect('parseConditions', 'Expected conditions');
+ if ( $this->MatchReg( '/\\Gwhen/' ) ) { // Guard
+ $cond = $this->expect( 'parseConditions', 'Expected conditions' );
}
$ruleset = $this->parseBlock();
- if( is_array($ruleset) ){
+ if ( $ruleset !== null ) {
$this->forget();
- return $this->NewObj5('Less_Tree_Mixin_Definition', array( $name, $params, $ruleset, $cond, $variadic));
+ return $this->NewObj( 'Less_Tree_Mixin_Definition', [ $name, $params, $ruleset, $cond, $variadic ] );
}
$this->restore();
- }else{
+ } else {
$this->forget();
}
}
@@ -1737,9 +1675,8 @@ class Less_Parser{
// Entities are the smallest recognized token,
// and can be found inside a rule's value.
//
- private function parseEntity(){
-
- return $this->MatchFuncs( array('parseEntitiesLiteral','parseEntitiesVariable','parseEntitiesUrl','parseEntitiesCall','parseEntitiesKeyword','parseEntitiesJavascript','parseComment') );
+ private function parseEntity() {
+ return $this->MatchFuncs( [ 'parseEntitiesLiteral','parseEntitiesVariable','parseEntitiesUrl','parseEntitiesCall','parseEntitiesKeyword','parseEntitiesJavascript','parseComment' ] );
}
//
@@ -1747,8 +1684,8 @@ class Less_Parser{
// because the `block` rule will be expecting it, but we still need to make sure
// it's there, if ';' was omitted.
//
- private function parseEnd(){
- return $this->MatchChar(';') || $this->PeekChar('}');
+ private function parseEnd() {
+ return $this->MatchChar( ';' ) || $this->PeekChar( '}' );
}
//
@@ -1756,62 +1693,72 @@ class Less_Parser{
//
// alpha(opacity=88)
//
- private function parseAlpha(){
-
- if ( ! $this->MatchReg('/\\G\(opacity=/i')) {
+ private function parseAlpha() {
+ if ( !$this->MatchReg( '/\\G\(opacity=/i' ) ) {
return;
}
- $value = $this->MatchReg('/\\G[0-9]+/');
- if( $value ){
+ $value = $this->MatchReg( '/\\G[0-9]+/' );
+ if ( $value ) {
$value = $value[0];
- }else{
+ } else {
$value = $this->parseEntitiesVariable();
- if( !$value ){
+ if ( !$value ) {
return;
}
}
- $this->expectChar(')');
- return $this->NewObj1('Less_Tree_Alpha',$value);
+ $this->expectChar( ')' );
+ return $this->NewObj( 'Less_Tree_Alpha', [ $value ] );
}
-
- //
- // A Selector Element
- //
- // div
- // + h1
- // #socks
- // input[type="text"]
- //
- // Elements are the building blocks for Selectors,
- // they are made out of a `Combinator` (see combinator rule),
- // and an element name, such as a tag a class, or `*`.
- //
- private function parseElement(){
+ /**
+ * A Selector Element
+ *
+ * div
+ * + h1
+ * #socks
+ * input[type="text"]
+ *
+ * Elements are the building blocks for Selectors,
+ * they are made out of a `Combinator` (see combinator rule),
+ * and an element name, such as a tag a class, or `*`.
+ *
+ * @return Less_Tree_Element|null
+ * @see less-2.5.3.js#parsers.element
+ */
+ private function parseElement() {
$c = $this->parseCombinator();
$index = $this->pos;
- $e = $this->match( array('/\\G(?:\d+\.\d+|\d+)%/', '/\\G(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/',
- '#*', '#&', 'parseAttribute', '/\\G\([^()@]+\)/', '/\\G[\.#](?=@)/', 'parseEntitiesVariableCurly') );
+ // TODO: Speed up by calling MatchChar directly, like less.js does
+ $e = $this->matcher( [
+ '/\\G(?:\d+\.\d+|\d+)%/',
+ '/\\G(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/',
+ '#*',
+ '#&',
+ 'parseAttribute',
+ '/\\G\([^&()@]+\)/',
+ '/\\G[\.#:](?=@)/',
+ 'parseEntitiesVariableCurly'
+ ] );
- if( is_null($e) ){
+ if ( $e === null ) {
$this->save();
- if( $this->MatchChar('(') ){
- if( ($v = $this->parseSelector()) && $this->MatchChar(')') ){
- $e = $this->NewObj1('Less_Tree_Paren',$v);
+ if ( $this->MatchChar( '(' ) ) {
+ if ( ( $v = $this->parseSelector() ) && $this->MatchChar( ')' ) ) {
+ $e = $this->NewObj( 'Less_Tree_Paren', [ $v ] );
$this->forget();
- }else{
+ } else {
$this->restore();
}
- }else{
+ } else {
$this->forget();
}
}
- if( !is_null($e) ){
- return $this->NewObj4('Less_Tree_Element',array( $c, $e, $index, $this->env->currentFileInfo));
+ if ( $e !== null ) {
+ return $this->NewObj( 'Less_Tree_Element', [ $c, $e, $index, $this->env->currentFileInfo ] );
}
}
@@ -1823,47 +1770,55 @@ class Less_Parser{
// as it's an empty space. We have to check the previous character
// in the input, to see if it's a ` ` character.
//
- private function parseCombinator(){
- if( $this->pos < $this->input_len ){
+ // @see less-2.5.3.js#parsers.combinator
+ private function parseCombinator() {
+ if ( $this->pos < $this->input_len ) {
$c = $this->input[$this->pos];
- if ($c === '>' || $c === '+' || $c === '~' || $c === '|' || $c === '^' ){
+ // TODO: Figure out why less.js also handles '/' here, and implement with regression test.
+ if ( $c === '>' || $c === '+' || $c === '~' || $c === '|' || $c === '^' ) {
$this->pos++;
- if( $this->input[$this->pos] === '^' ){
+ if ( $this->input[$this->pos] === '^' ) {
$c = '^^';
$this->pos++;
}
- $this->skipWhitespace(0);
+ $this->skipWhitespace( 0 );
return $c;
}
- if( $this->pos > 0 && $this->isWhitespace(-1) ){
+ if ( $this->pos > 0 && $this->isWhitespace( -1 ) ) {
return ' ';
}
}
}
- //
- // A CSS selector (see selector below)
- // with less extensions e.g. the ability to extend and guard
- //
- private function parseLessSelector(){
- return $this->parseSelector(true);
+ /**
+ * A CSS selector (see selector below)
+ * with less extensions e.g. the ability to extend and guard
+ *
+ * @return Less_Tree_Selector|null
+ * @see less-2.5.3.js#parsers.lessSelector
+ */
+ private function parseLessSelector() {
+ return $this->parseSelector( true );
}
- //
- // A CSS Selector
- //
- // .class > div + h1
- // li a:hover
- //
- // Selectors are made out of one or more Elements, see above.
- //
- private function parseSelector( $isLess = false ){
- $elements = array();
- $extendList = array();
+ /**
+ * A CSS Selector
+ *
+ * .class > div + h1
+ * li a:hover
+ *
+ * Selectors are made out of one or more Elements, see ::parseElement.
+ *
+ * @return Less_Tree_Selector|null
+ * @see less-2.5.3.js#parsers.selector
+ */
+ private function parseSelector( $isLess = false ) {
+ $elements = [];
+ $extendList = [];
$condition = null;
$when = false;
$extend = false;
@@ -1871,233 +1826,241 @@ class Less_Parser{
$c = null;
$index = $this->pos;
- while( ($isLess && ($extend = $this->parseExtend())) || ($isLess && ($when = $this->MatchReg('/\\Gwhen/') )) || ($e = $this->parseElement()) ){
- if( $when ){
- $condition = $this->expect('parseConditions', 'expected condition');
- }elseif( $condition ){
- //error("CSS guard can only be used at the end of selector");
- }elseif( $extend ){
- $extendList = array_merge($extendList,$extend);
- }else{
- //if( count($extendList) ){
+ while ( ( $isLess && ( $extend = $this->parseExtend() ) ) || ( $isLess && ( $when = $this->MatchReg( '/\\Gwhen/' ) ) ) || ( $e = $this->parseElement() ) ) {
+ if ( $when ) {
+ $condition = $this->expect( 'parseConditions', 'expected condition' );
+ } elseif ( $condition ) {
+ // error("CSS guard can only be used at the end of selector");
+ } elseif ( $extend ) {
+ $extendList = array_merge( $extendList, $extend );
+ } else {
+ // if( count($extendList) ){
//error("Extend can only be used at the end of selector");
//}
- if( $this->pos < $this->input_len ){
+ if ( $this->pos < $this->input_len ) {
$c = $this->input[ $this->pos ];
}
$elements[] = $e;
$e = null;
}
- if( $c === '{' || $c === '}' || $c === ';' || $c === ',' || $c === ')') { break; }
+ if ( $c === '{' || $c === '}' || $c === ';' || $c === ',' || $c === ')' ) {
+ break;
+ }
}
- if( $elements ){
- return $this->NewObj5('Less_Tree_Selector',array($elements, $extendList, $condition, $index, $this->env->currentFileInfo));
+ if ( $elements ) {
+ return $this->NewObj( 'Less_Tree_Selector', [ $elements, $extendList, $condition, $index, $this->env->currentFileInfo ] );
}
- if( $extendList ) {
- $this->Error('Extend must be used to extend a selector, it cannot be used on its own');
+ if ( $extendList ) {
+ $this->Error( 'Extend must be used to extend a selector, it cannot be used on its own' );
}
}
- private function parseTag(){
- return ( $tag = $this->MatchReg('/\\G[A-Za-z][A-Za-z-]*[0-9]?/') ) ? $tag : $this->MatchChar('*');
+ private function parseTag() {
+ return ( $tag = $this->MatchReg( '/\\G[A-Za-z][A-Za-z-]*[0-9]?/' ) ) ? $tag : $this->MatchChar( '*' );
}
- private function parseAttribute(){
-
+ private function parseAttribute() {
$val = null;
- if( !$this->MatchChar('[') ){
+ if ( !$this->MatchChar( '[' ) ) {
return;
}
$key = $this->parseEntitiesVariableCurly();
- if( !$key ){
- $key = $this->expect('/\\G(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\\\.)+/');
+ if ( !$key ) {
+ $key = $this->expect( '/\\G(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\\\.)+/' );
}
- $op = $this->MatchReg('/\\G[|~*$^]?=/');
- if( $op ){
- $val = $this->match( array('parseEntitiesQuoted','/\\G[0-9]+%/','/\\G[\w-]+/','parseEntitiesVariableCurly') );
+ $op = $this->MatchReg( '/\\G[|~*$^]?=/' );
+ if ( $op ) {
+ $val = $this->matcher( [ 'parseEntitiesQuoted','/\\G[0-9]+%/','/\\G[\w-]+/','parseEntitiesVariableCurly' ] );
}
- $this->expectChar(']');
+ $this->expectChar( ']' );
- return $this->NewObj3('Less_Tree_Attribute',array( $key, $op === null ? null : $op[0], $val));
+ return $this->NewObj( 'Less_Tree_Attribute', [ $key, $op === null ? null : $op[0], $val ] );
}
- //
- // The `block` rule is used by `ruleset` and `mixin.definition`.
- // It's a wrapper around the `primary` rule, with added `{}`.
- //
- private function parseBlock(){
- if( $this->MatchChar('{') ){
+ /**
+ * The `block` rule is used by `ruleset` and `mixin.definition`.
+ * It's a wrapper around the `primary` rule, with added `{}`.
+ *
+ * @return array|null
+ * @see less-2.5.3.js#parsers.block
+ */
+ private function parseBlock() {
+ if ( $this->MatchChar( '{' ) ) {
$content = $this->parsePrimary();
- if( $this->MatchChar('}') ){
+ if ( $this->MatchChar( '}' ) ) {
return $content;
}
}
}
- private function parseBlockRuleset(){
+ private function parseBlockRuleset() {
$block = $this->parseBlock();
- if( $block ){
- $block = $this->NewObj2('Less_Tree_Ruleset',array( null, $block));
+ if ( $block ) {
+ $block = $this->NewObj( 'Less_Tree_Ruleset', [ null, $block ] );
}
return $block;
}
- private function parseDetachedRuleset(){
+ /** @return Less_Tree_DetachedRuleset|null */
+ private function parseDetachedRuleset() {
$blockRuleset = $this->parseBlockRuleset();
- if( $blockRuleset ){
- return $this->NewObj1('Less_Tree_DetachedRuleset',$blockRuleset);
+ if ( $blockRuleset ) {
+ return $this->NewObj( 'Less_Tree_DetachedRuleset', [ $blockRuleset ] );
}
}
- //
- // div, .class, body > p {...}
- //
- private function parseRuleset(){
- $selectors = array();
+ /**
+ * Ruleset such as:
+ *
+ * div, .class, body > p {
+ * }
+ *
+ * @return Less_Tree_Ruleset|null
+ * @see less-2.5.3.js#parsers.ruleset
+ */
+ private function parseRuleset() {
+ $selectors = [];
$this->save();
- while( true ){
+ while ( true ) {
$s = $this->parseLessSelector();
- if( !$s ){
+ if ( !$s ) {
break;
}
$selectors[] = $s;
$this->parseComments();
- if( $s->condition && count($selectors) > 1 ){
- $this->Error('Guards are only currently allowed on a single selector.');
+ if ( $s->condition && count( $selectors ) > 1 ) {
+ $this->Error( 'Guards are only currently allowed on a single selector.' );
}
- if( !$this->MatchChar(',') ){
+ if ( !$this->MatchChar( ',' ) ) {
break;
}
- if( $s->condition ){
- $this->Error('Guards are only currently allowed on a single selector.');
+ if ( $s->condition ) {
+ $this->Error( 'Guards are only currently allowed on a single selector.' );
}
$this->parseComments();
}
-
- if( $selectors ){
+ if ( $selectors ) {
$rules = $this->parseBlock();
- if( is_array($rules) ){
+ if ( is_array( $rules ) ) {
$this->forget();
- return $this->NewObj2('Less_Tree_Ruleset',array( $selectors, $rules)); //Less_Environment::$strictImports
+ // TODO: Less_Environment::$strictImports is not yet ported
+ // It is passed here by less.js
+ return $this->NewObj( 'Less_Tree_Ruleset', [ $selectors, $rules ] );
}
}
// Backtrack
- $this->furthest = $this->pos;
$this->restore();
}
/**
* Custom less.php parse function for finding simple name-value css pairs
* ex: width:100px;
- *
*/
- private function parseNameValue(){
-
+ private function parseNameValue() {
$index = $this->pos;
$this->save();
+ $match = $this->MatchReg( '/\\G([a-zA-Z\-]+)\s*:\s*([\'"]?[#a-zA-Z0-9\-%\.,]+?[\'"]?) *(! *important)?\s*([;}])/' );
+ if ( $match ) {
- //$match = $this->MatchReg('/\\G([a-zA-Z\-]+)\s*:\s*((?:\'")?[a-zA-Z0-9\-% \.,!]+?(?:\'")?)\s*([;}])/');
- $match = $this->MatchReg('/\\G([a-zA-Z\-]+)\s*:\s*([\'"]?[#a-zA-Z0-9\-%\.,]+?[\'"]?) *(! *important)?\s*([;}])/');
- if( $match ){
-
- if( $match[4] == '}' ){
- $this->pos = $index + strlen($match[0])-1;
+ if ( $match[4] == '}' ) {
+ $this->pos = $index + strlen( $match[0] ) - 1;
}
- if( $match[3] ){
+ if ( $match[3] ) {
$match[2] .= ' !important';
}
- return $this->NewObj4('Less_Tree_NameValue',array( $match[1], $match[2], $index, $this->env->currentFileInfo));
+ return $this->NewObj( 'Less_Tree_NameValue', [ $match[1], $match[2], $index, $this->env->currentFileInfo ] );
}
$this->restore();
}
-
- private function parseRule( $tryAnonymous = null ){
-
- $merge = false;
+ // @see less-2.5.3.js#parsers.rule
+ private function parseRule( $tryAnonymous = null ) {
+ $value = null;
$startOfRule = $this->pos;
-
$c = $this->input[$this->pos];
- if( $c === '.' || $c === '#' || $c === '&' ){
+ $important = null;
+ $merge = false;
+
+ // TODO: Figure out why less.js also handles ':' here, and implement with regression test.
+ if ( $c === '.' || $c === '#' || $c === '&' ) {
return;
}
$this->save();
- $name = $this->MatchFuncs( array('parseVariable','parseRuleProperty'));
+ $name = $this->MatchFuncs( [ 'parseVariable', 'parseRuleProperty' ] );
- if( $name ){
+ if ( $name ) {
+ $isVariable = is_string( $name );
- $isVariable = is_string($name);
-
- $value = null;
- if( $isVariable ){
+ if ( $isVariable ) {
$value = $this->parseDetachedRuleset();
}
- $important = null;
- if( !$value ){
-
- // prefer to try to parse first if its a variable or we are compressing
- // but always fallback on the other one
- //if( !$tryAnonymous && is_string($name) && $name[0] === '@' ){
- if( !$tryAnonymous && (Less_Parser::$options['compress'] || $isVariable) ){
- $value = $this->MatchFuncs( array('parseValue','parseAnonymousValue'));
- }else{
- $value = $this->MatchFuncs( array('parseAnonymousValue','parseValue'));
- }
-
- $important = $this->parseImportant();
-
+ if ( !$value ) {
// a name returned by this.ruleProperty() is always an array of the form:
// [string-1, ..., string-n, ""] or [string-1, ..., string-n, "+"]
// where each item is a tree.Keyword or tree.Variable
- if( !$isVariable && is_array($name) ){
- $nm = array_pop($name);
- if( $nm->value ){
- $merge = $nm->value;
+ if ( !$isVariable && count( $name ) > 1 ) {
+ $merge = array_pop( $name )->value;
+ }
+
+ // prefer to try to parse first if its a variable or we are compressing
+ // but always fallback on the other one
+ $tryValueFirst = ( !$tryAnonymous && ( self::$options['compress'] || $isVariable ) );
+ if ( $tryValueFirst ) {
+ $value = $this->parseValue();
+ }
+ if ( !$value ) {
+ $value = $this->parseAnonymousValue();
+ if ( $value ) {
+ $this->forget();
+ // anonymous values absorb the end ';' which is required for them to work
+ return $this->NewObj( 'Less_Tree_Rule', [ $name, $value, false, $merge, $startOfRule, $this->env->currentFileInfo ] );
}
}
+ if ( !$tryValueFirst && !$value ) {
+ $value = $this->parseValue();
+ }
+
+ $important = $this->parseImportant();
}
-
- if( $value && $this->parseEnd() ){
+ if ( $value && $this->parseEnd() ) {
$this->forget();
- return $this->NewObj6('Less_Tree_Rule',array( $name, $value, $important, $merge, $startOfRule, $this->env->currentFileInfo));
- }else{
- $this->furthest = $this->pos;
+ return $this->NewObj( 'Less_Tree_Rule', [ $name, $value, $important, $merge, $startOfRule, $this->env->currentFileInfo ] );
+ } else {
$this->restore();
- if( $value && !$tryAnonymous ){
- return $this->parseRule(true);
+ if ( $value && !$tryAnonymous ) {
+ return $this->parseRule( true );
}
}
- }else{
+ } else {
$this->forget();
}
}
- function parseAnonymousValue(){
-
- if( preg_match('/\\G([^@+\/\'"*`(;{}-]*);/',$this->input, $match, 0, $this->pos) ){
- $this->pos += strlen($match[1]);
- return $this->NewObj1('Less_Tree_Anonymous',$match[1]);
+ function parseAnonymousValue() {
+ $match = $this->MatchReg( '/\\G([^@+\/\'"*`(;{}-]*);/' );
+ if ( $match ) {
+ return $this->NewObj( 'Less_Tree_Anonymous', [ $match[1] ] );
}
}
@@ -2111,25 +2074,24 @@ class Less_Parser{
// file-system operation. The function used for importing is
// stored in `import`, which we pass to the Import constructor.
//
- private function parseImport(){
-
+ private function parseImport() {
$this->save();
- $dir = $this->MatchReg('/\\G@import?\s+/');
+ $dir = $this->MatchReg( '/\\G@import?\s+/' );
- if( $dir ){
+ if ( $dir ) {
$options = $this->parseImportOptions();
- $path = $this->MatchFuncs( array('parseEntitiesQuoted','parseEntitiesUrl'));
+ $path = $this->MatchFuncs( [ 'parseEntitiesQuoted','parseEntitiesUrl' ] );
- if( $path ){
+ if ( $path ) {
$features = $this->parseMediaFeatures();
- if( $this->MatchChar(';') ){
- if( $features ){
- $features = $this->NewObj1('Less_Tree_Value',$features);
+ if ( $this->MatchChar( ';' ) ) {
+ if ( $features ) {
+ $features = $this->NewObj( 'Less_Tree_Value', [ $features ] );
}
$this->forget();
- return $this->NewObj5('Less_Tree_Import',array( $path, $features, $options, $this->pos, $this->env->currentFileInfo));
+ return $this->NewObj( 'Less_Tree_Import', [ $path, $features, $options, $this->pos, $this->env->currentFileInfo ] );
}
}
}
@@ -2137,19 +2099,18 @@ class Less_Parser{
$this->restore();
}
- private function parseImportOptions(){
-
- $options = array();
+ private function parseImportOptions() {
+ $options = [];
// list of options, surrounded by parens
- if( !$this->MatchChar('(') ){
+ if ( !$this->MatchChar( '(' ) ) {
return $options;
}
do{
$optionName = $this->parseImportOption();
- if( $optionName ){
+ if ( $optionName ) {
$value = true;
- switch( $optionName ){
+ switch ( $optionName ) {
case "css":
$optionName = "less";
$value = false;
@@ -2160,89 +2121,99 @@ class Less_Parser{
break;
}
$options[$optionName] = $value;
- if( !$this->MatchChar(',') ){ break; }
+ if ( !$this->MatchChar( ',' ) ) { break;
+ }
}
- }while( $optionName );
- $this->expectChar(')');
+ }while ( $optionName );
+ $this->expectChar( ')' );
return $options;
}
- private function parseImportOption(){
- $opt = $this->MatchReg('/\\G(less|css|multiple|once|inline|reference|optional)/');
- if( $opt ){
+ private function parseImportOption() {
+ $opt = $this->MatchReg( '/\\G(less|css|multiple|once|inline|reference|optional)/' );
+ if ( $opt ) {
return $opt[1];
}
}
private function parseMediaFeature() {
- $nodes = array();
+ $nodes = [];
do{
- $e = $this->MatchFuncs(array('parseEntitiesKeyword','parseEntitiesVariable'));
- if( $e ){
+ $e = $this->MatchFuncs( [ 'parseEntitiesKeyword','parseEntitiesVariable' ] );
+ if ( $e ) {
$nodes[] = $e;
- } elseif ($this->MatchChar('(')) {
+ } elseif ( $this->MatchChar( '(' ) ) {
$p = $this->parseProperty();
$e = $this->parseValue();
- if ($this->MatchChar(')')) {
- if ($p && $e) {
- $r = $this->NewObj7('Less_Tree_Rule', array( $p, $e, null, null, $this->pos, $this->env->currentFileInfo, true));
- $nodes[] = $this->NewObj1('Less_Tree_Paren',$r);
- } elseif ($e) {
- $nodes[] = $this->NewObj1('Less_Tree_Paren',$e);
+ if ( $this->MatchChar( ')' ) ) {
+ if ( $p && $e ) {
+ $r = $this->NewObj( 'Less_Tree_Rule', [ $p, $e, null, null, $this->pos, $this->env->currentFileInfo, true ] );
+ $nodes[] = $this->NewObj( 'Less_Tree_Paren', [ $r ] );
+ } elseif ( $e ) {
+ $nodes[] = $this->NewObj( 'Less_Tree_Paren', [ $e ] );
} else {
return null;
}
- } else
+ } else {
return null;
+ }
}
- } while ($e);
+ } while ( $e );
- if ($nodes) {
- return $this->NewObj1('Less_Tree_Expression',$nodes);
+ if ( $nodes ) {
+ return $this->NewObj( 'Less_Tree_Expression', [ $nodes ] );
}
}
private function parseMediaFeatures() {
- $features = array();
+ $features = [];
- do{
+ do {
$e = $this->parseMediaFeature();
- if( $e ){
+ if ( $e ) {
$features[] = $e;
- if (!$this->MatchChar(',')) break;
- }else{
+ if ( !$this->MatchChar( ',' ) ) {
+ break;
+ }
+ } else {
$e = $this->parseEntitiesVariable();
- if( $e ){
+ if ( $e ) {
$features[] = $e;
- if (!$this->MatchChar(',')) break;
+ if ( !$this->MatchChar( ',' ) ) {
+ break;
+ }
}
}
- } while ($e);
+ } while ( $e );
- return $features ? $features : null;
+ return $features ?: null;
}
private function parseMedia() {
- if( $this->MatchReg('/\\G@media/') ){
+ if ( $this->MatchReg( '/\\G@media/' ) ) {
+ $this->save();
+
$features = $this->parseMediaFeatures();
$rules = $this->parseBlock();
- if( is_array($rules) ){
- return $this->NewObj4('Less_Tree_Media',array( $rules, $features, $this->pos, $this->env->currentFileInfo));
+ if ( $rules === null ) {
+ $this->restore();
+ return;
}
+
+ $this->forget();
+ return $this->NewObj( 'Less_Tree_Media', [ $rules, $features, $this->pos, $this->env->currentFileInfo ] );
}
}
-
//
// A CSS Directive
//
// @charset "utf-8";
//
- private function parseDirective(){
-
- if( !$this->PeekChar('@') ){
+ private function parseDirective() {
+ if ( !$this->PeekChar( '@' ) ) {
return;
}
@@ -2253,28 +2224,30 @@ class Less_Parser{
$hasExpression = false;
$hasUnknown = false;
-
- $value = $this->MatchFuncs(array('parseImport','parseMedia'));
- if( $value ){
+ $value = $this->MatchFuncs( [
+ 'parseImport',
+ 'parseMedia'
+ ] );
+ if ( $value ) {
return $value;
}
$this->save();
- $name = $this->MatchReg('/\\G@[a-z-]+/');
+ $name = $this->MatchReg( '/\\G@[a-z-]+/' );
- if( !$name ) return;
+ if ( !$name ) {
+ return;
+ }
$name = $name[0];
-
$nonVendorSpecificName = $name;
- $pos = strpos($name,'-', 2);
- if( $name[1] == '-' && $pos > 0 ){
- $nonVendorSpecificName = "@" . substr($name, $pos + 1);
+ $pos = strpos( $name, '-', 2 );
+ if ( $name[1] == '-' && $pos > 0 ) {
+ $nonVendorSpecificName = "@" . substr( $name, $pos + 1 );
}
-
- switch( $nonVendorSpecificName ){
+ switch ( $nonVendorSpecificName ) {
/*
case "@font-face":
case "@viewport":
@@ -2316,37 +2289,36 @@ class Less_Parser{
break;
}
- if( $hasIdentifier ){
+ if ( $hasIdentifier ) {
$value = $this->parseEntity();
- if( !$value ){
- $this->error("expected " . $name . " identifier");
+ if ( !$value ) {
+ $this->error( "expected " . $name . " identifier" );
}
- } else if( $hasExpression ){
+ } elseif ( $hasExpression ) {
$value = $this->parseExpression();
- if( !$value ){
- $this->error("expected " . $name. " expression");
+ if ( !$value ) {
+ $this->error( "expected " . $name . " expression" );
}
- } else if ($hasUnknown) {
+ } elseif ( $hasUnknown ) {
- $value = $this->MatchReg('/\\G[^{;]+/');
- if( $value ){
- $value = $this->NewObj1('Less_Tree_Anonymous',trim($value[0]));
+ $value = $this->MatchReg( '/\\G[^{;]+/' );
+ if ( $value ) {
+ $value = $this->NewObj( 'Less_Tree_Anonymous', [ trim( $value[0] ) ] );
}
}
- if( $hasBlock ){
+ if ( $hasBlock ) {
$rules = $this->parseBlockRuleset();
}
- if( $rules || (!$hasBlock && $value && $this->MatchChar(';'))) {
+ if ( $rules || ( !$hasBlock && $value && $this->MatchChar( ';' ) ) ) {
$this->forget();
- return $this->NewObj5('Less_Tree_Directive',array($name, $value, $rules, $index, $this->env->currentFileInfo));
+ return $this->NewObj( 'Less_Tree_Directive', [ $name, $value, $rules, $index, $this->env->currentFileInfo ] );
}
$this->restore();
}
-
//
// A Value is a comma-delimited list of Expressions
//
@@ -2355,121 +2327,115 @@ class Less_Parser{
// In a Rule, a Value represents everything after the `:`,
// and before the `;`.
//
- private function parseValue(){
- $expressions = array();
+ private function parseValue() {
+ $expressions = [];
do{
$e = $this->parseExpression();
- if( $e ){
+ if ( $e ) {
$expressions[] = $e;
- if (! $this->MatchChar(',')) {
+ if ( !$this->MatchChar( ',' ) ) {
break;
}
}
- }while($e);
+ } while ( $e );
- if( $expressions ){
- return $this->NewObj1('Less_Tree_Value',$expressions);
+ if ( $expressions ) {
+ return $this->NewObj( 'Less_Tree_Value', [ $expressions ] );
}
}
- private function parseImportant (){
- if( $this->PeekChar('!') && $this->MatchReg('/\\G! *important/') ){
+ private function parseImportant() {
+ if ( $this->PeekChar( '!' ) && $this->MatchReg( '/\\G! *important/' ) ) {
return ' !important';
}
}
- private function parseSub (){
-
- if( $this->MatchChar('(') ){
+ private function parseSub() {
+ if ( $this->MatchChar( '(' ) ) {
$a = $this->parseAddition();
- if( $a ){
- $this->expectChar(')');
- return $this->NewObj2('Less_Tree_Expression',array( array($a), true) ); //instead of $e->parens = true so the value is cached
+ if ( $a ) {
+ $this->expectChar( ')' );
+ return $this->NewObj( 'Less_Tree_Expression', [ [ $a ], true ] ); // instead of $e->parens = true so the value is cached
}
}
}
-
/**
* Parses multiplication operation
*
* @return Less_Tree_Operation|null
*/
- function parseMultiplication(){
-
+ function parseMultiplication() {
$return = $m = $this->parseOperand();
- if( $return ){
- while( true ){
+ if ( $return ) {
+ while ( true ) {
$isSpaced = $this->isWhitespace( -1 );
- if( $this->PeekReg('/\\G\/[*\/]/') ){
+ if ( $this->PeekReg( '/\\G\/[*\/]/' ) ) {
break;
}
- $op = $this->MatchChar('/');
- if( !$op ){
- $op = $this->MatchChar('*');
- if( !$op ){
+ $op = $this->MatchChar( '/' );
+ if ( !$op ) {
+ $op = $this->MatchChar( '*' );
+ if ( !$op ) {
break;
}
}
$a = $this->parseOperand();
- if(!$a) { break; }
+ if ( !$a ) { break;
+ }
$m->parensInOp = true;
$a->parensInOp = true;
- $return = $this->NewObj3('Less_Tree_Operation',array( $op, array( $return, $a ), $isSpaced) );
+ $return = $this->NewObj( 'Less_Tree_Operation', [ $op, [ $return, $a ], $isSpaced ] );
}
}
return $return;
-
}
-
/**
* Parses an addition operation
*
* @return Less_Tree_Operation|null
*/
- private function parseAddition (){
-
+ private function parseAddition() {
$return = $m = $this->parseMultiplication();
- if( $return ){
- while( true ){
+ if ( $return ) {
+ while ( true ) {
$isSpaced = $this->isWhitespace( -1 );
- $op = $this->MatchReg('/\\G[-+]\s+/');
- if( $op ){
+ $op = $this->MatchReg( '/\\G[-+]\s+/' );
+ if ( $op ) {
$op = $op[0];
- }else{
- if( !$isSpaced ){
- $op = $this->match(array('#+','#-'));
+ } else {
+ if ( !$isSpaced ) {
+ $op = $this->matcher( [ '#+','#-' ] );
}
- if( !$op ){
+ if ( !$op ) {
break;
}
}
$a = $this->parseMultiplication();
- if( !$a ){
+ if ( !$a ) {
break;
}
$m->parensInOp = true;
$a->parensInOp = true;
- $return = $this->NewObj3('Less_Tree_Operation',array($op, array($return, $a), $isSpaced));
+ $return = $this->NewObj( 'Less_Tree_Operation', [ $op, [ $return, $a ], $isSpaced ] );
}
}
return $return;
}
-
/**
* Parses the conditions
*
@@ -2478,17 +2444,17 @@ class Less_Parser{
private function parseConditions() {
$index = $this->pos;
$return = $a = $this->parseCondition();
- if( $a ){
- while( true ){
- if( !$this->PeekReg('/\\G,\s*(not\s*)?\(/') || !$this->MatchChar(',') ){
+ if ( $a ) {
+ while ( true ) {
+ if ( !$this->PeekReg( '/\\G,\s*(not\s*)?\(/' ) || !$this->MatchChar( ',' ) ) {
break;
}
$b = $this->parseCondition();
- if( !$b ){
+ if ( !$b ) {
break;
}
- $return = $this->NewObj4('Less_Tree_Condition',array('or', $return, $b, $index));
+ $return = $this->NewObj( 'Less_Tree_Condition', [ 'or', $return, $b, $index ] );
}
return $return;
}
@@ -2499,318 +2465,265 @@ class Less_Parser{
$negate = false;
$c = null;
- if ($this->MatchReg('/\\Gnot/')) $negate = true;
- $this->expectChar('(');
- $a = $this->MatchFuncs(array('parseAddition','parseEntitiesKeyword','parseEntitiesQuoted'));
+ if ( $this->MatchReg( '/\\Gnot/' ) ) {
+ $negate = true;
+ }
+ $this->expectChar( '(' );
+ $a = $this->MatchFuncs( [ 'parseAddition','parseEntitiesKeyword','parseEntitiesQuoted' ] );
- if( $a ){
- $op = $this->MatchReg('/\\G(?:>=|<=|=<|[<=>])/');
- if( $op ){
- $b = $this->MatchFuncs(array('parseAddition','parseEntitiesKeyword','parseEntitiesQuoted'));
- if( $b ){
- $c = $this->NewObj5('Less_Tree_Condition',array($op[0], $a, $b, $index, $negate));
+ if ( $a ) {
+ $op = $this->MatchReg( '/\\G(?:>=|<=|=<|[<=>])/' );
+ if ( $op ) {
+ $b = $this->MatchFuncs( [ 'parseAddition','parseEntitiesKeyword','parseEntitiesQuoted' ] );
+ if ( $b ) {
+ $c = $this->NewObj( 'Less_Tree_Condition', [ $op[0], $a, $b, $index, $negate ] );
} else {
- $this->Error('Unexpected expression');
+ $this->Error( 'Unexpected expression' );
}
} else {
- $k = $this->NewObj1('Less_Tree_Keyword','true');
- $c = $this->NewObj5('Less_Tree_Condition',array('=', $a, $k, $index, $negate));
+ $k = $this->NewObj( 'Less_Tree_Keyword', [ 'true' ] );
+ $c = $this->NewObj( 'Less_Tree_Condition', [ '=', $a, $k, $index, $negate ] );
}
- $this->expectChar(')');
- return $this->MatchReg('/\\Gand/') ? $this->NewObj3('Less_Tree_Condition',array('and', $c, $this->parseCondition())) : $c;
+ $this->expectChar( ')' );
+ // @phan-suppress-next-line PhanPossiblyInfiniteRecursionSameParams
+ return $this->MatchReg( '/\\Gand/' ) ? $this->NewObj( 'Less_Tree_Condition', [ 'and', $c, $this->parseCondition() ] ) : $c;
}
}
/**
* An operand is anything that can be part of an operation,
* such as a Color, or a Variable
- *
*/
- private function parseOperand (){
-
+ private function parseOperand() {
$negate = false;
- $offset = $this->pos+1;
- if( $offset >= $this->input_len ){
+ $offset = $this->pos + 1;
+ if ( $offset >= $this->input_len ) {
return;
}
$char = $this->input[$offset];
- if( $char === '@' || $char === '(' ){
- $negate = $this->MatchChar('-');
+ if ( $char === '@' || $char === '(' ) {
+ $negate = $this->MatchChar( '-' );
}
- $o = $this->MatchFuncs(array('parseSub','parseEntitiesDimension','parseEntitiesColor','parseEntitiesVariable','parseEntitiesCall'));
+ $o = $this->MatchFuncs( [ 'parseSub','parseEntitiesDimension','parseEntitiesColor','parseEntitiesVariable','parseEntitiesCall' ] );
- if( $negate ){
+ if ( $negate ) {
$o->parensInOp = true;
- $o = $this->NewObj1('Less_Tree_Negative',$o);
+ $o = $this->NewObj( 'Less_Tree_Negative', [ $o ] );
}
return $o;
}
-
/**
* Expressions either represent mathematical operations,
* or white-space delimited Entities.
*
- * 1px solid black
- * @var * 2
- *
* @return Less_Tree_Expression|null
*/
- private function parseExpression (){
- $entities = array();
+ private function parseExpression() {
+ $entities = [];
- do{
- $e = $this->MatchFuncs(array('parseAddition','parseEntity'));
- if( $e ){
+ do {
+ $e = $this->MatchFuncs( [ 'parseAddition','parseEntity' ] );
+ if ( $e ) {
$entities[] = $e;
// operations do not allow keyword "/" dimension (e.g. small/20px) so we support that here
- if( !$this->PeekReg('/\\G\/[\/*]/') ){
- $delim = $this->MatchChar('/');
- if( $delim ){
- $entities[] = $this->NewObj1('Less_Tree_Anonymous',$delim);
+ if ( !$this->PeekReg( '/\\G\/[\/*]/' ) ) {
+ $delim = $this->MatchChar( '/' );
+ if ( $delim ) {
+ $entities[] = $this->NewObj( 'Less_Tree_Anonymous', [ $delim ] );
}
}
}
- }while($e);
+ } while ( $e );
- if( $entities ){
- return $this->NewObj1('Less_Tree_Expression',$entities);
+ if ( $entities ) {
+ return $this->NewObj( 'Less_Tree_Expression', [ $entities ] );
}
}
-
/**
* Parse a property
* eg: 'min-width', 'orientation', etc
*
* @return string
*/
- private function parseProperty (){
- $name = $this->MatchReg('/\\G(\*?-?[_a-zA-Z0-9-]+)\s*:/');
- if( $name ){
+ private function parseProperty() {
+ $name = $this->MatchReg( '/\\G(\*?-?[_a-zA-Z0-9-]+)\s*:/' );
+ if ( $name ) {
return $name[1];
}
}
-
/**
* Parse a rule property
* eg: 'color', 'width', 'height', etc
*
- * @return string
+ * @return array
*/
- private function parseRuleProperty(){
- $offset = $this->pos;
- $name = array();
- $index = array();
- $length = 0;
+ private function parseRuleProperty() {
+ $name = [];
+ $index = [];
+ $this->save();
- $this->rulePropertyMatch('/\\G(\*?)/', $offset, $length, $index, $name );
- while( $this->rulePropertyMatch('/\\G((?:[\w-]+)|(?:@\{[\w-]+\}))/', $offset, $length, $index, $name )); // !
-
- if( (count($name) > 1) && $this->rulePropertyMatch('/\\G\s*((?:\+_|\+)?)\s*:/', $offset, $length, $index, $name) ){
- // at last, we have the complete match now. move forward,
- // convert name particles to tree objects and return:
- $this->skipWhitespace($length);
-
- if( $name[0] === '' ){
- array_shift($name);
- array_shift($index);
- }
- foreach($name as $k => $s ){
- if( !$s || $s[0] !== '@' ){
- $name[$k] = $this->NewObj1('Less_Tree_Keyword',$s);
- }else{
- $name[$k] = $this->NewObj3('Less_Tree_Variable',array('@' . substr($s,2,-1), $index[$k], $this->env->currentFileInfo));
- }
- }
+ $simpleProperty = $this->MatchReg( '/\\G([_a-zA-Z0-9-]+)\s*:/' );
+ if ( $simpleProperty ) {
+ $name[] = $this->NewObj( 'Less_Tree_Keyword', [ $simpleProperty[1] ] );
+ $this->forget();
return $name;
}
+ $this->rulePropertyMatch( '/\\G(\*?)/', $index, $name );
+ // Consume!
+ // @phan-suppress-next-line PhanPluginEmptyStatementWhileLoop
+ while ( $this->rulePropertyMatch( '/\\G((?:[\w-]+)|(?:@\{[\w-]+\}))/', $index, $name ) );
+
+ if ( ( count( $name ) > 1 ) && $this->rulePropertyMatch( '/\\G\s*((?:\+_|\+)?)\s*:/', $index, $name ) ) {
+ $this->forget();
+
+ // at last, we have the complete match now. move forward,
+ // convert name particles to tree objects and return:
+ if ( $name[0] === '' ) {
+ array_shift( $name );
+ array_shift( $index );
+ }
+ foreach ( $name as $k => $s ) {
+ if ( !$s || $s[0] !== '@' ) {
+ $name[$k] = $this->NewObj( 'Less_Tree_Keyword', [ $s ] );
+ } else {
+ $name[$k] = $this->NewObj( 'Less_Tree_Variable', [ '@' . substr( $s, 2, -1 ), $index[$k], $this->env->currentFileInfo ] );
+ }
+ }
+ return $name;
+ } else {
+ $this->restore();
+ }
}
- private function rulePropertyMatch( $re, &$offset, &$length, &$index, &$name ){
- preg_match($re, $this->input, $a, 0, $offset);
- if( $a ){
- $index[] = $this->pos + $length;
- $length += strlen($a[0]);
- $offset += strlen($a[0]);
- $name[] = $a[1];
+ private function rulePropertyMatch( $re, &$index, &$name ) {
+ $i = $this->pos;
+ $chunk = $this->MatchReg( $re );
+ if ( $chunk ) {
+ $index[] = $i;
+ $name[] = $chunk[1];
return true;
}
}
- public static function serializeVars( $vars ){
+ public static function serializeVars( $vars ) {
$s = '';
- foreach($vars as $name => $value){
- $s .= (($name[0] === '@') ? '' : '@') . $name .': '. $value . ((substr($value,-1) === ';') ? '' : ';');
+ foreach ( $vars as $name => $value ) {
+ $s .= ( ( $name[0] === '@' ) ? '' : '@' ) . $name . ': ' . $value . ( ( substr( $value, -1 ) === ';' ) ? '' : ';' );
}
return $s;
}
-
/**
- * Some versions of php have trouble with method_exists($a,$b) if $a is not an object
+ * Some versions of PHP have trouble with method_exists($a,$b) if $a is not an object
*
+ * @param mixed $a
* @param string $b
*/
- public static function is_method($a,$b){
- return is_object($a) && method_exists($a,$b);
+ public static function is_method( $a, $b ) {
+ return is_object( $a ) && method_exists( $a, $b );
}
-
/**
* Round numbers similarly to javascript
* eg: 1.499999 to 1 instead of 2
- *
*/
- public static function round($i, $precision = 0){
+ public static function round( $input, $precision = 0 ) {
+ $precision = pow( 10, $precision );
+ $i = $input * $precision;
- $precision = pow(10,$precision);
- $i = $i*$precision;
-
- $ceil = ceil($i);
- $floor = floor($i);
- if( ($ceil - $i) <= ($i - $floor) ){
- return $ceil/$precision;
- }else{
- return $floor/$precision;
+ $ceil = ceil( $i );
+ $floor = floor( $i );
+ if ( ( $ceil - $i ) <= ( $i - $floor ) ) {
+ return $ceil / $precision;
+ } else {
+ return $floor / $precision;
}
}
-
/**
- * Create Less_Tree_* objects and optionally generate a cache string
+ * Create a new instance of $class with args $args, and optionally generates a cache string.
+ * $class should be a Less_Tree_* class.
*
- * @return mixed
+ * @phan-template TClassName
+ * @phan-param class-string $class
+ * @phan-param array $args
+ * @phan-return TClassName
+ *
+ * @param string $class
+ * @param mixed[] $args
+ * @return Less_Tree Instance of $class subclass created with $args
*/
- public function NewObj0($class){
- $obj = new $class();
- if( $this->CacheEnabled() ){
- $obj->cache_string = ' new '.$class.'()';
+ public function NewObj( $class, $args = [] ) {
+ $obj = new $class( ...$args );
+ if ( $this->CacheEnabled() ) {
+ $argStrings = array_map(
+ [ __CLASS__, 'ArgString' ],
+ $args
+ );
+ $argCache = implode( ',', $argStrings );
+ // @phan-suppress-next-line PhanTypeExpectedObjectPropAccess False positive
+ $obj->cache_string = " new $class($argCache)";
}
return $obj;
}
- public function NewObj1($class, $arg){
- $obj = new $class( $arg );
- if( $this->CacheEnabled() ){
- $obj->cache_string = ' new '.$class.'('.Less_Parser::ArgString($arg).')';
- }
- return $obj;
- }
-
- public function NewObj2($class, $args){
- $obj = new $class( $args[0], $args[1] );
- if( $this->CacheEnabled() ){
- $this->ObjCache( $obj, $class, $args);
- }
- return $obj;
- }
-
- public function NewObj3($class, $args){
- $obj = new $class( $args[0], $args[1], $args[2] );
- if( $this->CacheEnabled() ){
- $this->ObjCache( $obj, $class, $args);
- }
- return $obj;
- }
-
- public function NewObj4($class, $args){
- $obj = new $class( $args[0], $args[1], $args[2], $args[3] );
- if( $this->CacheEnabled() ){
- $this->ObjCache( $obj, $class, $args);
- }
- return $obj;
- }
-
- public function NewObj5($class, $args){
- $obj = new $class( $args[0], $args[1], $args[2], $args[3], $args[4] );
- if( $this->CacheEnabled() ){
- $this->ObjCache( $obj, $class, $args);
- }
- return $obj;
- }
-
- public function NewObj6($class, $args){
- $obj = new $class( $args[0], $args[1], $args[2], $args[3], $args[4], $args[5] );
- if( $this->CacheEnabled() ){
- $this->ObjCache( $obj, $class, $args);
- }
- return $obj;
- }
-
- public function NewObj7($class, $args){
- $obj = new $class( $args[0], $args[1], $args[2], $args[3], $args[4], $args[5], $args[6] );
- if( $this->CacheEnabled() ){
- $this->ObjCache( $obj, $class, $args);
- }
- return $obj;
- }
-
- //caching
- public function ObjCache($obj, $class, $args=array()){
- $obj->cache_string = ' new '.$class.'('. self::ArgCache($args).')';
- }
-
- public function ArgCache($args){
- return implode(',',array_map( array('Less_Parser','ArgString'),$args));
- }
-
-
/**
* Convert an argument to a string for use in the parser cache
*
* @return string
*/
- public static function ArgString($arg){
+ public static function ArgString( $arg ) {
+ $type = gettype( $arg );
- $type = gettype($arg);
-
- if( $type === 'object'){
+ if ( $type === 'object' ) {
$string = $arg->cache_string;
- unset($arg->cache_string);
+ unset( $arg->cache_string );
return $string;
- }elseif( $type === 'array' ){
+ } elseif ( $type === 'array' ) {
$string = ' Array(';
- foreach($arg as $k => $a){
- $string .= var_export($k,true).' => '.self::ArgString($a).',';
+ foreach ( $arg as $k => $a ) {
+ $string .= var_export( $k, true ) . ' => ' . self::ArgString( $a ) . ',';
}
return $string . ')';
}
- return var_export($arg,true);
+ return var_export( $arg, true );
}
- public function Error($msg){
- throw new Less_Exception_Parser($msg, null, $this->furthest, $this->env->currentFileInfo);
+ /** @return never */
+ public function Error( $msg ) {
+ throw new Less_Exception_Parser( $msg, null, $this->furthest, $this->env->currentFileInfo );
}
- public static function WinPath($path){
- return str_replace('\\', '/', $path);
+ public static function WinPath( $path ) {
+ return str_replace( '\\', '/', $path );
}
- public static function AbsPath($path, $winPath = false){
- if (strpos($path, '//') !== false && preg_match('_^(https?:)?//\\w+(\\.\\w+)+/\\w+_i', $path)) {
+ public static function AbsPath( $path, $winPath = false ) {
+ if ( strpos( $path, '//' ) !== false && preg_match( '/^(https?:)?\/\//i', $path ) ) {
return $winPath ? '' : false;
} else {
- $path = realpath($path);
- if ($winPath) {
- $path = self::WinPath($path);
+ $path = realpath( $path );
+ if ( $winPath ) {
+ $path = self::WinPath( $path );
}
return $path;
}
}
- public function CacheEnabled(){
- return (Less_Parser::$options['cache_method'] && (Less_Cache::$cache_dir || (Less_Parser::$options['cache_method'] == 'callback')));
+ public function CacheEnabled() {
+ return ( self::$options['cache_method'] && ( Less_Cache::$cache_dir || ( self::$options['cache_method'] == 'callback' ) ) );
}
}
diff --git a/vendor/wikimedia/less.php/lib/Less/SourceMap/Base64VLQ.php b/vendor/wikimedia/less.php/lib/Less/SourceMap/Base64VLQ.php
index f5b200c35..c27c6ed56 100644
--- a/vendor/wikimedia/less.php/lib/Less/SourceMap/Base64VLQ.php
+++ b/vendor/wikimedia/less.php/lib/Less/SourceMap/Base64VLQ.php
@@ -1,31 +1,29 @@
0, 'B' => 1, 'C' => 2, 'D' => 3, 'E' => 4, 'F' => 5, 'G' => 6,
'H' => 7,'I' => 8, 'J' => 9, 'K' => 10, 'L' => 11, 'M' => 12, 'N' => 13,
'O' => 14, 'P' => 15, 'Q' => 16, 'R' => 17, 'S' => 18, 'T' => 19, 'U' => 20,
@@ -44,14 +42,14 @@ class Less_SourceMap_Base64VLQ {
'q' => 42, 'r' => 43, 's' => 44, 't' => 45, 'u' => 46, 'v' => 47, 'w' => 48,
'x' => 49, 'y' => 50, 'z' => 51, 0 => 52, 1 => 53, 2 => 54, 3 => 55, 4 => 56,
5 => 57, 6 => 58, 7 => 59, 8 => 60, 9 => 61, '+' => 62, '/' => 63,
- );
+ ];
/**
* Integer to char map
*
* @var array
*/
- private $intToCharMap = array(
+ private $intToCharMap = [
0 => 'A', 1 => 'B', 2 => 'C', 3 => 'D', 4 => 'E', 5 => 'F', 6 => 'G',
7 => 'H', 8 => 'I', 9 => 'J', 10 => 'K', 11 => 'L', 12 => 'M', 13 => 'N',
14 => 'O', 15 => 'P', 16 => 'Q', 17 => 'R', 18 => 'S', 19 => 'T', 20 => 'U',
@@ -62,12 +60,12 @@ class Less_SourceMap_Base64VLQ {
49 => 'x', 50 => 'y', 51 => 'z', 52 => '0', 53 => '1', 54 => '2', 55 => '3',
56 => '4', 57 => '5', 58 => '6', 59 => '7', 60 => '8', 61 => '9', 62 => '+',
63 => '/',
- );
+ ];
/**
* Constructor
*/
- public function __construct(){
+ public function __construct() {
// I leave it here for future reference
// foreach(str_split('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/') as $i => $char)
// {
@@ -83,10 +81,10 @@ class Less_SourceMap_Base64VLQ {
* 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
* We generate the value for 32 bit machines, hence -2147483648 becomes 1, not 4294967297,
* even on a 64 bit machine.
- * @param string $aValue
+ * @param int $aValue
*/
- public function toVLQSigned($aValue){
- return 0xffffffff & ($aValue < 0 ? ((-$aValue) << 1) + 1 : ($aValue << 1) + 0);
+ public function toVLQSigned( $aValue ) {
+ return 0xffffffff & ( $aValue < 0 ? ( ( -$aValue ) << 1 ) + 1 : ( $aValue << 1 ) + 0 );
}
/**
@@ -98,30 +96,30 @@ class Less_SourceMap_Base64VLQ {
* Hence
* 1 becomes -2147483648
* even on a 64 bit machine.
- * @param integer $aValue
+ * @param int $aValue
*/
- public function fromVLQSigned($aValue){
- return $aValue & 1 ? $this->zeroFill(~$aValue + 2, 1) | (-1 - 0x7fffffff) : $this->zeroFill($aValue, 1);
+ public function fromVLQSigned( $aValue ) {
+ return $aValue & 1 ? $this->zeroFill( ~$aValue + 2, 1 ) | ( -1 - 0x7fffffff ) : $this->zeroFill( $aValue, 1 );
}
/**
* Return the base 64 VLQ encoded value.
*
- * @param string $aValue The value to encode
+ * @param int $aValue The value to encode
* @return string The encoded value
*/
- public function encode($aValue){
+ public function encode( $aValue ) {
$encoded = '';
- $vlq = $this->toVLQSigned($aValue);
+ $vlq = $this->toVLQSigned( $aValue );
do
{
$digit = $vlq & $this->mask;
- $vlq = $this->zeroFill($vlq, $this->shift);
- if($vlq > 0){
+ $vlq = $this->zeroFill( $vlq, $this->shift );
+ if ( $vlq > 0 ) {
$digit |= $this->continuationBit;
}
- $encoded .= $this->base64Encode($digit);
- } while($vlq > 0);
+ $encoded .= $this->base64Encode( $digit );
+ } while ( $vlq > 0 );
return $encoded;
}
@@ -130,42 +128,42 @@ class Less_SourceMap_Base64VLQ {
* Return the value decoded from base 64 VLQ.
*
* @param string $encoded The encoded value to decode
- * @return integer The decoded value
+ * @return int The decoded value
*/
- public function decode($encoded){
+ public function decode( $encoded ) {
$vlq = 0;
$i = 0;
do
{
- $digit = $this->base64Decode($encoded[$i]);
- $vlq |= ($digit & $this->mask) << ($i * $this->shift);
+ $digit = $this->base64Decode( $encoded[$i] );
+ $vlq |= ( $digit & $this->mask ) << ( $i * $this->shift );
$i++;
- } while($digit & $this->continuationBit);
+ } while ( $digit & $this->continuationBit );
- return $this->fromVLQSigned($vlq);
+ return $this->fromVLQSigned( $vlq );
}
/**
* Right shift with zero fill.
*
- * @param integer $a number to shift
- * @param integer $b number of bits to shift
- * @return integer
+ * @param int $a number to shift
+ * @param int $b number of bits to shift
+ * @return int
*/
- public function zeroFill($a, $b){
- return ($a >= 0) ? ($a >> $b) : ($a >> $b) & (PHP_INT_MAX >> ($b - 1));
+ public function zeroFill( $a, $b ) {
+ return ( $a >= 0 ) ? ( $a >> $b ) : ( $a >> $b ) & ( PHP_INT_MAX >> ( $b - 1 ) );
}
/**
* Encode single 6-bit digit as base64.
*
- * @param integer $number
+ * @param int $number
* @return string
* @throws Exception If the number is invalid
*/
- public function base64Encode($number){
- if($number < 0 || $number > 63){
- throw new Exception(sprintf('Invalid number "%s" given. Must be between 0 and 63.', $number));
+ public function base64Encode( $number ) {
+ if ( $number < 0 || $number > 63 ) {
+ throw new Exception( sprintf( 'Invalid number "%s" given. Must be between 0 and 63.', (string)$number ) );
}
return $this->intToCharMap[$number];
}
@@ -174,12 +172,12 @@ class Less_SourceMap_Base64VLQ {
* Decode single 6-bit digit from base64
*
* @param string $char
- * @return number
+ * @return int
* @throws Exception If the number is invalid
*/
- public function base64Decode($char){
- if(!array_key_exists($char, $this->charToIntMap)){
- throw new Exception(sprintf('Invalid base 64 digit "%s" given.', $char));
+ public function base64Decode( $char ) {
+ if ( !array_key_exists( $char, $this->charToIntMap ) ) {
+ throw new Exception( sprintf( 'Invalid base 64 digit "%s" given.', $char ) );
}
return $this->charToIntMap[$char];
}
diff --git a/vendor/wikimedia/less.php/lib/Less/SourceMap/Generator.php b/vendor/wikimedia/less.php/lib/Less/SourceMap/Generator.php
index 9509aea71..7da960991 100644
--- a/vendor/wikimedia/less.php/lib/Less/SourceMap/Generator.php
+++ b/vendor/wikimedia/less.php/lib/Less/SourceMap/Generator.php
@@ -1,24 +1,22 @@
''
- );
+ ];
/**
* The base64 VLQ encoder
@@ -55,7 +53,7 @@ class Less_SourceMap_Generator extends Less_Configurable {
*
* @var array
*/
- protected $mappings = array();
+ protected $mappings = [];
/**
* The root node
@@ -69,31 +67,32 @@ class Less_SourceMap_Generator extends Less_Configurable {
*
* @var array
*/
- protected $contentsMap = array();
+ protected $contentsMap = [];
/**
* File to content map
*
* @var array
*/
- protected $sources = array();
- protected $source_keys = array();
+ protected $sources = [];
+ protected $source_keys = [];
/**
* Constructor
*
* @param Less_Tree_Ruleset $root The root node
+ * @param array $contentsMap
* @param array $options Array of options
*/
- public function __construct(Less_Tree_Ruleset $root, $contentsMap, $options = array()){
+ public function __construct( Less_Tree_Ruleset $root, $contentsMap, $options = [] ) {
$this->root = $root;
$this->contentsMap = $contentsMap;
$this->encoder = new Less_SourceMap_Base64VLQ();
- $this->SetOptions($options);
-
- $this->options['sourceMapRootpath'] = $this->fixWindowsPath($this->options['sourceMapRootpath'], true);
- $this->options['sourceMapBasepath'] = $this->fixWindowsPath($this->options['sourceMapBasepath'], true);
+ $this->SetOptions( $options );
+
+ $this->options['sourceMapRootpath'] = $this->fixWindowsPath( $this->options['sourceMapRootpath'], true );
+ $this->options['sourceMapBasepath'] = $this->fixWindowsPath( $this->options['sourceMapBasepath'], true );
}
/**
@@ -101,34 +100,33 @@ class Less_SourceMap_Generator extends Less_Configurable {
*
* @return string
*/
- public function generateCSS(){
- $output = new Less_Output_Mapped($this->contentsMap, $this);
+ public function generateCSS() {
+ $output = new Less_Output_Mapped( $this->contentsMap, $this );
// catch the output
- $this->root->genCSS($output);
+ $this->root->genCSS( $output );
-
- $sourceMapUrl = $this->getOption('sourceMapURL');
- $sourceMapFilename = $this->getOption('sourceMapFilename');
+ $sourceMapUrl = $this->getOption( 'sourceMapURL' );
+ $sourceMapFilename = $this->getOption( 'sourceMapFilename' );
$sourceMapContent = $this->generateJson();
- $sourceMapWriteTo = $this->getOption('sourceMapWriteTo');
+ $sourceMapWriteTo = $this->getOption( 'sourceMapWriteTo' );
- if( !$sourceMapUrl && $sourceMapFilename ){
- $sourceMapUrl = $this->normalizeFilename($sourceMapFilename);
+ if ( !$sourceMapUrl && $sourceMapFilename ) {
+ $sourceMapUrl = $this->normalizeFilename( $sourceMapFilename );
}
// write map to a file
- if( $sourceMapWriteTo ){
- $this->saveMap($sourceMapWriteTo, $sourceMapContent);
+ if ( $sourceMapWriteTo ) {
+ $this->saveMap( $sourceMapWriteTo, $sourceMapContent );
}
// inline the map
- if( !$sourceMapUrl ){
- $sourceMapUrl = sprintf('data:application/json,%s', Less_Functions::encodeURIComponent($sourceMapContent));
+ if ( !$sourceMapUrl ) {
+ $sourceMapUrl = sprintf( 'data:application/json,%s', Less_Functions::encodeURIComponent( $sourceMapContent ) );
}
- if( $sourceMapUrl ){
- $output->add( sprintf('/*# sourceMappingURL=%s */', $sourceMapUrl) );
+ if ( $sourceMapUrl ) {
+ $output->add( sprintf( '/*# sourceMappingURL=%s */', $sourceMapUrl ) );
}
return $output->toString();
@@ -141,16 +139,16 @@ class Less_SourceMap_Generator extends Less_Configurable {
* @param string $content The content to write
* @throws Exception If the file could not be saved
*/
- protected function saveMap($file, $content){
- $dir = dirname($file);
+ protected function saveMap( $file, $content ) {
+ $dir = dirname( $file );
// directory does not exist
- if( !is_dir($dir) ){
+ if ( !is_dir( $dir ) ) {
// FIXME: create the dir automatically?
- throw new Exception(sprintf('The directory "%s" does not exist. Cannot save the source map.', $dir));
+ throw new Exception( sprintf( 'The directory "%s" does not exist. Cannot save the source map.', $dir ) );
}
// FIXME: proper saving, with dir write check!
- if(file_put_contents($file, $content) === false){
- throw new Exception(sprintf('Cannot save the source map to "%s"', $file));
+ if ( file_put_contents( $file, $content ) === false ) {
+ throw new Exception( sprintf( 'Cannot save the source map to "%s"', $file ) );
}
return true;
}
@@ -161,21 +159,20 @@ class Less_SourceMap_Generator extends Less_Configurable {
* @param string $filename
* @return string
*/
- protected function normalizeFilename($filename){
+ protected function normalizeFilename( $filename ) {
+ $filename = $this->fixWindowsPath( $filename );
- $filename = $this->fixWindowsPath($filename);
-
- $rootpath = $this->getOption('sourceMapRootpath');
- $basePath = $this->getOption('sourceMapBasepath');
+ $rootpath = $this->getOption( 'sourceMapRootpath' );
+ $basePath = $this->getOption( 'sourceMapBasepath' );
// "Trim" the 'sourceMapBasepath' from the output filename.
- if (is_string($basePath) && strpos($filename, $basePath) === 0) {
- $filename = substr($filename, strlen($basePath));
+ if ( is_string( $basePath ) && strpos( $filename, $basePath ) === 0 ) {
+ $filename = substr( $filename, strlen( $basePath ) );
}
// Remove extra leading path separators.
- if(strpos($filename, '\\') === 0 || strpos($filename, '/') === 0){
- $filename = substr($filename, 1);
+ if ( strpos( $filename, '\\' ) === 0 || strpos( $filename, '/' ) === 0 ) {
+ $filename = substr( $filename, 1 );
}
return $rootpath . $filename;
@@ -184,69 +181,62 @@ class Less_SourceMap_Generator extends Less_Configurable {
/**
* Adds a mapping
*
- * @param integer $generatedLine The line number in generated file
- * @param integer $generatedColumn The column number in generated file
- * @param integer $originalLine The line number in original file
- * @param integer $originalColumn The column number in original file
- * @param string $sourceFile The original source file
+ * @param int $generatedLine The line number in generated file
+ * @param int $generatedColumn The column number in generated file
+ * @param int $originalLine The line number in original file
+ * @param int $originalColumn The column number in original file
+ * @param array $fileInfo The original source file
*/
- public function addMapping($generatedLine, $generatedColumn, $originalLine, $originalColumn, $fileInfo ){
-
- $this->mappings[] = array(
+ public function addMapping( $generatedLine, $generatedColumn, $originalLine, $originalColumn, $fileInfo ) {
+ $this->mappings[] = [
'generated_line' => $generatedLine,
'generated_column' => $generatedColumn,
'original_line' => $originalLine,
'original_column' => $originalColumn,
'source_file' => $fileInfo['currentUri']
- );
+ ];
$this->sources[$fileInfo['currentUri']] = $fileInfo['filename'];
}
-
/**
* Generates the JSON source map
*
* @return string
* @see https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#
*/
- protected function generateJson(){
-
- $sourceMap = array();
+ protected function generateJson() {
+ $sourceMap = [];
$mappings = $this->generateMappings();
// File version (always the first entry in the object) and must be a positive integer.
$sourceMap['version'] = self::VERSION;
-
// An optional name of the generated code that this source map is associated with.
- $file = $this->getOption('sourceMapFilename');
- if( $file ){
+ $file = $this->getOption( 'sourceMapFilename' );
+ if ( $file ) {
$sourceMap['file'] = $file;
}
-
// An optional source root, useful for relocating source files on a server or removing repeated values in the 'sources' entry. This value is prepended to the individual entries in the 'source' field.
- $root = $this->getOption('sourceRoot');
- if( $root ){
+ $root = $this->getOption( 'sourceRoot' );
+ if ( $root ) {
$sourceMap['sourceRoot'] = $root;
}
-
// A list of original sources used by the 'mappings' entry.
- $sourceMap['sources'] = array();
- foreach($this->sources as $source_uri => $source_filename){
- $sourceMap['sources'][] = $this->normalizeFilename($source_filename);
+ $sourceMap['sources'] = [];
+ foreach ( $this->sources as $source_uri => $source_filename ) {
+ $sourceMap['sources'][] = $this->normalizeFilename( $source_filename );
}
-
// A list of symbol names used by the 'mappings' entry.
- $sourceMap['names'] = array();
+ $sourceMap['names'] = [];
// A string with the encoded mapping data.
$sourceMap['mappings'] = $mappings;
- if( $this->getOption('outputSourceFiles') ){
+ if ( $this->getOption( 'outputSourceFiles' ) ) {
// An optional list of source content, useful when the 'source' can't be hosted.
// The contents are listed in the same order as the sources above.
// 'null' may be used if some original sources should be retrieved by name.
@@ -254,11 +244,11 @@ class Less_SourceMap_Generator extends Less_Configurable {
}
// less.js compat fixes
- if( count($sourceMap['sources']) && empty($sourceMap['sourceRoot']) ){
- unset($sourceMap['sourceRoot']);
+ if ( count( $sourceMap['sources'] ) && empty( $sourceMap['sourceRoot'] ) ) {
+ unset( $sourceMap['sourceRoot'] );
}
- return json_encode($sourceMap);
+ return json_encode( $sourceMap );
}
/**
@@ -266,13 +256,13 @@ class Less_SourceMap_Generator extends Less_Configurable {
*
* @return array|null
*/
- protected function getSourcesContent(){
- if(empty($this->sources)){
+ protected function getSourcesContent() {
+ if ( empty( $this->sources ) ) {
return;
}
- $content = array();
- foreach($this->sources as $sourceFile){
- $content[] = file_get_contents($sourceFile);
+ $content = [];
+ foreach ( $this->sources as $sourceFile ) {
+ $content[] = file_get_contents( $sourceFile );
}
return $content;
}
@@ -282,48 +272,46 @@ class Less_SourceMap_Generator extends Less_Configurable {
*
* @return string
*/
- public function generateMappings(){
-
- if( !count($this->mappings) ){
+ public function generateMappings() {
+ if ( !count( $this->mappings ) ) {
return '';
}
- $this->source_keys = array_flip(array_keys($this->sources));
-
+ $this->source_keys = array_flip( array_keys( $this->sources ) );
// group mappings by generated line number.
- $groupedMap = $groupedMapEncoded = array();
- foreach($this->mappings as $m){
+ $groupedMap = $groupedMapEncoded = [];
+ foreach ( $this->mappings as $m ) {
$groupedMap[$m['generated_line']][] = $m;
}
- ksort($groupedMap);
+ ksort( $groupedMap );
$lastGeneratedLine = $lastOriginalIndex = $lastOriginalLine = $lastOriginalColumn = 0;
- foreach($groupedMap as $lineNumber => $line_map){
- while(++$lastGeneratedLine < $lineNumber){
+ foreach ( $groupedMap as $lineNumber => $line_map ) {
+ while ( ++$lastGeneratedLine < $lineNumber ) {
$groupedMapEncoded[] = ';';
}
- $lineMapEncoded = array();
+ $lineMapEncoded = [];
$lastGeneratedColumn = 0;
- foreach($line_map as $m){
- $mapEncoded = $this->encoder->encode($m['generated_column'] - $lastGeneratedColumn);
+ foreach ( $line_map as $m ) {
+ $mapEncoded = $this->encoder->encode( $m['generated_column'] - $lastGeneratedColumn );
$lastGeneratedColumn = $m['generated_column'];
// find the index
- if( $m['source_file'] ){
- $index = $this->findFileIndex($m['source_file']);
- if( $index !== false ){
- $mapEncoded .= $this->encoder->encode($index - $lastOriginalIndex);
+ if ( $m['source_file'] ) {
+ $index = $this->findFileIndex( $m['source_file'] );
+ if ( $index !== false ) {
+ $mapEncoded .= $this->encoder->encode( $index - $lastOriginalIndex );
$lastOriginalIndex = $index;
// lines are stored 0-based in SourceMap spec version 3
- $mapEncoded .= $this->encoder->encode($m['original_line'] - 1 - $lastOriginalLine);
+ $mapEncoded .= $this->encoder->encode( $m['original_line'] - 1 - $lastOriginalLine );
$lastOriginalLine = $m['original_line'] - 1;
- $mapEncoded .= $this->encoder->encode($m['original_column'] - $lastOriginalColumn);
+ $mapEncoded .= $this->encoder->encode( $m['original_column'] - $lastOriginalColumn );
$lastOriginalColumn = $m['original_column'];
}
}
@@ -331,32 +319,33 @@ class Less_SourceMap_Generator extends Less_Configurable {
$lineMapEncoded[] = $mapEncoded;
}
- $groupedMapEncoded[] = implode(',', $lineMapEncoded) . ';';
+ $groupedMapEncoded[] = implode( ',', $lineMapEncoded ) . ';';
}
- return rtrim(implode($groupedMapEncoded), ';');
+ return rtrim( implode( $groupedMapEncoded ), ';' );
}
/**
* Finds the index for the filename
*
* @param string $filename
- * @return integer|false
+ * @return int|false
*/
- protected function findFileIndex($filename){
+ protected function findFileIndex( $filename ) {
return $this->source_keys[$filename];
}
/**
* fix windows paths
- * @param string $path
- * @return string
+ * @param string $path
+ * @param bool $addEndSlash
+ * @return string
*/
- public function fixWindowsPath($path, $addEndSlash = false){
- $slash = ($addEndSlash) ? '/' : '';
- if( !empty($path) ){
- $path = str_replace('\\', '/', $path);
- $path = rtrim($path,'/') . $slash;
+ public function fixWindowsPath( $path, $addEndSlash = false ) {
+ $slash = ( $addEndSlash ) ? '/' : '';
+ if ( !empty( $path ) ) {
+ $path = str_replace( '\\', '/', $path );
+ $path = rtrim( $path, '/' ) . $slash;
}
return $path;
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree.php b/vendor/wikimedia/less.php/lib/Less/Tree.php
index 6fb104bc7..f606b5879 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree.php
@@ -3,42 +3,50 @@
/**
* Tree
*
- * @package Less
- * @subpackage tree
+ * TODO: Callers often use `property_exists(, 'value')` to distinguish
+ * tree nodes that are considerd value-holding. Refactor this to move
+ * the 'value' property that most subclasses implement to there, and use
+ * something else (special value, method, or intermediate class?) to
+ * signal whether a subclass is considered value-holding.
*/
-class Less_Tree{
+class Less_Tree {
public $cache_string;
+ public $parensInOp = false;
+ public $extendOnEveryPath;
+ public $allExtends;
- public function toCSS(){
+ public function toCSS() {
$output = new Less_Output();
- $this->genCSS($output);
+ $this->genCSS( $output );
return $output->toString();
}
+ /**
+ * Generate CSS by adding it to the output object
+ *
+ * @param Less_Output $output The output
+ * @return void
+ */
+ public function genCSS( $output ) {
+ }
- /**
- * Generate CSS by adding it to the output object
- *
- * @param Less_Output $output The output
- * @return void
- */
- public function genCSS($output){}
-
+ public function compile( $env ) {
+ return $this;
+ }
/**
+ * @param Less_Output $output
* @param Less_Tree_Ruleset[] $rules
*/
- public static function outputRuleset( $output, $rules ){
-
- $ruleCnt = count($rules);
+ public static function outputRuleset( $output, $rules ) {
+ $ruleCnt = count( $rules );
Less_Environment::$tabLevel++;
-
// Compressed
- if( Less_Parser::$options['compress'] ){
- $output->add('{');
- for( $i = 0; $i < $ruleCnt; $i++ ){
+ if ( Less_Parser::$options['compress'] ) {
+ $output->add( '{' );
+ for ( $i = 0; $i < $ruleCnt; $i++ ) {
$rules[$i]->genCSS( $output );
}
@@ -47,41 +55,38 @@ class Less_Tree{
return;
}
-
// Non-compressed
- $tabSetStr = "\n".str_repeat( Less_Parser::$options['indentation'] , Less_Environment::$tabLevel-1 );
- $tabRuleStr = $tabSetStr.Less_Parser::$options['indentation'];
+ $tabSetStr = "\n" . str_repeat( Less_Parser::$options['indentation'], Less_Environment::$tabLevel - 1 );
+ $tabRuleStr = $tabSetStr . Less_Parser::$options['indentation'];
$output->add( " {" );
- for($i = 0; $i < $ruleCnt; $i++ ){
+ for ( $i = 0; $i < $ruleCnt; $i++ ) {
$output->add( $tabRuleStr );
$rules[$i]->genCSS( $output );
}
Less_Environment::$tabLevel--;
- $output->add( $tabSetStr.'}' );
-
+ $output->add( $tabSetStr . '}' );
}
- public function accept($visitor){}
+ public function accept( $visitor ) {
+ }
-
- public static function ReferencedArray($rules){
- foreach($rules as $rule){
- if( method_exists($rule, 'markReferenced') ){
+ public static function ReferencedArray( $rules ) {
+ foreach ( $rules as $rule ) {
+ if ( method_exists( $rule, 'markReferenced' ) ) {
+ // @phan-suppress-next-line PhanUndeclaredMethod
$rule->markReferenced();
}
}
}
-
/**
* Requires php 5.3+
*/
- public static function __set_state($args){
-
+ public static function __set_state( $args ) {
$class = get_called_class();
- $obj = new $class(null,null,null,null);
- foreach($args as $key => $val){
+ $obj = new $class( null, null, null, null );
+ foreach ( $args as $key => $val ) {
$obj->$key = $val;
}
return $obj;
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Alpha.php b/vendor/wikimedia/less.php/lib/Less/Tree/Alpha.php
index 935377da3..bdf5dee75 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Alpha.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Alpha.php
@@ -1,51 +1,44 @@
value = $val;
}
- //function accept( $visitor ){
+ // function accept( $visitor ){
// $this->value = $visitor->visit( $this->value );
//}
- public function compile($env){
-
- if( is_object($this->value) ){
- $this->value = $this->value->compile($env);
+ public function compile( $env ) {
+ if ( is_object( $this->value ) ) {
+ $this->value = $this->value->compile( $env );
}
return $this;
}
- /**
- * @see Less_Tree::genCSS
- */
- public function genCSS( $output ){
-
+ /**
+ * @see Less_Tree::genCSS
+ */
+ public function genCSS( $output ) {
$output->add( "alpha(opacity=" );
- if( is_string($this->value) ){
+ if ( is_string( $this->value ) ) {
$output->add( $this->value );
- }else{
- $this->value->genCSS( $output);
+ } else {
+ $this->value->genCSS( $output );
}
$output->add( ')' );
}
- public function toCSS(){
- return "alpha(opacity=" . (is_string($this->value) ? $this->value : $this->value->toCSS()) . ")";
+ public function toCSS() {
+ return "alpha(opacity=" . ( is_string( $this->value ) ? $this->value : $this->value->toCSS() ) . ")";
}
-
-}
\ No newline at end of file
+}
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Anonymous.php b/vendor/wikimedia/less.php/lib/Less/Tree/Anonymous.php
index 8889dc0f3..6d588e9ec 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Anonymous.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Anonymous.php
@@ -1,12 +1,8 @@
value = $value;
$this->index = $index;
$this->mapLines = $mapLines;
$this->currentFileInfo = $currentFileInfo;
}
- public function compile(){
- return new Less_Tree_Anonymous($this->value, $this->index, $this->currentFileInfo, $this->mapLines);
+ public function compile( $env ) {
+ return new Less_Tree_Anonymous( $this->value, $this->index, $this->currentFileInfo, $this->mapLines );
}
- public function compare($x){
- if( !is_object($x) ){
+ public function compare( $x ) {
+ if ( !is_object( $x ) ) {
return -1;
}
$left = $this->toCSS();
$right = $x->toCSS();
- if( $left === $right ){
+ if ( $left === $right ) {
return 0;
}
return $left < $right ? -1 : 1;
}
- /**
- * @see Less_Tree::genCSS
- */
- public function genCSS( $output ){
+ /**
+ * @see Less_Tree::genCSS
+ */
+ public function genCSS( $output ) {
$output->add( $this->value, $this->currentFileInfo, $this->index, $this->mapLines );
}
- public function toCSS(){
+ public function toCSS() {
return $this->value;
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Assignment.php b/vendor/wikimedia/less.php/lib/Less/Tree/Assignment.php
index 238000647..1f939a11f 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Assignment.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Assignment.php
@@ -1,39 +1,35 @@
key = $key;
$this->value = $val;
}
- public function accept( $visitor ){
+ public function accept( $visitor ) {
$this->value = $visitor->visitObj( $this->value );
}
- public function compile($env) {
- return new Less_Tree_Assignment( $this->key, $this->value->compile($env));
+ public function compile( $env ) {
+ return new Less_Tree_Assignment( $this->key, $this->value->compile( $env ) );
}
- /**
- * @see Less_Tree::genCSS
- */
- public function genCSS( $output ){
+ /**
+ * @see Less_Tree::genCSS
+ */
+ public function genCSS( $output ) {
$output->add( $this->key . '=' );
$this->value->genCSS( $output );
}
- public function toCss(){
+ public function toCss() {
return $this->key . '=' . $this->value->toCSS();
}
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Attribute.php b/vendor/wikimedia/less.php/lib/Less/Tree/Attribute.php
index 32b8900d8..dd365959f 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Attribute.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Attribute.php
@@ -1,54 +1,49 @@
key = $key;
$this->op = $op;
$this->value = $value;
}
- public function compile($env){
+ public function compile( $env ) {
+ $key_obj = is_object( $this->key );
+ $val_obj = is_object( $this->value );
- $key_obj = is_object($this->key);
- $val_obj = is_object($this->value);
-
- if( !$key_obj && !$val_obj ){
+ if ( !$key_obj && !$val_obj ) {
return $this;
}
return new Less_Tree_Attribute(
- $key_obj ? $this->key->compile($env) : $this->key ,
+ $key_obj ? $this->key->compile( $env ) : $this->key,
$this->op,
- $val_obj ? $this->value->compile($env) : $this->value);
+ $val_obj ? $this->value->compile( $env ) : $this->value );
}
- /**
- * @see Less_Tree::genCSS
- */
- public function genCSS( $output ){
+ /**
+ * @see Less_Tree::genCSS
+ */
+ public function genCSS( $output ) {
$output->add( $this->toCSS() );
}
- public function toCSS(){
+ public function toCSS() {
$value = $this->key;
- if( $this->op ){
+ if ( $this->op ) {
$value .= $this->op;
- $value .= (is_object($this->value) ? $this->value->toCSS() : $this->value);
+ $value .= ( is_object( $this->value ) ? $this->value->toCSS() : $this->value );
}
return '[' . $value . ']';
}
-}
\ No newline at end of file
+}
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Call.php b/vendor/wikimedia/less.php/lib/Less/Tree/Call.php
index 3c3382d10..28a3a192e 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Call.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Call.php
@@ -1,111 +1,107 @@
name = $name;
$this->args = $args;
$this->index = $index;
$this->currentFileInfo = $currentFileInfo;
}
- public function accept( $visitor ){
+ public function accept( $visitor ) {
$this->args = $visitor->visitArray( $this->args );
}
- //
- // When evaluating a function call,
- // we either find the function in `tree.functions` [1],
- // in which case we call it, passing the evaluated arguments,
- // or we simply print it out as it appeared originally [2].
- //
- // The *functions.js* file contains the built-in functions.
- //
- // The reason why we evaluate the arguments, is in the case where
- // we try to pass a variable to a function, like: `saturate(@color)`.
- // The function should receive the value, not the variable.
- //
- public function compile($env=null){
- $args = array();
- foreach($this->args as $a){
- $args[] = $a->compile($env);
+ //
+ // When evaluating a function call,
+ // we either find the function in `tree.functions` [1],
+ // in which case we call it, passing the evaluated arguments,
+ // or we simply print it out as it appeared originally [2].
+ //
+ // The *functions.js* file contains the built-in functions.
+ //
+ // The reason why we evaluate the arguments, is in the case where
+ // we try to pass a variable to a function, like: `saturate(@color)`.
+ // The function should receive the value, not the variable.
+ //
+ public function compile( $env = null ) {
+ $args = [];
+ foreach ( $this->args as $a ) {
+ $args[] = $a->compile( $env );
}
- $nameLC = strtolower($this->name);
- switch($nameLC){
+ $nameLC = strtolower( $this->name );
+ switch ( $nameLC ) {
case '%':
$nameLC = '_percent';
- break;
+ break;
case 'get-unit':
$nameLC = 'getunit';
- break;
+ break;
case 'data-uri':
$nameLC = 'datauri';
- break;
+ break;
case 'svg-gradient':
$nameLC = 'svggradient';
- break;
+ break;
}
$result = null;
- if( $nameLC === 'default' ){
+ if ( $nameLC === 'default' ) {
$result = Less_Tree_DefaultFunc::compile();
-
- }else{
-
- if( method_exists('Less_Functions',$nameLC) ){ // 1.
+ } else {
+ $func = null;
+ if ( method_exists( 'Less_Functions', $nameLC ) ) {
+ $functions = new Less_Functions( $env, $this->currentFileInfo );
+ $func = [ $functions, $nameLC ];
+ } elseif ( isset( $env->functions[$nameLC] ) && is_callable( $env->functions[$nameLC] ) ) {
+ $func = $env->functions[$nameLC];
+ }
+ // If the function name isn't known to LESS, output it unchanged as CSS.
+ if ( $func ) {
try {
-
- $func = new Less_Functions($env, $this->currentFileInfo);
- $result = call_user_func_array( array($func,$nameLC),$args);
-
- } catch (Exception $e) {
- throw new Less_Exception_Compiler('error evaluating function `' . $this->name . '` '.$e->getMessage().' index: '. $this->index);
- }
- } elseif( isset( $env->functions[$nameLC] ) && is_callable( $env->functions[$nameLC] ) ) {
- try {
- $result = call_user_func_array( $env->functions[$nameLC], $args );
- } catch (Exception $e) {
- throw new Less_Exception_Compiler('error evaluating function `' . $this->name . '` '.$e->getMessage().' index: '. $this->index);
+ $result = call_user_func_array( $func, $args );
+ } catch ( Exception $e ) {
+ // Preserve original trace, especially from custom functions.
+ // https://github.com/wikimedia/less.php/issues/38
+ throw new Less_Exception_Compiler(
+ 'error evaluating function `' . $this->name . '` ' . $e->getMessage()
+ . ' index: ' . $this->index,
+ $e
+ );
}
}
}
- if( $result !== null ){
+ if ( $result !== null ) {
return $result;
}
-
return new Less_Tree_Call( $this->name, $args, $this->index, $this->currentFileInfo );
- }
-
- /**
- * @see Less_Tree::genCSS
- */
- public function genCSS( $output ){
+ }
+ /**
+ * @see Less_Tree::genCSS
+ */
+ public function genCSS( $output ) {
$output->add( $this->name . '(', $this->currentFileInfo, $this->index );
- $args_len = count($this->args);
- for($i = 0; $i < $args_len; $i++ ){
+ $args_len = count( $this->args );
+ for ( $i = 0; $i < $args_len; $i++ ) {
$this->args[$i]->genCSS( $output );
- if( $i + 1 < $args_len ){
+ if ( $i + 1 < $args_len ) {
$output->add( ', ' );
}
}
@@ -113,9 +109,8 @@ class Less_Tree_Call extends Less_Tree{
$output->add( ')' );
}
-
- //public function toCSS(){
- // return $this->compile()->toCSS();
- //}
+ // public function toCSS(){
+ // return $this->compile()->toCSS();
+ //}
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Color.php b/vendor/wikimedia/less.php/lib/Less/Tree/Color.php
index 77af07a6e..427f47dc4 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Color.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Color.php
@@ -1,53 +1,44 @@
rgb = $rgb;
$this->alpha = $a;
$this->isTransparentKeyword = true;
return;
}
- $this->rgb = array();
- if( is_array($rgb) ){
+ $this->rgb = [];
+ if ( is_array( $rgb ) ) {
$this->rgb = $rgb;
- }else if( strlen($rgb) == 6 ){
- foreach(str_split($rgb, 2) as $c){
- $this->rgb[] = hexdec($c);
+ } elseif ( strlen( $rgb ) == 6 ) {
+ foreach ( str_split( $rgb, 2 ) as $c ) {
+ $this->rgb[] = hexdec( $c );
}
- }else{
- foreach(str_split($rgb, 1) as $c){
- $this->rgb[] = hexdec($c.$c);
+ } else {
+ foreach ( str_split( $rgb, 1 ) as $c ) {
+ $this->rgb[] = hexdec( $c . $c );
}
}
- $this->alpha = is_numeric($a) ? $a : 1;
+ $this->alpha = is_numeric( $a ) ? $a : 1;
}
- public function compile(){
- return $this;
- }
-
- public function luma(){
+ public function luma() {
$r = $this->rgb[0] / 255;
$g = $this->rgb[1] / 255;
$b = $this->rgb[2] / 255;
- $r = ($r <= 0.03928) ? $r / 12.92 : pow((($r + 0.055) / 1.055), 2.4);
- $g = ($g <= 0.03928) ? $g / 12.92 : pow((($g + 0.055) / 1.055), 2.4);
- $b = ($b <= 0.03928) ? $b / 12.92 : pow((($b + 0.055) / 1.055), 2.4);
+ $r = ( $r <= 0.03928 ) ? $r / 12.92 : pow( ( ( $r + 0.055 ) / 1.055 ), 2.4 );
+ $g = ( $g <= 0.03928 ) ? $g / 12.92 : pow( ( ( $g + 0.055 ) / 1.055 ), 2.4 );
+ $b = ( $b <= 0.03928 ) ? $b / 12.92 : pow( ( ( $b + 0.055 ) / 1.055 ), 2.4 );
return 0.2126 * $r + 0.7152 * $g + 0.0722 * $b;
}
@@ -55,43 +46,42 @@ class Less_Tree_Color extends Less_Tree{
/**
* @see Less_Tree::genCSS
*/
- public function genCSS( $output ){
+ public function genCSS( $output ) {
$output->add( $this->toCSS() );
}
- public function toCSS( $doNotCompress = false ){
+ public function toCSS( $doNotCompress = false ) {
$compress = Less_Parser::$options['compress'] && !$doNotCompress;
$alpha = Less_Functions::fround( $this->alpha );
-
//
// If we have some transparency, the only way to represent it
// is via `rgba`. Otherwise, we use the hex representation,
// which has better compatibility with older browsers.
// Values are capped between `0` and `255`, rounded and zero-padded.
//
- if( $alpha < 1 ){
- if( ( $alpha === 0 || $alpha === 0.0 ) && isset($this->isTransparentKeyword) && $this->isTransparentKeyword ){
+ if ( $alpha < 1 ) {
+ if ( ( $alpha === 0 || $alpha === 0.0 ) && isset( $this->isTransparentKeyword ) && $this->isTransparentKeyword ) {
return 'transparent';
}
- $values = array();
- foreach($this->rgb as $c){
- $values[] = Less_Functions::clamp( round($c), 255);
+ $values = [];
+ foreach ( $this->rgb as $c ) {
+ $values[] = Less_Functions::clamp( round( $c ), 255 );
}
$values[] = $alpha;
- $glue = ($compress ? ',' : ', ');
- return "rgba(" . implode($glue, $values) . ")";
- }else{
+ $glue = ( $compress ? ',' : ', ' );
+ return "rgba(" . implode( $glue, $values ) . ")";
+ } else {
$color = $this->toRGB();
- if( $compress ){
+ if ( $compress ) {
// Convert color to short format
- if( $color[1] === $color[2] && $color[3] === $color[4] && $color[5] === $color[6]) {
- $color = '#'.$color[1] . $color[3] . $color[5];
+ if ( $color[1] === $color[2] && $color[3] === $color[4] && $color[5] === $color[6] ) {
+ $color = '#' . $color[1] . $color[3] . $color[5];
}
}
@@ -109,121 +99,129 @@ class Less_Tree_Color extends Less_Tree{
/**
* @param string $op
*/
- public function operate( $op, $other) {
- $rgb = array();
- $alpha = $this->alpha * (1 - $other->alpha) + $other->alpha;
- for ($c = 0; $c < 3; $c++) {
- $rgb[$c] = Less_Functions::operate( $op, $this->rgb[$c], $other->rgb[$c]);
+ public function operate( $op, $other ) {
+ $rgb = [];
+ $alpha = $this->alpha * ( 1 - $other->alpha ) + $other->alpha;
+ for ( $c = 0; $c < 3; $c++ ) {
+ $rgb[$c] = Less_Functions::operate( $op, $this->rgb[$c], $other->rgb[$c] );
}
- return new Less_Tree_Color($rgb, $alpha);
+ return new Less_Tree_Color( $rgb, $alpha );
}
- public function toRGB(){
- return $this->toHex($this->rgb);
+ public function toRGB() {
+ return $this->toHex( $this->rgb );
}
- public function toHSL(){
+ public function toHSL() {
$r = $this->rgb[0] / 255;
$g = $this->rgb[1] / 255;
$b = $this->rgb[2] / 255;
$a = $this->alpha;
- $max = max($r, $g, $b);
- $min = min($r, $g, $b);
- $l = ($max + $min) / 2;
+ $max = max( $r, $g, $b );
+ $min = min( $r, $g, $b );
+ $l = ( $max + $min ) / 2;
$d = $max - $min;
$h = $s = 0;
- if( $max !== $min ){
- $s = $l > 0.5 ? $d / (2 - $max - $min) : $d / ($max + $min);
+ if ( $max !== $min ) {
+ $s = $l > 0.5 ? $d / ( 2 - $max - $min ) : $d / ( $max + $min );
- switch ($max) {
- case $r: $h = ($g - $b) / $d + ($g < $b ? 6 : 0); break;
- case $g: $h = ($b - $r) / $d + 2; break;
- case $b: $h = ($r - $g) / $d + 4; break;
+ switch ( $max ) {
+ case $r:
+ $h = ( $g - $b ) / $d + ( $g < $b ? 6 : 0 );
+ break;
+ case $g:
+ $h = ( $b - $r ) / $d + 2;
+ break;
+ case $b:
+ $h = ( $r - $g ) / $d + 4;
+ break;
}
$h /= 6;
}
- return array('h' => $h * 360, 's' => $s, 'l' => $l, 'a' => $a );
+ return [ 'h' => $h * 360, 's' => $s, 'l' => $l, 'a' => $a ];
}
- //Adapted from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
- public function toHSV() {
+ // Adapted from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
+ public function toHSV() {
$r = $this->rgb[0] / 255;
$g = $this->rgb[1] / 255;
$b = $this->rgb[2] / 255;
$a = $this->alpha;
- $max = max($r, $g, $b);
- $min = min($r, $g, $b);
+ $max = max( $r, $g, $b );
+ $min = min( $r, $g, $b );
$v = $max;
$d = $max - $min;
- if ($max === 0) {
+ if ( $max === 0 ) {
$s = 0;
} else {
$s = $d / $max;
}
$h = 0;
- if( $max !== $min ){
- switch($max){
- case $r: $h = ($g - $b) / $d + ($g < $b ? 6 : 0); break;
- case $g: $h = ($b - $r) / $d + 2; break;
- case $b: $h = ($r - $g) / $d + 4; break;
+ if ( $max !== $min ) {
+ switch ( $max ) {
+ case $r:
+ $h = ( $g - $b ) / $d + ( $g < $b ? 6 : 0 );
+ break;
+ case $g:
+ $h = ( $b - $r ) / $d + 2;
+ break;
+ case $b:
+ $h = ( $r - $g ) / $d + 4;
+ break;
}
$h /= 6;
}
- return array('h'=> $h * 360, 's'=> $s, 'v'=> $v, 'a' => $a );
+ return [ 'h' => $h * 360, 's' => $s, 'v' => $v, 'a' => $a ];
}
- public function toARGB(){
- $argb = array_merge( (array) Less_Parser::round($this->alpha * 255), $this->rgb);
+ public function toARGB() {
+ $argb = array_merge( (array)Less_Parser::round( $this->alpha * 255 ), $this->rgb );
return $this->toHex( $argb );
}
- public function compare($x){
-
- if( !property_exists( $x, 'rgb' ) ){
+ public function compare( $x ) {
+ if ( !property_exists( $x, 'rgb' ) ) {
return -1;
}
-
- return ($x->rgb[0] === $this->rgb[0] &&
+ return ( $x->rgb[0] === $this->rgb[0] &&
$x->rgb[1] === $this->rgb[1] &&
$x->rgb[2] === $this->rgb[2] &&
- $x->alpha === $this->alpha) ? 0 : -1;
+ $x->alpha === $this->alpha ) ? 0 : -1;
}
- public function toHex( $v ){
-
+ public function toHex( $v ) {
$ret = '#';
- foreach($v as $c){
- $c = Less_Functions::clamp( Less_Parser::round($c), 255);
- if( $c < 16 ){
+ foreach ( $v as $c ) {
+ $c = Less_Functions::clamp( Less_Parser::round( $c ), 255 );
+ if ( $c < 16 ) {
$ret .= '0';
}
- $ret .= dechex($c);
+ $ret .= dechex( $c );
}
return $ret;
}
-
/**
* @param string $keyword
*/
- public static function fromKeyword( $keyword ){
- $keyword = strtolower($keyword);
+ public static function fromKeyword( $keyword ) {
+ $keyword = strtolower( $keyword );
- if( Less_Colors::hasOwnProperty($keyword) ){
+ if ( Less_Colors::hasOwnProperty( $keyword ) ) {
// detect named color
- return new Less_Tree_Color(substr(Less_Colors::color($keyword), 1));
+ return new Less_Tree_Color( substr( Less_Colors::color( $keyword ), 1 ) );
}
- if( $keyword === 'transparent' ){
- return new Less_Tree_Color( array(0, 0, 0), 0, true);
+ if ( $keyword === 'transparent' ) {
+ return new Less_Tree_Color( [ 0, 0, 0 ], 0, true );
}
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Comment.php b/vendor/wikimedia/less.php/lib/Less/Tree/Comment.php
index 7261284a2..b4dd68c60 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Comment.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Comment.php
@@ -1,12 +1,8 @@
value = $value;
- $this->silent = !! $silent;
+ $this->silent = (bool)$silent;
$this->currentFileInfo = $currentFileInfo;
}
- /**
- * @see Less_Tree::genCSS
- */
- public function genCSS( $output ){
- //if( $this->debugInfo ){
+ /**
+ * @see Less_Tree::genCSS
+ */
+ public function genCSS( $output ) {
+ // if( $this->debugInfo ){
//$output->add( tree.debugInfo($env, $this), $this->currentFileInfo, $this->index);
//}
- $output->add( trim($this->value) );//TODO shouldn't need to trim, we shouldn't grab the \n
+ $output->add( trim( $this->value ) );// TODO shouldn't need to trim, we shouldn't grab the \n
}
- public function toCSS(){
+ public function toCSS() {
return Less_Parser::$options['compress'] ? '' : $this->value;
}
- public function isSilent(){
- $isReference = ($this->currentFileInfo && isset($this->currentFileInfo['reference']) && (!isset($this->isReferenced) || !$this->isReferenced) );
- $isCompressed = Less_Parser::$options['compress'] && !preg_match('/^\/\*!/', $this->value);
+ public function isSilent() {
+ $isReference = ( $this->currentFileInfo && isset( $this->currentFileInfo['reference'] ) && ( !isset( $this->isReferenced ) || !$this->isReferenced ) );
+ $isCompressed = Less_Parser::$options['compress'] && !preg_match( '/^\/\*!/', $this->value );
return $this->silent || $isReference || $isCompressed;
}
- public function compile(){
- return $this;
- }
-
- public function markReferenced(){
+ public function markReferenced() {
$this->isReferenced = true;
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Condition.php b/vendor/wikimedia/less.php/lib/Less/Tree/Condition.php
index 929d33be9..5204e838c 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Condition.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Condition.php
@@ -1,12 +1,8 @@
op = trim($op);
+ public function __construct( $op, $l, $r, $i = 0, $negate = false ) {
+ $this->op = trim( $op );
$this->lvalue = $l;
$this->rvalue = $r;
$this->index = $i;
$this->negate = $negate;
}
- public function accept($visitor){
+ public function accept( $visitor ) {
$this->lvalue = $visitor->visitObj( $this->lvalue );
$this->rvalue = $visitor->visitObj( $this->rvalue );
}
- public function compile($env) {
- $a = $this->lvalue->compile($env);
- $b = $this->rvalue->compile($env);
+ public function compile( $env ) {
+ $a = $this->lvalue->compile( $env );
+ $b = $this->rvalue->compile( $env );
- switch( $this->op ){
+ switch ( $this->op ) {
case 'and':
$result = $a && $b;
- break;
+ break;
case 'or':
$result = $a || $b;
- break;
+ break;
default:
- if( Less_Parser::is_method($a, 'compare') ){
- $result = $a->compare($b);
- }elseif( Less_Parser::is_method($b, 'compare') ){
- $result = $b->compare($a);
- }else{
- throw new Less_Exception_Compiler('Unable to perform comparison', null, $this->index);
+ if ( Less_Parser::is_method( $a, 'compare' ) ) {
+ $result = $a->compare( $b );
+ } elseif ( Less_Parser::is_method( $b, 'compare' ) ) {
+ $result = $b->compare( $a );
+ } else {
+ throw new Less_Exception_Compiler( 'Unable to perform comparison', null, $this->index );
}
- switch ($result) {
+ switch ( $result ) {
case -1:
$result = $this->op === '<' || $this->op === '=<' || $this->op === '<=';
- break;
+ break;
- case 0:
+ case 0:
$result = $this->op === '=' || $this->op === '>=' || $this->op === '=<' || $this->op === '<=';
- break;
+ break;
- case 1:
+ case 1:
$result = $this->op === '>' || $this->op === '>=';
- break;
+ break;
}
- break;
+ break;
}
return $this->negate ? !$result : $result;
- }
+ }
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/DefaultFunc.php b/vendor/wikimedia/less.php/lib/Less/Tree/DefaultFunc.php
index c2dbf7496..66f0008cc 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/DefaultFunc.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/DefaultFunc.php
@@ -1,34 +1,30 @@
ruleset = $ruleset;
$this->frames = $frames;
}
- public function accept($visitor) {
- $this->ruleset = $visitor->visitObj($this->ruleset);
+ public function accept( $visitor ) {
+ $this->ruleset = $visitor->visitObj( $this->ruleset );
}
- public function compile($env){
- if( $this->frames ){
+ public function compile( $env ) {
+ if ( $this->frames ) {
$frames = $this->frames;
- }else{
+ } else {
$frames = $env->frames;
}
- return new Less_Tree_DetachedRuleset($this->ruleset, $frames);
+ return new Less_Tree_DetachedRuleset( $this->ruleset, $frames );
}
- public function callEval($env) {
- if( $this->frames ){
- return $this->ruleset->compile( $env->copyEvalEnv( array_merge($this->frames,$env->frames) ) );
+ public function callEval( $env ) {
+ if ( $this->frames ) {
+ return $this->ruleset->compile( $env->copyEvalEnv( array_merge( $this->frames, $env->frames ) ) );
}
return $this->ruleset->compile( $env );
}
}
-
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Dimension.php b/vendor/wikimedia/less.php/lib/Less/Tree/Dimension.php
index 2bfb9d54b..4dd719834 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Dimension.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Dimension.php
@@ -1,69 +1,60 @@
value = floatval($value);
+ public function __construct( $value, $unit = null ) {
+ $this->value = floatval( $value );
- if( $unit && ($unit instanceof Less_Tree_Unit) ){
+ if ( $unit && ( $unit instanceof Less_Tree_Unit ) ) {
$this->unit = $unit;
- }elseif( $unit ){
- $this->unit = new Less_Tree_Unit( array($unit) );
- }else{
- $this->unit = new Less_Tree_Unit( );
+ } elseif ( $unit ) {
+ $this->unit = new Less_Tree_Unit( [ $unit ] );
+ } else {
+ $this->unit = new Less_Tree_Unit();
}
- }
+ }
- public function accept( $visitor ){
+ public function accept( $visitor ) {
$this->unit = $visitor->visitObj( $this->unit );
}
- public function compile(){
- return $this;
- }
+ public function toColor() {
+ return new Less_Tree_Color( [ $this->value, $this->value, $this->value ] );
+ }
- public function toColor() {
- return new Less_Tree_Color(array($this->value, $this->value, $this->value));
- }
-
- /**
- * @see Less_Tree::genCSS
- */
- public function genCSS( $output ){
-
- if( Less_Parser::$options['strictUnits'] && !$this->unit->isSingular() ){
- throw new Less_Exception_Compiler("Multiple units in dimension. Correct the units or use the unit function. Bad unit: ".$this->unit->toString());
+ /**
+ * @see Less_Tree::genCSS
+ */
+ public function genCSS( $output ) {
+ if ( Less_Parser::$options['strictUnits'] && !$this->unit->isSingular() ) {
+ throw new Less_Exception_Compiler( "Multiple units in dimension. Correct the units or use the unit function. Bad unit: " . $this->unit->toString() );
}
$value = Less_Functions::fround( $this->value );
$strValue = (string)$value;
- if( $value !== 0 && $value < 0.000001 && $value > -0.000001 ){
+ if ( $value !== 0 && $value < 0.000001 && $value > -0.000001 ) {
// would be output 1e-6 etc.
- $strValue = number_format($strValue,10);
- $strValue = preg_replace('/\.?0+$/','', $strValue);
+ $strValue = number_format( (float)$strValue, 10 );
+ $strValue = preg_replace( '/\.?0+$/', '', $strValue );
}
- if( Less_Parser::$options['compress'] ){
+ if ( Less_Parser::$options['compress'] ) {
// Zero values doesn't need a unit
- if( $value === 0 && $this->unit->isLength() ){
+ if ( $value === 0 && $this->unit->isLength() ) {
$output->add( $strValue );
- return $strValue;
+ return;
}
// Float values doesn't need a leading zero
- if( $value > 0 && $value < 1 && $strValue[0] === '0' ){
- $strValue = substr($strValue,1);
+ if ( $value > 0 && $value < 1 && $strValue[0] === '0' ) {
+ $strValue = substr( $strValue, 1 );
}
}
@@ -71,73 +62,72 @@ class Less_Tree_Dimension extends Less_Tree{
$this->unit->genCSS( $output );
}
- public function __toString(){
- return $this->toCSS();
- }
+ public function __toString() {
+ return $this->toCSS();
+ }
- // In an operation between two Dimensions,
- // we default to the first Dimension's unit,
- // so `1px + 2em` will yield `3px`.
+ // In an operation between two Dimensions,
+ // we default to the first Dimension's unit,
+ // so `1px + 2em` will yield `3px`.
- /**
- * @param string $op
- */
- public function operate( $op, $other){
-
- $value = Less_Functions::operate( $op, $this->value, $other->value);
+ /**
+ * @param string $op
+ */
+ public function operate( $op, $other ) {
+ $value = Less_Functions::operate( $op, $this->value, $other->value );
$unit = clone $this->unit;
- if( $op === '+' || $op === '-' ){
+ if ( $op === '+' || $op === '-' ) {
- if( !$unit->numerator && !$unit->denominator ){
+ if ( !$unit->numerator && !$unit->denominator ) {
$unit->numerator = $other->unit->numerator;
$unit->denominator = $other->unit->denominator;
- }elseif( !$other->unit->numerator && !$other->unit->denominator ){
+ } elseif ( !$other->unit->numerator && !$other->unit->denominator ) {
// do nothing
- }else{
- $other = $other->convertTo( $this->unit->usedUnits());
+ } else {
+ $other = $other->convertTo( $this->unit->usedUnits() );
- if( Less_Parser::$options['strictUnits'] && $other->unit->toString() !== $unit->toCSS() ){
- throw new Less_Exception_Compiler("Incompatible units. Change the units or use the unit function. Bad units: '" . $unit->toString() . "' and " . $other->unit->toString() . "'.");
+ if ( Less_Parser::$options['strictUnits'] && $other->unit->toString() !== $unit->toCSS() ) {
+ throw new Less_Exception_Compiler( "Incompatible units. Change the units or use the unit function. Bad units: '" . $unit->toString() . "' and " . $other->unit->toString() . "'." );
}
- $value = Less_Functions::operate( $op, $this->value, $other->value);
+ $value = Less_Functions::operate( $op, $this->value, $other->value );
}
- }elseif( $op === '*' ){
- $unit->numerator = array_merge($unit->numerator, $other->unit->numerator);
- $unit->denominator = array_merge($unit->denominator, $other->unit->denominator);
- sort($unit->numerator);
- sort($unit->denominator);
+ } elseif ( $op === '*' ) {
+ $unit->numerator = array_merge( $unit->numerator, $other->unit->numerator );
+ $unit->denominator = array_merge( $unit->denominator, $other->unit->denominator );
+ sort( $unit->numerator );
+ sort( $unit->denominator );
$unit->cancel();
- }elseif( $op === '/' ){
- $unit->numerator = array_merge($unit->numerator, $other->unit->denominator);
- $unit->denominator = array_merge($unit->denominator, $other->unit->numerator);
- sort($unit->numerator);
- sort($unit->denominator);
+ } elseif ( $op === '/' ) {
+ $unit->numerator = array_merge( $unit->numerator, $other->unit->denominator );
+ $unit->denominator = array_merge( $unit->denominator, $other->unit->numerator );
+ sort( $unit->numerator );
+ sort( $unit->denominator );
$unit->cancel();
}
- return new Less_Tree_Dimension( $value, $unit);
- }
+ return new Less_Tree_Dimension( $value, $unit );
+ }
- public function compare($other) {
- if ($other instanceof Less_Tree_Dimension) {
+ public function compare( $other ) {
+ if ( $other instanceof Less_Tree_Dimension ) {
- if( $this->unit->isEmpty() || $other->unit->isEmpty() ){
+ if ( $this->unit->isEmpty() || $other->unit->isEmpty() ) {
$a = $this;
$b = $other;
} else {
$a = $this->unify();
$b = $other->unify();
- if( $a->unit->compare($b->unit) !== 0 ){
+ if ( $a->unit->compare( $b->unit ) !== 0 ) {
return -1;
}
}
$aValue = $a->value;
$bValue = $b->value;
- if ($bValue > $aValue) {
+ if ( $bValue > $aValue ) {
return -1;
- } elseif ($bValue < $aValue) {
+ } elseif ( $bValue < $aValue ) {
return 1;
} else {
return 0;
@@ -147,48 +137,47 @@ class Less_Tree_Dimension extends Less_Tree{
}
}
- public function unify() {
- return $this->convertTo(array('length'=> 'px', 'duration'=> 's', 'angle' => 'rad' ));
+ public function unify() {
+ return $this->convertTo( [ 'length' => 'px', 'duration' => 's', 'angle' => 'rad' ] );
}
- public function convertTo($conversions) {
+ public function convertTo( $conversions ) {
$value = $this->value;
$unit = clone $this->unit;
- if( is_string($conversions) ){
- $derivedConversions = array();
- foreach( Less_Tree_UnitConversions::$groups as $i ){
- if( isset(Less_Tree_UnitConversions::${$i}[$conversions]) ){
- $derivedConversions = array( $i => $conversions);
+ if ( is_string( $conversions ) ) {
+ $derivedConversions = [];
+ foreach ( Less_Tree_UnitConversions::$groups as $i ) {
+ if ( isset( Less_Tree_UnitConversions::${$i}[$conversions] ) ) {
+ $derivedConversions = [ $i => $conversions ];
}
}
$conversions = $derivedConversions;
}
-
- foreach($conversions as $groupName => $targetUnit){
+ foreach ( $conversions as $groupName => $targetUnit ) {
$group = Less_Tree_UnitConversions::${$groupName};
- //numerator
- foreach($unit->numerator as $i => $atomicUnit){
+ // numerator
+ foreach ( $unit->numerator as $i => $atomicUnit ) {
$atomicUnit = $unit->numerator[$i];
- if( !isset($group[$atomicUnit]) ){
+ if ( !isset( $group[$atomicUnit] ) ) {
continue;
}
- $value = $value * ($group[$atomicUnit] / $group[$targetUnit]);
+ $value = $value * ( $group[$atomicUnit] / $group[$targetUnit] );
$unit->numerator[$i] = $targetUnit;
}
- //denominator
- foreach($unit->denominator as $i => $atomicUnit){
+ // denominator
+ foreach ( $unit->denominator as $i => $atomicUnit ) {
$atomicUnit = $unit->denominator[$i];
- if( !isset($group[$atomicUnit]) ){
+ if ( !isset( $group[$atomicUnit] ) ) {
continue;
}
- $value = $value / ($group[$atomicUnit] / $group[$targetUnit]);
+ $value = $value / ( $group[$atomicUnit] / $group[$targetUnit] );
$unit->denominator[$i] = $targetUnit;
}
@@ -196,6 +185,6 @@ class Less_Tree_Dimension extends Less_Tree{
$unit->cancel();
- return new Less_Tree_Dimension( $value, $unit);
- }
+ return new Less_Tree_Dimension( $value, $unit );
+ }
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Directive.php b/vendor/wikimedia/less.php/lib/Less/Tree/Directive.php
index 04a1e467e..dfada8437 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Directive.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Directive.php
@@ -1,12 +1,8 @@
name = $name;
$this->value = $value;
- if( $rules ){
+ if ( $rules ) {
$this->rules = $rules;
$this->rules->allowImports = true;
}
@@ -30,70 +26,66 @@ class Less_Tree_Directive extends Less_Tree{
$this->debugInfo = $debugInfo;
}
-
- public function accept( $visitor ){
- if( $this->rules ){
+ public function accept( $visitor ) {
+ if ( $this->rules ) {
$this->rules = $visitor->visitObj( $this->rules );
}
- if( $this->value ){
+ if ( $this->value ) {
$this->value = $visitor->visitObj( $this->value );
}
}
-
- /**
- * @see Less_Tree::genCSS
- */
- public function genCSS( $output ){
+ /**
+ * @see Less_Tree::genCSS
+ */
+ public function genCSS( $output ) {
$value = $this->value;
$rules = $this->rules;
$output->add( $this->name, $this->currentFileInfo, $this->index );
- if( $this->value ){
- $output->add(' ');
- $this->value->genCSS($output);
+ if ( $this->value ) {
+ $output->add( ' ' );
+ $this->value->genCSS( $output );
}
- if( $this->rules ){
- Less_Tree::outputRuleset( $output, array($this->rules));
+ if ( $this->rules ) {
+ Less_Tree::outputRuleset( $output, [ $this->rules ] );
} else {
- $output->add(';');
+ $output->add( ';' );
}
}
- public function compile($env){
-
+ public function compile( $env ) {
$value = $this->value;
$rules = $this->rules;
- if( $value ){
- $value = $value->compile($env);
+ if ( $value ) {
+ $value = $value->compile( $env );
}
- if( $rules ){
- $rules = $rules->compile($env);
+ if ( $rules ) {
+ $rules = $rules->compile( $env );
$rules->root = true;
}
return new Less_Tree_Directive( $this->name, $value, $rules, $this->index, $this->currentFileInfo, $this->debugInfo );
}
-
- public function variable($name){
- if( $this->rules ){
- return $this->rules->variable($name);
+ public function variable( $name ) {
+ if ( $this->rules ) {
+ return $this->rules->variable( $name );
}
}
- public function find($selector){
- if( $this->rules ){
- return $this->rules->find($selector, $this);
+ public function find( $selector ) {
+ if ( $this->rules ) {
+ return $this->rules->find( $selector, $this );
}
}
- //rulesets: function () { if (this.rules) return tree.Ruleset.prototype.rulesets.apply(this.rules); },
+ // rulesets: function () { if (this.rules) return tree.Ruleset.prototype.rulesets.apply(this.rules); },
- public function markReferenced(){
+ public function markReferenced() {
$this->isReferenced = true;
- if( $this->rules ){
- Less_Tree::ReferencedArray($this->rules->rules);
+ if ( $this->rules ) {
+ Less_Tree::ReferencedArray( $this->rules->rules );
}
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Element.php b/vendor/wikimedia/less.php/lib/Less/Tree/Element.php
index 9cea5e43c..11b9ce40a 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Element.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Element.php
@@ -1,74 +1,72 @@
value = $value;
- $this->value_is_object = is_object($value);
+ $this->value_is_object = is_object( $value );
- if( $combinator ){
- $this->combinator = $combinator;
- }
+ // see less-2.5.3.js#Combinator
+ $this->combinator = $combinator ?? '';
+ $this->combinatorIsEmptyOrWhitespace = ( $combinator === null || trim( $combinator ) === '' );
$this->index = $index;
$this->currentFileInfo = $currentFileInfo;
}
- public function accept( $visitor ){
- if( $this->value_is_object ){ //object or string
+ public function accept( $visitor ) {
+ if ( $this->value_is_object ) { // object or string
$this->value = $visitor->visitObj( $this->value );
}
}
- public function compile($env){
-
- if( Less_Environment::$mixin_stack ){
- return new Less_Tree_Element($this->combinator, ($this->value_is_object ? $this->value->compile($env) : $this->value), $this->index, $this->currentFileInfo );
- }
-
- if( $this->value_is_object ){
- $this->value = $this->value->compile($env);
- }
-
- return $this;
+ public function compile( $env ) {
+ return new Less_Tree_Element(
+ $this->combinator,
+ ( $this->value_is_object ? $this->value->compile( $env ) : $this->value ),
+ $this->index,
+ $this->currentFileInfo
+ );
}
- /**
- * @see Less_Tree::genCSS
- */
- public function genCSS( $output ){
+ /**
+ * @see Less_Tree::genCSS
+ */
+ public function genCSS( $output ) {
$output->add( $this->toCSS(), $this->currentFileInfo, $this->index );
}
- public function toCSS(){
-
- if( $this->value_is_object ){
+ public function toCSS() {
+ if ( $this->value_is_object ) {
$value = $this->value->toCSS();
- }else{
+ } else {
$value = $this->value;
}
-
- if( $value === '' && $this->combinator && $this->combinator === '&' ){
+ if ( $value === '' && $this->combinator && $this->combinator === '&' ) {
return '';
}
-
return Less_Environment::$_outputMap[$this->combinator] . $value;
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Expression.php b/vendor/wikimedia/less.php/lib/Less/Tree/Expression.php
index d834354a1..832414102 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Expression.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Expression.php
@@ -1,92 +1,85 @@
value = $value;
$this->parens = $parens;
}
- public function accept( $visitor ){
+ public function accept( $visitor ) {
$this->value = $visitor->visitArray( $this->value );
}
- public function compile($env) {
-
+ public function compile( $env ) {
$doubleParen = false;
- if( $this->parens && !$this->parensInOp ){
+ if ( $this->parens && !$this->parensInOp ) {
Less_Environment::$parensStack++;
}
$returnValue = null;
- if( $this->value ){
+ if ( $this->value ) {
- $count = count($this->value);
+ $count = count( $this->value );
- if( $count > 1 ){
+ if ( $count > 1 ) {
- $ret = array();
- foreach($this->value as $e){
- $ret[] = $e->compile($env);
+ $ret = [];
+ foreach ( $this->value as $e ) {
+ $ret[] = $e->compile( $env );
}
- $returnValue = new Less_Tree_Expression($ret);
+ $returnValue = new Less_Tree_Expression( $ret );
- }else{
+ } else {
- if( ($this->value[0] instanceof Less_Tree_Expression) && $this->value[0]->parens && !$this->value[0]->parensInOp ){
+ if ( ( $this->value[0] instanceof Less_Tree_Expression ) && $this->value[0]->parens && !$this->value[0]->parensInOp ) {
$doubleParen = true;
}
- $returnValue = $this->value[0]->compile($env);
+ $returnValue = $this->value[0]->compile( $env );
}
} else {
$returnValue = $this;
}
- if( $this->parens ){
- if( !$this->parensInOp ){
+ if ( $this->parens ) {
+ if ( !$this->parensInOp ) {
Less_Environment::$parensStack--;
- }elseif( !Less_Environment::isMathOn() && !$doubleParen ){
- $returnValue = new Less_Tree_Paren($returnValue);
+ } elseif ( !Less_Environment::isMathOn() && !$doubleParen ) {
+ $returnValue = new Less_Tree_Paren( $returnValue );
}
}
return $returnValue;
}
- /**
- * @see Less_Tree::genCSS
- */
- public function genCSS( $output ){
- $val_len = count($this->value);
- for( $i = 0; $i < $val_len; $i++ ){
+ /**
+ * @see Less_Tree::genCSS
+ */
+ public function genCSS( $output ) {
+ $val_len = count( $this->value );
+ for ( $i = 0; $i < $val_len; $i++ ) {
$this->value[$i]->genCSS( $output );
- if( $i + 1 < $val_len ){
+ if ( $i + 1 < $val_len ) {
$output->add( ' ' );
}
}
}
- public function throwAwayComments() {
-
- if( is_array($this->value) ){
- $new_value = array();
- foreach($this->value as $v){
- if( $v instanceof Less_Tree_Comment ){
+ public function throwAwayComments() {
+ if ( is_array( $this->value ) ) {
+ $new_value = [];
+ foreach ( $this->value as $v ) {
+ if ( $v instanceof Less_Tree_Comment ) {
continue;
}
$new_value[] = $v;
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Extend.php b/vendor/wikimedia/less.php/lib/Less/Tree/Extend.php
index 8f21e939d..362e284ff 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Extend.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Extend.php
@@ -1,77 +1,76 @@
selector = $selector;
$this->option = $option;
$this->index = $index;
- switch($option){
+ switch ( $option ) {
case "all":
$this->allowBefore = true;
$this->allowAfter = true;
- break;
+ break;
default:
$this->allowBefore = false;
$this->allowAfter = false;
- break;
+ break;
}
- $this->object_id = $i++;
- $this->parent_ids = array($this->object_id);
+ // This must use a string (instead of int) so that array_merge()
+ // preserves keys on arrays that use IDs in their keys.
+ $this->object_id = 'id_' . $i++;
+
+ $this->parent_ids = [
+ $this->object_id => true
+ ];
}
- public function accept( $visitor ){
+ public function accept( $visitor ) {
$this->selector = $visitor->visitObj( $this->selector );
}
- public function compile( $env ){
+ public function compile( $env ) {
Less_Parser::$has_extends = true;
- $this->selector = $this->selector->compile($env);
+ $this->selector = $this->selector->compile( $env );
return $this;
- //return new Less_Tree_Extend( $this->selector->compile($env), $this->option, $this->index);
+ // return new Less_Tree_Extend( $this->selector->compile($env), $this->option, $this->index);
}
- public function findSelfSelectors( $selectors ){
- $selfElements = array();
+ public function findSelfSelectors( $selectors ) {
+ $selfElements = [];
-
- for( $i = 0, $selectors_len = count($selectors); $i < $selectors_len; $i++ ){
+ for ( $i = 0, $selectors_len = count( $selectors ); $i < $selectors_len; $i++ ) {
$selectorElements = $selectors[$i]->elements;
// duplicate the logic in genCSS function inside the selector node.
// future TODO - move both logics into the selector joiner visitor
- if( $i && $selectorElements && $selectorElements[0]->combinator === "") {
+ if ( $i && $selectorElements && $selectorElements[0]->combinator === "" ) {
$selectorElements[0]->combinator = ' ';
}
$selfElements = array_merge( $selfElements, $selectors[$i]->elements );
}
- $this->selfSelectors = array(new Less_Tree_Selector($selfElements));
+ $this->selfSelectors = [ new Less_Tree_Selector( $selfElements ) ];
}
-}
\ No newline at end of file
+}
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Import.php b/vendor/wikimedia/less.php/lib/Less/Tree/Import.php
index 49ffbf636..fc5e81d56 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Import.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Import.php
@@ -1,7 +1,6 @@
options = $options;
$this->index = $index;
$this->path = $path;
$this->features = $features;
$this->currentFileInfo = $currentFileInfo;
- if( is_array($options) ){
- $this->options += array('inline'=>false);
+ if ( is_array( $options ) ) {
+ $this->options += [ 'inline' => false ];
- if( isset($this->options['less']) || $this->options['inline'] ){
- $this->css = !isset($this->options['less']) || !$this->options['less'] || $this->options['inline'];
+ if ( isset( $this->options['less'] ) || $this->options['inline'] ) {
+ $this->css = !isset( $this->options['less'] ) || !$this->options['less'] || $this->options['inline'];
} else {
$pathValue = $this->getPath();
- if( $pathValue && preg_match('/css([\?;].*)?$/',$pathValue) ){
+ // Leave any ".css" file imports as literals for the browser.
+ // Also leave any remote HTTP resources as literals regardless of whether
+ // they contain ".css" in their filename.
+ if ( $pathValue && preg_match( '/^(https?:)?\/\/|\.css$/i', $pathValue ) ) {
$this->css = true;
}
}
@@ -58,28 +59,27 @@ class Less_Tree_Import extends Less_Tree{
// ruleset.
//
- public function accept($visitor){
-
- if( $this->features ){
- $this->features = $visitor->visitObj($this->features);
+ public function accept( $visitor ) {
+ if ( $this->features ) {
+ $this->features = $visitor->visitObj( $this->features );
}
- $this->path = $visitor->visitObj($this->path);
+ $this->path = $visitor->visitObj( $this->path );
- if( !$this->options['inline'] && $this->root ){
- $this->root = $visitor->visit($this->root);
+ if ( !$this->options['inline'] && $this->root ) {
+ $this->root = $visitor->visit( $this->root );
}
}
- /**
- * @see Less_Tree::genCSS
- */
- public function genCSS( $output ){
- if( $this->css ){
+ /**
+ * @see Less_Tree::genCSS
+ */
+ public function genCSS( $output ) {
+ if ( $this->css ) {
$output->add( '@import ', $this->currentFileInfo, $this->index );
$this->path->genCSS( $output );
- if( $this->features ){
+ if ( $this->features ) {
$output->add( ' ' );
$this->features->genCSS( $output );
}
@@ -87,10 +87,10 @@ class Less_Tree_Import extends Less_Tree{
}
}
- public function toCSS(){
+ public function toCSS() {
$features = $this->features ? ' ' . $this->features->toCSS() : '';
- if ($this->css) {
+ if ( $this->css ) {
return "@import " . $this->path->toCSS() . $features . ";\n";
} else {
return "";
@@ -98,132 +98,126 @@ class Less_Tree_Import extends Less_Tree{
}
/**
- * @return string
+ * @return string|null
*/
- public function getPath(){
- if ($this->path instanceof Less_Tree_Quoted) {
+ public function getPath() {
+ if ( $this->path instanceof Less_Tree_Quoted ) {
$path = $this->path->value;
- $path = ( isset($this->css) || preg_match('/(\.[a-z]*$)|([\?;].*)$/',$path)) ? $path : $path . '.less';
- } else if ($this->path instanceof Less_Tree_URL) {
+ $path = ( isset( $this->css ) || preg_match( '/(\.[a-z]*$)|([\?;].*)$/', $path ) ) ? $path : $path . '.less';
+
+ // During the first pass, Less_Tree_URL may contain a Less_Tree_Variable (not yet expanded),
+ // and thus has no value property defined yet. Return null until we reach the next phase.
+ // https://github.com/wikimedia/less.php/issues/29
+ } elseif ( $this->path instanceof Less_Tree_URL && !( $this->path->value instanceof Less_Tree_Variable ) ) {
$path = $this->path->value->value;
- }else{
+ } else {
return null;
}
- //remove query string and fragment
- return preg_replace('/[\?#][^\?]*$/','',$path);
+ // remove query string and fragment
+ return preg_replace( '/[\?#][^\?]*$/', '', $path );
}
- public function compileForImport( $env ){
- return new Less_Tree_Import( $this->path->compile($env), $this->features, $this->options, $this->index, $this->currentFileInfo);
+ public function compileForImport( $env ) {
+ return new Less_Tree_Import( $this->path->compile( $env ), $this->features, $this->options, $this->index, $this->currentFileInfo );
}
- public function compilePath($env) {
- $path = $this->path->compile($env);
+ public function compilePath( $env ) {
+ $path = $this->path->compile( $env );
$rootpath = '';
- if( $this->currentFileInfo && $this->currentFileInfo['rootpath'] ){
+ if ( $this->currentFileInfo && $this->currentFileInfo['rootpath'] ) {
$rootpath = $this->currentFileInfo['rootpath'];
}
-
- if( !($path instanceof Less_Tree_URL) ){
- if( $rootpath ){
+ if ( !( $path instanceof Less_Tree_URL ) ) {
+ if ( $rootpath ) {
$pathValue = $path->value;
// Add the base path if the import is relative
- if( $pathValue && Less_Environment::isPathRelative($pathValue) ){
- $path->value = $this->currentFileInfo['uri_root'].$pathValue;
+ if ( $pathValue && Less_Environment::isPathRelative( $pathValue ) ) {
+ $path->value = $this->currentFileInfo['uri_root'] . $pathValue;
}
}
- $path->value = Less_Environment::normalizePath($path->value);
+ $path->value = Less_Environment::normalizePath( $path->value );
}
-
-
return $path;
}
- public function compile( $env ){
+ public function compile( $env ) {
+ $evald = $this->compileForImport( $env );
- $evald = $this->compileForImport($env);
-
- //get path & uri
+ // get path & uri
$path_and_uri = null;
- if( is_callable(Less_Parser::$options['import_callback']) ){
- $path_and_uri = call_user_func(Less_Parser::$options['import_callback'],$evald);
+ if ( is_callable( Less_Parser::$options['import_callback'] ) ) {
+ $path_and_uri = call_user_func( Less_Parser::$options['import_callback'], $evald );
}
- if( !$path_and_uri ){
+ if ( !$path_and_uri ) {
$path_and_uri = $evald->PathAndUri();
}
- if( $path_and_uri ){
- list($full_path, $uri) = $path_and_uri;
- }else{
+ if ( $path_and_uri ) {
+ list( $full_path, $uri ) = $path_and_uri;
+ } else {
$full_path = $uri = $evald->getPath();
}
-
- //import once
- if( $evald->skip( $full_path, $env) ){
- return array();
+ // import once
+ if ( $evald->skip( $full_path, $env ) ) {
+ return [];
}
+ '@phan-var string $full_path';
- if( $this->options['inline'] ){
- //todo needs to reference css file not import
+ if ( $this->options['inline'] ) {
+ // todo needs to reference css file not import
//$contents = new Less_Tree_Anonymous($this->root, 0, array('filename'=>$this->importedFilename), true );
- Less_Parser::AddParsedFile($full_path);
- $contents = new Less_Tree_Anonymous( file_get_contents($full_path), 0, array(), true );
+ Less_Parser::AddParsedFile( $full_path );
+ $contents = new Less_Tree_Anonymous( file_get_contents( $full_path ), 0, [], true );
- if( $this->features ){
- return new Less_Tree_Media( array($contents), $this->features->value );
+ if ( $this->features ) {
+ return new Less_Tree_Media( [ $contents ], $this->features->value );
}
- return array( $contents );
+ return [ $contents ];
}
// optional (need to be before "CSS" to support optional CSS imports. CSS should be checked only if empty($this->currentFileInfo))
- if( isset($this->options['optional']) && $this->options['optional'] && !file_exists($full_path) && (!$evald->css || !empty($this->currentFileInfo))) {
- return array();
+ if ( isset( $this->options['optional'] ) && $this->options['optional'] && !file_exists( $full_path ) && ( !$evald->css || !empty( $this->currentFileInfo ) ) ) {
+ return [];
}
-
// css ?
- if( $evald->css ){
- $features = ( $evald->features ? $evald->features->compile($env) : null );
- return new Less_Tree_Import( $this->compilePath( $env), $features, $this->options, $this->index);
+ if ( $evald->css ) {
+ $features = ( $evald->features ? $evald->features->compile( $env ) : null );
+ return new Less_Tree_Import( $this->compilePath( $env ), $features, $this->options, $this->index );
}
-
return $this->ParseImport( $full_path, $uri, $env );
}
-
/**
* Using the import directories, get the full absolute path and uri of the import
- *
- * @param Less_Tree_Import $evald
*/
- public function PathAndUri(){
-
+ public function PathAndUri() {
$evald_path = $this->getPath();
- if( $evald_path ){
+ if ( $evald_path ) {
- $import_dirs = array();
+ $import_dirs = [];
- if( Less_Environment::isPathRelative($evald_path) ){
- //if the path is relative, the file should be in the current directory
- if ( $this->currentFileInfo ){
+ if ( Less_Environment::isPathRelative( $evald_path ) ) {
+ // if the path is relative, the file should be in the current directory
+ if ( $this->currentFileInfo ) {
$import_dirs[ $this->currentFileInfo['currentDirectory'] ] = $this->currentFileInfo['uri_root'];
}
- }else{
- //otherwise, the file should be relative to the server root
- if( $this->currentFileInfo ) {
+ } else {
+ // otherwise, the file should be relative to the server root
+ if ( $this->currentFileInfo ) {
$import_dirs[ $this->currentFileInfo['entryPath'] ] = $this->currentFileInfo['entryUri'];
}
- //if the user supplied entryPath isn't the actual root
+ // if the user supplied entryPath isn't the actual root
$import_dirs[ $_SERVER['DOCUMENT_ROOT'] ] = '';
}
@@ -231,77 +225,75 @@ class Less_Tree_Import extends Less_Tree{
// always look in user supplied import directories
$import_dirs = array_merge( $import_dirs, Less_Parser::$options['import_dirs'] );
-
- foreach( $import_dirs as $rootpath => $rooturi){
- if( is_callable($rooturi) ){
- list($path, $uri) = call_user_func($rooturi, $evald_path);
- if( is_string($path) ){
+ foreach ( $import_dirs as $rootpath => $rooturi ) {
+ if ( is_callable( $rooturi ) ) {
+ list( $path, $uri ) = call_user_func( $rooturi, $evald_path );
+ if ( is_string( $path ) ) {
$full_path = $path;
- return array( $full_path, $uri );
+ return [ $full_path, $uri ];
}
- }elseif( !empty($rootpath) ){
+ } elseif ( !empty( $rootpath ) ) {
- $path = rtrim($rootpath,'/\\').'/'.ltrim($evald_path,'/\\');
+ $path = rtrim( $rootpath, '/\\' ) . '/' . ltrim( $evald_path, '/\\' );
- if( file_exists($path) ){
- $full_path = Less_Environment::normalizePath($path);
- $uri = Less_Environment::normalizePath(dirname($rooturi.$evald_path));
- return array( $full_path, $uri );
- } elseif( file_exists($path.'.less') ){
- $full_path = Less_Environment::normalizePath($path.'.less');
- $uri = Less_Environment::normalizePath(dirname($rooturi.$evald_path.'.less'));
- return array( $full_path, $uri );
+ if ( file_exists( $path ) ) {
+ $full_path = Less_Environment::normalizePath( $path );
+ $uri = Less_Environment::normalizePath( dirname( $rooturi . $evald_path ) );
+ return [ $full_path, $uri ];
+ } elseif ( file_exists( $path . '.less' ) ) {
+ $full_path = Less_Environment::normalizePath( $path . '.less' );
+ $uri = Less_Environment::normalizePath( dirname( $rooturi . $evald_path . '.less' ) );
+ return [ $full_path, $uri ];
}
}
}
}
}
-
/**
* Parse the import url and return the rules
*
+ * @param string $full_path
+ * @param string|null $uri
+ * @param mixed $env
* @return Less_Tree_Media|array
*/
- public function ParseImport( $full_path, $uri, $env ){
-
+ public function ParseImport( $full_path, $uri, $env ) {
$import_env = clone $env;
- if( (isset($this->options['reference']) && $this->options['reference']) || isset($this->currentFileInfo['reference']) ){
+ if ( ( isset( $this->options['reference'] ) && $this->options['reference'] ) || isset( $this->currentFileInfo['reference'] ) ) {
$import_env->currentFileInfo['reference'] = true;
}
- if( (isset($this->options['multiple']) && $this->options['multiple']) ){
+ if ( ( isset( $this->options['multiple'] ) && $this->options['multiple'] ) ) {
$import_env->importMultiple = true;
}
- $parser = new Less_Parser($import_env);
- $root = $parser->parseFile($full_path, $uri, true);
+ $parser = new Less_Parser( $import_env );
+ $root = $parser->parseFile( $full_path, $uri, true );
+ $ruleset = new Less_Tree_Ruleset( null, $root->rules );
+ $ruleset->evalImports( $import_env );
- $ruleset = new Less_Tree_Ruleset(array(), $root->rules );
- $ruleset->evalImports($import_env);
-
- return $this->features ? new Less_Tree_Media($ruleset->rules, $this->features->value) : $ruleset->rules;
+ return $this->features ? new Less_Tree_Media( $ruleset->rules, $this->features->value ) : $ruleset->rules;
}
-
/**
* Should the import be skipped?
*
- * @return boolean|null
+ * @param string|null $path
+ * @param Less_Environment $env
+ * @return bool|null
*/
- private function Skip($path, $env){
+ private function skip( $path, $env ) {
+ $path = Less_Parser::AbsPath( $path, true );
- $path = Less_Parser::AbsPath($path, true);
+ if ( $path && Less_Parser::FileParsed( $path ) ) {
- if( $path && Less_Parser::FileParsed($path) ){
-
- if( isset($this->currentFileInfo['reference']) ){
+ if ( isset( $this->currentFileInfo['reference'] ) ) {
return true;
}
- return !isset($this->options['multiple']) && !$env->importMultiple;
+ return !isset( $this->options['multiple'] ) && !$env->importMultiple;
}
-
}
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Javascript.php b/vendor/wikimedia/less.php/lib/Less/Tree/Javascript.php
index 1b03183d9..218d48178 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Javascript.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Javascript.php
@@ -1,12 +1,8 @@
escaped = $escaped;
$this->expression = $string;
$this->index = $index;
}
- public function compile(){
- return new Less_Tree_Anonymous('/* Sorry, can not do JavaScript evaluation in PHP... :( */');
+ public function compile( $env ) {
+ return new Less_Tree_Anonymous( '/* Sorry, can not do JavaScript evaluation in PHP... :( */' );
}
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Keyword.php b/vendor/wikimedia/less.php/lib/Less/Tree/Keyword.php
index e1d98c456..60663f04c 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Keyword.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Keyword.php
@@ -1,12 +1,8 @@
value = $value;
}
- public function compile(){
- return $this;
- }
-
- /**
- * @see Less_Tree::genCSS
- */
- public function genCSS( $output ){
-
- if( $this->value === '%') {
- throw new Less_Exception_Compiler("Invalid % without number");
+ /**
+ * @see Less_Tree::genCSS
+ */
+ public function genCSS( $output ) {
+ if ( $this->value === '%' ) {
+ throw new Less_Exception_Compiler( "Invalid % without number" );
}
$output->add( $this->value );
}
- public function compare($other) {
- if ($other instanceof Less_Tree_Keyword) {
+ public function compare( $other ) {
+ if ( $other instanceof Less_Tree_Keyword ) {
return $other->value === $this->value ? 0 : 1;
} else {
return -1;
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Media.php b/vendor/wikimedia/less.php/lib/Less/Tree/Media.php
index f9ee9d421..3cb1fc4d1 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Media.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Media.php
@@ -1,12 +1,8 @@
index = $index;
$this->currentFileInfo = $currentFileInfo;
$selectors = $this->emptySelectors();
- $this->features = new Less_Tree_Value($features);
+ $this->features = new Less_Tree_Value( $features );
- $this->rules = array(new Less_Tree_Ruleset($selectors, $value));
+ $this->rules = [ new Less_Tree_Ruleset( $selectors, $value ) ];
$this->rules[0]->allowImports = true;
}
- public function accept( $visitor ){
- $this->features = $visitor->visitObj($this->features);
- $this->rules = $visitor->visitArray($this->rules);
+ public function accept( $visitor ) {
+ $this->features = $visitor->visitObj( $this->features );
+ $this->rules = $visitor->visitArray( $this->rules );
}
- /**
- * @see Less_Tree::genCSS
- */
- public function genCSS( $output ){
-
+ /**
+ * @see Less_Tree::genCSS
+ */
+ public function genCSS( $output ) {
$output->add( '@media ', $this->currentFileInfo, $this->index );
$this->features->genCSS( $output );
- Less_Tree::outputRuleset( $output, $this->rules);
-
+ Less_Tree::outputRuleset( $output, $this->rules );
}
- public function compile($env) {
-
- $media = new Less_Tree_Media(array(), array(), $this->index, $this->currentFileInfo );
+ /**
+ * @param Less_Environment $env
+ * @return Less_Tree_Media|Less_Tree_Ruleset
+ * @see less-2.5.3.js#Media.prototype.eval
+ */
+ public function compile( $env ) {
+ $media = new Less_Tree_Media( [], [], $this->index, $this->currentFileInfo );
$strictMathBypass = false;
- if( Less_Parser::$options['strictMath'] === false) {
+ if ( Less_Parser::$options['strictMath'] === false ) {
$strictMathBypass = true;
Less_Parser::$options['strictMath'] = true;
}
- $media->features = $this->features->compile($env);
+ $media->features = $this->features->compile( $env );
- if( $strictMathBypass ){
+ if ( $strictMathBypass ) {
Less_Parser::$options['strictMath'] = false;
}
$env->mediaPath[] = $media;
$env->mediaBlocks[] = $media;
- array_unshift($env->frames, $this->rules[0]);
- $media->rules = array($this->rules[0]->compile($env));
- array_shift($env->frames);
+ array_unshift( $env->frames, $this->rules[0] );
+ $media->rules = [ $this->rules[0]->compile( $env ) ];
+ array_shift( $env->frames );
- array_pop($env->mediaPath);
+ array_pop( $env->mediaPath );
- return !$env->mediaPath ? $media->compileTop($env) : $media->compileNested($env);
+ return !$env->mediaPath ? $media->compileTop( $env ) : $media->compileNested( $env );
}
- public function variable($name) {
- return $this->rules[0]->variable($name);
+ public function variable( $name ) {
+ return $this->rules[0]->variable( $name );
}
- public function find($selector) {
- return $this->rules[0]->find($selector, $this);
+ public function find( $selector ) {
+ return $this->rules[0]->find( $selector, $this );
}
- public function emptySelectors(){
- $el = new Less_Tree_Element('','&', $this->index, $this->currentFileInfo );
- $sels = array( new Less_Tree_Selector(array($el), array(), null, $this->index, $this->currentFileInfo) );
+ public function emptySelectors() {
+ $el = new Less_Tree_Element( '', '&', $this->index, $this->currentFileInfo );
+ $sels = [ new Less_Tree_Selector( [ $el ], [], null, $this->index, $this->currentFileInfo ) ];
$sels[0]->mediaEmpty = true;
- return $sels;
+ return $sels;
}
- public function markReferenced(){
+ public function markReferenced() {
$this->rules[0]->markReferenced();
$this->isReferenced = true;
- Less_Tree::ReferencedArray($this->rules[0]->rules);
+ Less_Tree::ReferencedArray( $this->rules[0]->rules );
}
// evaltop
- public function compileTop($env) {
+ public function compileTop( $env ) {
$result = $this;
- if (count($env->mediaBlocks) > 1) {
+ if ( count( $env->mediaBlocks ) > 1 ) {
$selectors = $this->emptySelectors();
- $result = new Less_Tree_Ruleset($selectors, $env->mediaBlocks);
+ $result = new Less_Tree_Ruleset( $selectors, $env->mediaBlocks );
$result->multiMedia = true;
}
- $env->mediaBlocks = array();
- $env->mediaPath = array();
+ $env->mediaBlocks = [];
+ $env->mediaPath = [];
return $result;
}
- public function compileNested($env) {
- $path = array_merge($env->mediaPath, array($this));
+ /**
+ * @param Less_Environment $env
+ * @return Less_Tree_Ruleset
+ */
+ public function compileNested( $env ) {
+ $path = array_merge( $env->mediaPath, [ $this ] );
+ '@phan-var array $path';
// Extract the media-query conditions separated with `,` (OR).
- foreach ($path as $key => $p) {
+ foreach ( $path as $key => $p ) {
$value = $p->features instanceof Less_Tree_Value ? $p->features->value : $p->features;
- $path[$key] = is_array($value) ? $value : array($value);
+ $path[$key] = is_array( $value ) ? $value : [ $value ];
}
+ '@phan-var array> $path';
// Trace all permutations to generate the resulting media-query.
//
@@ -126,42 +129,42 @@ class Less_Tree_Media extends Less_Tree{
// b and c and d
// b and c and e
- $permuted = $this->permute($path);
- $expressions = array();
- foreach($permuted as $path){
+ $permuted = $this->permute( $path );
+ $expressions = [];
+ foreach ( $permuted as $path ) {
- for( $i=0, $len=count($path); $i < $len; $i++){
- $path[$i] = Less_Parser::is_method($path[$i], 'toCSS') ? $path[$i] : new Less_Tree_Anonymous($path[$i]);
+ for ( $i = 0, $len = count( $path ); $i < $len; $i++ ) {
+ $path[$i] = Less_Parser::is_method( $path[$i], 'toCSS' ) ? $path[$i] : new Less_Tree_Anonymous( $path[$i] );
}
- for( $i = count($path) - 1; $i > 0; $i-- ){
- array_splice($path, $i, 0, array(new Less_Tree_Anonymous('and')));
+ for ( $i = count( $path ) - 1; $i > 0; $i-- ) {
+ array_splice( $path, $i, 0, [ new Less_Tree_Anonymous( 'and' ) ] );
}
- $expressions[] = new Less_Tree_Expression($path);
+ $expressions[] = new Less_Tree_Expression( $path );
}
- $this->features = new Less_Tree_Value($expressions);
-
-
+ $this->features = new Less_Tree_Value( $expressions );
// Fake a tree-node that doesn't output anything.
- return new Less_Tree_Ruleset(array(), array());
+ return new Less_Tree_Ruleset( [], [] );
}
- public function permute($arr) {
- if (!$arr)
- return array();
+ public function permute( $arr ) {
+ if ( !$arr ) {
+ return [];
+ }
- if (count($arr) == 1)
+ if ( count( $arr ) == 1 ) {
return $arr[0];
+ }
- $result = array();
- $rest = $this->permute(array_slice($arr, 1));
- foreach ($rest as $r) {
- foreach ($arr[0] as $a) {
+ $result = [];
+ $rest = $this->permute( array_slice( $arr, 1 ) );
+ foreach ( $rest as $r ) {
+ foreach ( $arr[0] as $a ) {
$result[] = array_merge(
- is_array($a) ? $a : array($a),
- is_array($r) ? $r : array($r)
+ is_array( $a ) ? $a : [ $a ],
+ is_array( $r ) ? $r : [ $r ]
);
}
}
@@ -169,11 +172,12 @@ class Less_Tree_Media extends Less_Tree{
return $result;
}
- public function bubbleSelectors($selectors) {
+ public function bubbleSelectors( $selectors ) {
+ if ( !$selectors ) {
+ return;
+ }
- if( !$selectors) return;
-
- $this->rules = array(new Less_Tree_Ruleset( $selectors, array($this->rules[0])));
+ $this->rules = [ new Less_Tree_Ruleset( $selectors, [ $this->rules[0] ] ) ];
}
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Mixin/Call.php b/vendor/wikimedia/less.php/lib/Less/Tree/Mixin/Call.php
index 04eb426d9..61e10fefb 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Mixin/Call.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Mixin/Call.php
@@ -1,7 +1,8 @@
selector = new Less_Tree_Selector($elements);
+ public function __construct( $elements, $args, $index, $currentFileInfo, $important = false ) {
+ $this->selector = new Less_Tree_Selector( $elements );
$this->arguments = $args;
$this->index = $index;
$this->currentFileInfo = $currentFileInfo;
$this->important = $important;
}
- //function accept($visitor){
+ // function accept($visitor){
// $this->selector = $visitor->visit($this->selector);
// $this->arguments = $visitor->visit($this->arguments);
//}
-
- public function compile($env){
-
- $rules = array();
+ public function compile( $env ) {
+ $rules = [];
$match = false;
$isOneFound = false;
- $candidates = array();
+ $candidates = [];
$defaultUsed = false;
- $conditionResult = array();
+ $conditionResult = [];
- $args = array();
- foreach($this->arguments as $a){
- $args[] = array('name'=> $a['name'], 'value' => $a['value']->compile($env) );
+ $args = [];
+ foreach ( $this->arguments as $a ) {
+ $args[] = [ 'name' => $a['name'], 'value' => $a['value']->compile( $env ) ];
}
- foreach($env->frames as $frame){
+ foreach ( $env->frames as $frame ) {
- $mixins = $frame->find($this->selector);
+ $mixins = $frame->find( $this->selector );
- if( !$mixins ){
+ if ( !$mixins ) {
continue;
}
@@ -61,32 +60,35 @@ class Less_Tree_Mixin_Call extends Less_Tree{
// and build candidate list with corresponding flags. Then, when we know all possible matches,
// we make a final decision.
- $mixins_len = count($mixins);
- for( $m = 0; $m < $mixins_len; $m++ ){
+ $mixins_len = count( $mixins );
+ for ( $m = 0; $m < $mixins_len; $m++ ) {
$mixin = $mixins[$m];
- if( $this->IsRecursive( $env, $mixin ) ){
+ if ( $this->IsRecursive( $env, $mixin ) ) {
continue;
}
- if( $mixin->matchArgs($args, $env) ){
+ if ( $mixin->matchArgs( $args, $env ) ) {
- $candidate = array('mixin' => $mixin, 'group' => $defNone);
+ $candidate = [ 'mixin' => $mixin, 'group' => $defNone ];
- if( $mixin instanceof Less_Tree_Ruleset ){
-
- for( $f = 0; $f < 2; $f++ ){
- Less_Tree_DefaultFunc::value($f);
- $conditionResult[$f] = $mixin->matchCondition( $args, $env);
+ if ( $mixin instanceof Less_Tree_Ruleset ) {
+ for ( $f = 0; $f < 2; $f++ ) {
+ Less_Tree_DefaultFunc::value( $f );
+ $conditionResult[$f] = $mixin->matchCondition( $args, $env );
}
- if( $conditionResult[0] || $conditionResult[1] ){
- if( $conditionResult[0] != $conditionResult[1] ){
+
+ // PhanTypeInvalidDimOffset -- False positive
+ '@phan-var array{0:bool,1:bool} $conditionResult';
+
+ if ( $conditionResult[0] || $conditionResult[1] ) {
+ if ( $conditionResult[0] != $conditionResult[1] ) {
$candidate['group'] = $conditionResult[1] ? $defTrue : $defFalse;
}
$candidates[] = $candidate;
}
- }else{
+ } else {
$candidates[] = $candidate;
}
@@ -96,99 +98,94 @@ class Less_Tree_Mixin_Call extends Less_Tree{
Less_Tree_DefaultFunc::reset();
-
- $count = array(0, 0, 0);
- for( $m = 0; $m < count($candidates); $m++ ){
+ $count = [ 0, 0, 0 ];
+ for ( $m = 0; $m < count( $candidates ); $m++ ) {
$count[ $candidates[$m]['group'] ]++;
}
- if( $count[$defNone] > 0 ){
+ if ( $count[$defNone] > 0 ) {
$defaultResult = $defFalse;
} else {
$defaultResult = $defTrue;
- if( ($count[$defTrue] + $count[$defFalse]) > 1 ){
- throw new Exception( 'Ambiguous use of `default()` found when matching for `' . $this->format($args) . '`' );
+ if ( ( $count[$defTrue] + $count[$defFalse] ) > 1 ) {
+ throw new Exception( 'Ambiguous use of `default()` found when matching for `' . $this->format( $args ) . '`' );
}
}
+ $candidates_length = count( $candidates );
+ $length_1 = ( $candidates_length == 1 );
- $candidates_length = count($candidates);
- $length_1 = ($candidates_length == 1);
-
- for( $m = 0; $m < $candidates_length; $m++){
+ for ( $m = 0; $m < $candidates_length; $m++ ) {
$candidate = $candidates[$m]['group'];
- if( ($candidate === $defNone) || ($candidate === $defaultResult) ){
+ if ( ( $candidate === $defNone ) || ( $candidate === $defaultResult ) ) {
try{
$mixin = $candidates[$m]['mixin'];
- if( !($mixin instanceof Less_Tree_Mixin_Definition) ){
- $mixin = new Less_Tree_Mixin_Definition('', array(), $mixin->rules, null, false);
+ if ( !( $mixin instanceof Less_Tree_Mixin_Definition ) ) {
+ $mixin = new Less_Tree_Mixin_Definition( '', [], $mixin->rules, null, false );
$mixin->originalRuleset = $mixins[$m]->originalRuleset;
}
- $rules = array_merge($rules, $mixin->evalCall($env, $args, $this->important)->rules);
- } catch (Exception $e) {
- //throw new Less_Exception_Compiler($e->getMessage(), $e->index, null, $this->currentFileInfo['filename']);
- throw new Less_Exception_Compiler($e->getMessage(), null, null, $this->currentFileInfo);
+ $rules = array_merge( $rules, $mixin->evalCall( $env, $args, $this->important )->rules );
+ } catch ( Exception $e ) {
+ // throw new Less_Exception_Compiler($e->getMessage(), $e->index, null, $this->currentFileInfo['filename']);
+ throw new Less_Exception_Compiler( $e->getMessage(), null, null, $this->currentFileInfo );
}
}
}
- if( $match ){
- if( !$this->currentFileInfo || !isset($this->currentFileInfo['reference']) || !$this->currentFileInfo['reference'] ){
- Less_Tree::ReferencedArray($rules);
+ if ( $match ) {
+ if ( !$this->currentFileInfo || !isset( $this->currentFileInfo['reference'] ) || !$this->currentFileInfo['reference'] ) {
+ Less_Tree::ReferencedArray( $rules );
}
return $rules;
}
}
- if( $isOneFound ){
- throw new Less_Exception_Compiler('No matching definition was found for `'.$this->Format( $args ).'`', null, $this->index, $this->currentFileInfo);
+ if ( $isOneFound ) {
+ throw new Less_Exception_Compiler( 'No matching definition was found for `' . $this->Format( $args ) . '`', null, $this->index, $this->currentFileInfo );
- }else{
- throw new Less_Exception_Compiler(trim($this->selector->toCSS()) . " is undefined in ".$this->currentFileInfo['filename'], null, $this->index);
+ } else {
+ throw new Less_Exception_Compiler( trim( $this->selector->toCSS() ) . " is undefined in " . $this->currentFileInfo['filename'], null, $this->index );
}
-
}
/**
* Format the args for use in exception messages
*
*/
- private function Format($args){
- $message = array();
- if( $args ){
- foreach($args as $a){
+ private function Format( $args ) {
+ $message = [];
+ if ( $args ) {
+ foreach ( $args as $a ) {
$argValue = '';
- if( $a['name'] ){
+ if ( $a['name'] ) {
$argValue .= $a['name'] . ':';
}
- if( is_object($a['value']) ){
+ if ( is_object( $a['value'] ) ) {
$argValue .= $a['value']->toCSS();
- }else{
+ } else {
$argValue .= '???';
}
$message[] = $argValue;
}
}
- return implode(', ',$message);
+ return implode( ', ', $message );
}
-
/**
* Are we in a recursive mixin call?
*
* @return bool
*/
- private function IsRecursive( $env, $mixin ){
+ private function IsRecursive( $env, $mixin ) {
+ foreach ( $env->frames as $recur_frame ) {
+ if ( !( $mixin instanceof Less_Tree_Mixin_Definition ) ) {
- foreach($env->frames as $recur_frame){
- if( !($mixin instanceof Less_Tree_Mixin_Definition) ){
-
- if( $mixin === $recur_frame ){
+ if ( $mixin === $recur_frame ) {
return true;
}
- if( isset($recur_frame->originalRuleset) && $mixin->ruleset_id === $recur_frame->originalRuleset ){
+ if ( isset( $recur_frame->originalRuleset ) && $mixin->ruleset_id === $recur_frame->originalRuleset ) {
return true;
}
}
@@ -198,5 +195,3 @@ class Less_Tree_Mixin_Call extends Less_Tree{
}
}
-
-
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Mixin/Definition.php b/vendor/wikimedia/less.php/lib/Less/Tree/Mixin/Definition.php
index b16d68871..08bcd7af2 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Mixin/Definition.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Mixin/Definition.php
@@ -1,33 +1,34 @@
name = $name;
- $this->selectors = array(new Less_Tree_Selector(array( new Less_Tree_Element(null, $name))));
+ $this->selectors = [ new Less_Tree_Selector( [ new Less_Tree_Element( null, $name ) ] ) ];
$this->params = $params;
$this->condition = $condition;
$this->variadic = $variadic;
$this->rules = $rules;
- if( $params ){
- $this->arity = count($params);
- foreach( $params as $p ){
- if (! isset($p['name']) || ($p['name'] && !isset($p['value']))) {
+ if ( $params ) {
+ $this->arity = count( $params );
+ foreach ( $params as $p ) {
+ if ( !isset( $p['name'] ) || ( $p['name'] && !isset( $p['value'] ) ) ) {
$this->required++;
}
}
@@ -37,144 +38,139 @@ class Less_Tree_Mixin_Definition extends Less_Tree_Ruleset{
$this->SetRulesetIndex();
}
-
-
- //function accept( $visitor ){
+ // function accept( $visitor ){
// $this->params = $visitor->visit($this->params);
// $this->rules = $visitor->visit($this->rules);
// $this->condition = $visitor->visit($this->condition);
//}
-
- public function toCSS(){
+ public function toCSS() {
return '';
}
// less.js : /lib/less/tree/mixin.js : tree.mixin.Definition.evalParams
- public function compileParams($env, $mixinFrames, $args = array() , &$evaldArguments = array() ){
- $frame = new Less_Tree_Ruleset(null, array());
+ public function compileParams( $env, $mixinFrames, $args = [], &$evaldArguments = [] ) {
+ $frame = new Less_Tree_Ruleset( null, [] );
$params = $this->params;
$mixinEnv = null;
$argsLength = 0;
- if( $args ){
- $argsLength = count($args);
- for($i = 0; $i < $argsLength; $i++ ){
+ if ( $args ) {
+ $argsLength = count( $args );
+ for ( $i = 0; $i < $argsLength; $i++ ) {
$arg = $args[$i];
- if( $arg && $arg['name'] ){
+ if ( $arg && $arg['name'] ) {
$isNamedFound = false;
- foreach($params as $j => $param){
- if( !isset($evaldArguments[$j]) && $arg['name'] === $params[$j]['name']) {
- $evaldArguments[$j] = $arg['value']->compile($env);
- array_unshift($frame->rules, new Less_Tree_Rule( $arg['name'], $arg['value']->compile($env) ) );
+ foreach ( $params as $j => $param ) {
+ if ( !isset( $evaldArguments[$j] ) && $arg['name'] === $params[$j]['name'] ) {
+ $evaldArguments[$j] = $arg['value']->compile( $env );
+ array_unshift( $frame->rules, new Less_Tree_Rule( $arg['name'], $arg['value']->compile( $env ) ) );
$isNamedFound = true;
break;
}
}
- if ($isNamedFound) {
- array_splice($args, $i, 1);
+ if ( $isNamedFound ) {
+ array_splice( $args, $i, 1 );
$i--;
$argsLength--;
continue;
} else {
- throw new Less_Exception_Compiler("Named argument for " . $this->name .' '.$args[$i]['name'] . ' not found');
+ throw new Less_Exception_Compiler( "Named argument for " . $this->name . ' ' . $args[$i]['name'] . ' not found' );
}
}
}
}
$argIndex = 0;
- foreach($params as $i => $param){
+ foreach ( $params as $i => $param ) {
- if ( isset($evaldArguments[$i]) ){ continue; }
+ if ( isset( $evaldArguments[$i] ) ) { continue;
+ }
$arg = null;
- if( isset($args[$argIndex]) ){
+ if ( isset( $args[$argIndex] ) ) {
$arg = $args[$argIndex];
}
- if (isset($param['name']) && $param['name']) {
+ if ( isset( $param['name'] ) && $param['name'] ) {
- if( isset($param['variadic']) ){
- $varargs = array();
- for ($j = $argIndex; $j < $argsLength; $j++) {
- $varargs[] = $args[$j]['value']->compile($env);
+ if ( isset( $param['variadic'] ) ) {
+ $varargs = [];
+ for ( $j = $argIndex; $j < $argsLength; $j++ ) {
+ $varargs[] = $args[$j]['value']->compile( $env );
}
- $expression = new Less_Tree_Expression($varargs);
- array_unshift($frame->rules, new Less_Tree_Rule($param['name'], $expression->compile($env)));
- }else{
- $val = ($arg && $arg['value']) ? $arg['value'] : false;
+ $expression = new Less_Tree_Expression( $varargs );
+ array_unshift( $frame->rules, new Less_Tree_Rule( $param['name'], $expression->compile( $env ) ) );
+ } else {
+ $val = ( $arg && $arg['value'] ) ? $arg['value'] : false;
- if ($val) {
- $val = $val->compile($env);
- } else if ( isset($param['value']) ) {
+ if ( $val ) {
+ $val = $val->compile( $env );
+ } elseif ( isset( $param['value'] ) ) {
- if( !$mixinEnv ){
+ if ( !$mixinEnv ) {
$mixinEnv = new Less_Environment();
- $mixinEnv->frames = array_merge( array($frame), $mixinFrames);
+ $mixinEnv->frames = array_merge( [ $frame ], $mixinFrames );
}
- $val = $param['value']->compile($mixinEnv);
+ $val = $param['value']->compile( $mixinEnv );
$frame->resetCache();
} else {
- throw new Less_Exception_Compiler("Wrong number of arguments for " . $this->name . " (" . $argsLength . ' for ' . $this->arity . ")");
+ throw new Less_Exception_Compiler( "Wrong number of arguments for " . $this->name . " (" . $argsLength . ' for ' . $this->arity . ")" );
}
- array_unshift($frame->rules, new Less_Tree_Rule($param['name'], $val));
+ array_unshift( $frame->rules, new Less_Tree_Rule( $param['name'], $val ) );
$evaldArguments[$i] = $val;
}
}
- if ( isset($param['variadic']) && $args) {
- for ($j = $argIndex; $j < $argsLength; $j++) {
- $evaldArguments[$j] = $args[$j]['value']->compile($env);
+ if ( isset( $param['variadic'] ) && $args ) {
+ for ( $j = $argIndex; $j < $argsLength; $j++ ) {
+ $evaldArguments[$j] = $args[$j]['value']->compile( $env );
}
}
$argIndex++;
}
- ksort($evaldArguments);
- $evaldArguments = array_values($evaldArguments);
+ ksort( $evaldArguments );
+ $evaldArguments = array_values( $evaldArguments );
return $frame;
}
- public function compile($env) {
- if( $this->frames ){
- return new Less_Tree_Mixin_Definition($this->name, $this->params, $this->rules, $this->condition, $this->variadic, $this->frames );
+ public function compile( $env ) {
+ if ( $this->frames ) {
+ return new Less_Tree_Mixin_Definition( $this->name, $this->params, $this->rules, $this->condition, $this->variadic, $this->frames );
}
- return new Less_Tree_Mixin_Definition($this->name, $this->params, $this->rules, $this->condition, $this->variadic, $env->frames );
+ return new Less_Tree_Mixin_Definition( $this->name, $this->params, $this->rules, $this->condition, $this->variadic, $env->frames );
}
- public function evalCall($env, $args = NULL, $important = NULL) {
-
+ public function evalCall( $env, $args = null, $important = null ) {
Less_Environment::$mixin_stack++;
- $_arguments = array();
+ $_arguments = [];
- if( $this->frames ){
- $mixinFrames = array_merge($this->frames, $env->frames);
- }else{
+ if ( $this->frames ) {
+ $mixinFrames = array_merge( $this->frames, $env->frames );
+ } else {
$mixinFrames = $env->frames;
}
- $frame = $this->compileParams($env, $mixinFrames, $args, $_arguments);
+ $frame = $this->compileParams( $env, $mixinFrames, $args, $_arguments );
- $ex = new Less_Tree_Expression($_arguments);
- array_unshift($frame->rules, new Less_Tree_Rule('@arguments', $ex->compile($env)));
+ $ex = new Less_Tree_Expression( $_arguments );
+ array_unshift( $frame->rules, new Less_Tree_Rule( '@arguments', $ex->compile( $env ) ) );
-
- $ruleset = new Less_Tree_Ruleset(null, $this->rules);
+ $ruleset = new Less_Tree_Ruleset( null, $this->rules );
$ruleset->originalRuleset = $this->ruleset_id;
-
$ruleSetEnv = new Less_Environment();
- $ruleSetEnv->frames = array_merge( array($this, $frame), $mixinFrames );
+ $ruleSetEnv->frames = array_merge( [ $this, $frame ], $mixinFrames );
$ruleset = $ruleset->compile( $ruleSetEnv );
- if( $important ){
+ if ( $important ) {
$ruleset = $ruleset->makeImportant();
}
@@ -183,53 +179,52 @@ class Less_Tree_Mixin_Definition extends Less_Tree_Ruleset{
return $ruleset;
}
-
- public function matchCondition($args, $env) {
-
- if( !$this->condition ){
+ /** @return bool */
+ public function matchCondition( $args, $env ) {
+ if ( !$this->condition ) {
return true;
}
// set array to prevent error on array_merge
- if(!is_array($this->frames)) {
- $this->frames = array();
- }
+ if ( !is_array( $this->frames ) ) {
+ $this->frames = [];
+ }
- $frame = $this->compileParams($env, array_merge($this->frames,$env->frames), $args );
+ $frame = $this->compileParams( $env, array_merge( $this->frames, $env->frames ), $args );
$compile_env = new Less_Environment();
$compile_env->frames = array_merge(
- array($frame) // the parameter variables
- , $this->frames // the parent namespace/mixin frames
- , $env->frames // the current environment frames
+ [ $frame ], // the parameter variables
+ $this->frames, // the parent namespace/mixin frames
+ $env->frames // the current environment frames
);
$compile_env->functions = $env->functions;
- return (bool)$this->condition->compile($compile_env);
+ return (bool)$this->condition->compile( $compile_env );
}
- public function matchArgs($args, $env = NULL){
- $argsLength = count($args);
+ public function matchArgs( $args, $env = null ) {
+ $argsLength = count( $args );
- if( !$this->variadic ){
- if( $argsLength < $this->required ){
+ if ( !$this->variadic ) {
+ if ( $argsLength < $this->required ) {
return false;
}
- if( $argsLength > count($this->params) ){
+ if ( $argsLength > count( $this->params ) ) {
return false;
}
- }else{
- if( $argsLength < ($this->required - 1)){
+ } else {
+ if ( $argsLength < ( $this->required - 1 ) ) {
return false;
}
}
- $len = min($argsLength, $this->arity);
+ $len = min( $argsLength, $this->arity );
- for( $i = 0; $i < $len; $i++ ){
- if( !isset($this->params[$i]['name']) && !isset($this->params[$i]['variadic']) ){
- if( $args[$i]['value']->compile($env)->toCSS() != $this->params[$i]['value']->compile($env)->toCSS() ){
+ for ( $i = 0; $i < $len; $i++ ) {
+ if ( !isset( $this->params[$i]['name'] ) && !isset( $this->params[$i]['variadic'] ) ) {
+ if ( $args[$i]['value']->compile( $env )->toCSS() != $this->params[$i]['value']->compile( $env )->toCSS() ) {
return false;
}
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/NameValue.php b/vendor/wikimedia/less.php/lib/Less/Tree/NameValue.php
index 31cbe03ed..88a229641 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/NameValue.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/NameValue.php
@@ -1,16 +1,16 @@
color:#FF0000;
+ * In bootstrap, there are about 600-1000 simple name-value pairs (depending on
+ * how forgiving the match is) -vs- 6,020 dynamic rules (Less_Tree_Rule).
*
- * @package Less
- * @subpackage tree
+ * Using the name-value object can speed up bootstrap compilation slightly, but
+ * it breaks color keyword interpretation: `color: red` -> `color: #FF0000`.
+ *
+ * @private
*/
-class Less_Tree_NameValue extends Less_Tree{
+class Less_Tree_NameValue extends Less_Tree {
public $name;
public $value;
@@ -19,33 +19,31 @@ class Less_Tree_NameValue extends Less_Tree{
public $type = 'NameValue';
public $important = '';
- public function __construct($name, $value = null, $index = null, $currentFileInfo = null ){
+ public function __construct( $name, $value = null, $index = null, $currentFileInfo = null ) {
$this->name = $name;
$this->value = $value;
$this->index = $index;
$this->currentFileInfo = $currentFileInfo;
}
- public function genCSS( $output ){
-
+ public function genCSS( $output ) {
$output->add(
$this->name
. Less_Environment::$_outputMap[': ']
. $this->value
. $this->important
- . (((Less_Environment::$lastRule && Less_Parser::$options['compress'])) ? "" : ";")
- , $this->currentFileInfo, $this->index);
+ . ( ( ( Less_Environment::$lastRule && Less_Parser::$options['compress'] ) ) ? "" : ";" ),
+ $this->currentFileInfo, $this->index );
}
- public function compile ($env){
+ public function compile( $env ) {
return $this;
}
- public function makeImportant(){
- $new = new Less_Tree_NameValue($this->name, $this->value, $this->index, $this->currentFileInfo);
+ public function makeImportant() {
+ $new = new Less_Tree_NameValue( $this->name, $this->value, $this->index, $this->currentFileInfo );
$new->important = ' !important';
return $new;
}
-
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Negative.php b/vendor/wikimedia/less.php/lib/Less/Tree/Negative.php
index 507443ecf..516f1ee7c 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Negative.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Negative.php
@@ -1,37 +1,33 @@
value = $node;
}
- //function accept($visitor) {
+ // function accept($visitor) {
// $this->value = $visitor->visit($this->value);
//}
- /**
- * @see Less_Tree::genCSS
- */
- public function genCSS( $output ){
+ /**
+ * @see Less_Tree::genCSS
+ */
+ public function genCSS( $output ) {
$output->add( '-' );
$this->value->genCSS( $output );
}
- public function compile($env) {
- if( Less_Environment::isMathOn() ){
- $ret = new Less_Tree_Operation('*', array( new Less_Tree_Dimension(-1), $this->value ) );
- return $ret->compile($env);
+ public function compile( $env ) {
+ if ( Less_Environment::isMathOn() ) {
+ $ret = new Less_Tree_Operation( '*', [ new Less_Tree_Dimension( -1 ), $this->value ] );
+ return $ret->compile( $env );
}
- return new Less_Tree_Negative( $this->value->compile($env) );
+ return new Less_Tree_Negative( $this->value->compile( $env ) );
}
-}
\ No newline at end of file
+}
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Operation.php b/vendor/wikimedia/less.php/lib/Less/Tree/Operation.php
index e69e0da6e..4d79dc0ba 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Operation.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Operation.php
@@ -1,12 +1,8 @@
op = trim($op);
+ public function __construct( $op, $operands, $isSpaced = false ) {
+ $this->op = trim( $op );
$this->operands = $operands;
$this->isSpaced = $isSpaced;
}
- public function accept($visitor) {
- $this->operands = $visitor->visitArray($this->operands);
+ public function accept( $visitor ) {
+ $this->operands = $visitor->visitArray( $this->operands );
}
- public function compile($env){
- $a = $this->operands[0]->compile($env);
- $b = $this->operands[1]->compile($env);
+ public function compile( $env ) {
+ $a = $this->operands[0]->compile( $env );
+ $b = $this->operands[1]->compile( $env );
+ if ( Less_Environment::isMathOn() ) {
- if( Less_Environment::isMathOn() ){
-
- if( $a instanceof Less_Tree_Dimension && $b instanceof Less_Tree_Color ){
+ if ( $a instanceof Less_Tree_Dimension && $b instanceof Less_Tree_Color ) {
$a = $a->toColor();
- }elseif( $b instanceof Less_Tree_Dimension && $a instanceof Less_Tree_Color ){
+ } elseif ( $b instanceof Less_Tree_Dimension && $a instanceof Less_Tree_Color ) {
$b = $b->toColor();
}
- if( !method_exists($a,'operate') ){
- throw new Less_Exception_Compiler("Operation on an invalid type");
+ if ( !method_exists( $a, 'operate' ) ) {
+ throw new Less_Exception_Compiler( "Operation on an invalid type" );
}
- return $a->operate( $this->op, $b);
+ return $a->operate( $this->op, $b );
}
- return new Less_Tree_Operation($this->op, array($a, $b), $this->isSpaced );
+ return new Less_Tree_Operation( $this->op, [ $a, $b ], $this->isSpaced );
}
-
- /**
- * @see Less_Tree::genCSS
- */
- public function genCSS( $output ){
+ /**
+ * @see Less_Tree::genCSS
+ */
+ public function genCSS( $output ) {
$this->operands[0]->genCSS( $output );
- if( $this->isSpaced ){
+ if ( $this->isSpaced ) {
$output->add( " " );
}
$output->add( $this->op );
- if( $this->isSpaced ){
+ if ( $this->isSpaced ) {
$output->add( ' ' );
}
$this->operands[1]->genCSS( $output );
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Paren.php b/vendor/wikimedia/less.php/lib/Less/Tree/Paren.php
index 01864550a..d659b84c2 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Paren.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Paren.php
@@ -1,35 +1,35 @@
value = $value;
}
- public function accept($visitor){
- $this->value = $visitor->visitObj($this->value);
+ public function accept( $visitor ) {
+ $this->value = $visitor->visitObj( $this->value );
}
- /**
- * @see Less_Tree::genCSS
- */
- public function genCSS( $output ){
+ /**
+ * @see Less_Tree::genCSS
+ */
+ public function genCSS( $output ) {
$output->add( '(' );
$this->value->genCSS( $output );
$output->add( ')' );
}
- public function compile($env) {
- return new Less_Tree_Paren($this->value->compile($env));
+ public function compile( $env ) {
+ return new Less_Tree_Paren( $this->value->compile( $env ) );
}
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Quoted.php b/vendor/wikimedia/less.php/lib/Less/Tree/Quoted.php
index 80063b5ef..0c5e190a6 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Quoted.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Quoted.php
@@ -1,12 +1,8 @@
escaped = $escaped;
$this->value = $content;
- if( $str ){
+ if ( $str ) {
$this->quote = $str[0];
}
$this->index = $index;
$this->currentFileInfo = $currentFileInfo;
}
- /**
- * @see Less_Tree::genCSS
- */
- public function genCSS( $output ){
- if( !$this->escaped ){
+ /**
+ * @see Less_Tree::genCSS
+ */
+ public function genCSS( $output ) {
+ if ( !$this->escaped ) {
$output->add( $this->quote, $this->currentFileInfo, $this->index );
- }
- $output->add( $this->value );
- if( !$this->escaped ){
+ }
+ $output->add( $this->value );
+ if ( !$this->escaped ) {
$output->add( $this->quote );
- }
- }
-
- public function compile($env){
-
- $value = $this->value;
- if( preg_match_all('/`([^`]+)`/', $this->value, $matches) ){
- foreach($matches as $i => $match){
- $js = new Less_Tree_JavaScript($matches[1], $this->index, true);
- $js = $js->compile()->value;
- $value = str_replace($matches[0][$i], $js, $value);
- }
}
-
- if( preg_match_all('/@\{([\w-]+)\}/',$value,$matches) ){
- foreach($matches[1] as $i => $match){
- $v = new Less_Tree_Variable('@' . $match, $this->index, $this->currentFileInfo );
- $v = $v->compile($env);
- $v = ($v instanceof Less_Tree_Quoted) ? $v->value : $v->toCSS();
- $value = str_replace($matches[0][$i], $v, $value);
- }
- }
-
- return new Less_Tree_Quoted($this->quote . $value . $this->quote, $value, $this->escaped, $this->index, $this->currentFileInfo);
}
- public function compare($x) {
+ public function compile( $env ) {
+ $value = $this->value;
+ if ( preg_match_all( '/`([^`]+)`/', $this->value, $matches ) ) {
+ foreach ( $matches as $i => $match ) {
+ $js = new Less_Tree_JavaScript( $matches[1], $this->index, true );
+ $js = $js->compile( $env )->value;
+ $value = str_replace( $matches[0][$i], $js, $value );
+ }
+ }
- if( !Less_Parser::is_method($x, 'toCSS') ){
+ if ( preg_match_all( '/@\{([\w-]+)\}/', $value, $matches ) ) {
+ foreach ( $matches[1] as $i => $match ) {
+ $v = new Less_Tree_Variable( '@' . $match, $this->index, $this->currentFileInfo );
+ $v = $v->compile( $env );
+ $v = ( $v instanceof Less_Tree_Quoted ) ? $v->value : $v->toCSS();
+ $value = str_replace( $matches[0][$i], $v, $value );
+ }
+ }
+
+ return new Less_Tree_Quoted( $this->quote . $value . $this->quote, $value, $this->escaped, $this->index, $this->currentFileInfo );
+ }
+
+ public function compare( $x ) {
+ if ( !Less_Parser::is_method( $x, 'toCSS' ) ) {
return -1;
}
$left = $this->toCSS();
$right = $x->toCSS();
- if ($left === $right) {
+ if ( $left === $right ) {
return 0;
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Rule.php b/vendor/wikimedia/less.php/lib/Less/Tree/Rule.php
index ee4a9e257..842ad0cc0 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Rule.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Rule.php
@@ -1,14 +1,11 @@
name = $name;
- $this->value = ($value instanceof Less_Tree_Value || $value instanceof Less_Tree_Ruleset) ? $value : new Less_Tree_Value(array($value));
- $this->important = $important ? ' ' . trim($important) : '';
+ $this->value = ( $value instanceof Less_Tree )
+ ? $value
+ : new Less_Tree_Value( [ $value ] );
+ $this->important = $important ? ' ' . trim( $important ) : '';
$this->merge = $merge;
$this->index = $index;
$this->currentFileInfo = $currentFileInfo;
$this->inline = $inline;
- $this->variable = ( is_string($name) && $name[0] === '@');
+ $this->variable = ( is_string( $name ) && $name[0] === '@' );
}
- public function accept($visitor) {
+ public function accept( $visitor ) {
$this->value = $visitor->visitObj( $this->value );
}
- /**
- * @see Less_Tree::genCSS
- */
- public function genCSS( $output ){
-
- $output->add( $this->name . Less_Environment::$_outputMap[': '], $this->currentFileInfo, $this->index);
+ /**
+ * @see Less_Tree::genCSS
+ */
+ public function genCSS( $output ) {
+ $output->add( $this->name . Less_Environment::$_outputMap[': '], $this->currentFileInfo, $this->index );
try{
- $this->value->genCSS( $output);
+ $this->value->genCSS( $output );
- }catch( Less_Exception_Parser $e ){
+ }catch ( Less_Exception_Parser $e ) {
$e->index = $this->index;
$e->currentFile = $this->currentFileInfo;
throw $e;
}
- $output->add( $this->important . (($this->inline || (Less_Environment::$lastRule && Less_Parser::$options['compress'])) ? "" : ";"), $this->currentFileInfo, $this->index);
+ $output->add( $this->important . ( ( $this->inline || ( Less_Environment::$lastRule && Less_Parser::$options['compress'] ) ) ? "" : ";" ), $this->currentFileInfo, $this->index );
}
- public function compile ($env){
-
+ /**
+ * @param Less_Environment $env
+ * @return Less_Tree_Rule
+ */
+ public function compile( $env ) {
$name = $this->name;
- if( is_array($name) ){
+ if ( is_array( $name ) ) {
// expand 'primitive' name directly to get
// things faster (~10% for benchmark.less):
- if( count($name) === 1 && $name[0] instanceof Less_Tree_Keyword ){
+ if ( count( $name ) === 1 && $name[0] instanceof Less_Tree_Keyword ) {
$name = $name[0]->value;
- }else{
- $name = $this->CompileName($env,$name);
+ } else {
+ $name = $this->CompileName( $env, $name );
}
}
$strictMathBypass = Less_Parser::$options['strictMath'];
- if( $name === "font" && !Less_Parser::$options['strictMath'] ){
+ if ( $name === "font" && !Less_Parser::$options['strictMath'] ) {
Less_Parser::$options['strictMath'] = true;
}
try {
- $evaldValue = $this->value->compile($env);
+ $evaldValue = $this->value->compile( $env );
- if( !$this->variable && $evaldValue->type === "DetachedRuleset") {
- throw new Less_Exception_Compiler("Rulesets cannot be evaluated on a property.", null, $this->index, $this->currentFileInfo);
+ if ( !$this->variable && $evaldValue->type === "DetachedRuleset" ) {
+ throw new Less_Exception_Compiler( "Rulesets cannot be evaluated on a property.", null, $this->index, $this->currentFileInfo );
}
- if( Less_Environment::$mixin_stack ){
- $return = new Less_Tree_Rule($name, $evaldValue, $this->important, $this->merge, $this->index, $this->currentFileInfo, $this->inline);
- }else{
+ if ( Less_Environment::$mixin_stack ) {
+ $return = new Less_Tree_Rule( $name, $evaldValue, $this->important, $this->merge, $this->index, $this->currentFileInfo, $this->inline );
+ } else {
$this->name = $name;
$this->value = $evaldValue;
$return = $this;
}
- }catch( Less_Exception_Parser $e ){
- if( !is_numeric($e->index) ){
+ } catch ( Less_Exception_Parser $e ) {
+ if ( !is_numeric( $e->index ) ) {
$e->index = $this->index;
$e->currentFile = $this->currentFileInfo;
}
@@ -99,17 +100,16 @@ class Less_Tree_Rule extends Less_Tree{
return $return;
}
-
- public function CompileName( $env, $name ){
+ public function CompileName( $env, $name ) {
$output = new Less_Output();
- foreach($name as $n){
- $n->compile($env)->genCSS($output);
+ foreach ( $name as $n ) {
+ $n->compile( $env )->genCSS( $output );
}
return $output->toString();
}
- public function makeImportant(){
- return new Less_Tree_Rule($this->name, $this->value, '!important', $this->merge, $this->index, $this->currentFileInfo, $this->inline);
+ public function makeImportant() {
+ return new Less_Tree_Rule( $this->name, $this->value, '!important', $this->merge, $this->index, $this->currentFileInfo, $this->inline );
}
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Ruleset.php b/vendor/wikimedia/less.php/lib/Less/Tree/Ruleset.php
index bdf9fec79..7acc6af8c 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Ruleset.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Ruleset.php
@@ -1,12 +1,8 @@
ruleset_id = Less_Parser::$next_id++;
$this->originalRuleset = $this->ruleset_id;
- if( $this->selectors ){
- foreach($this->selectors as $sel){
- if( $sel->_oelements ){
+ if ( $this->selectors ) {
+ foreach ( $this->selectors as $sel ) {
+ if ( $sel->_oelements ) {
$this->first_oelements[$sel->_oelements[0]] = true;
}
}
}
}
- public function __construct($selectors, $rules, $strictImports = null){
+ /**
+ * @param null|Less_Tree_Selector[] $selectors
+ * @param Less_Tree[] $rules
+ * @param null|bool $strictImports
+ */
+ public function __construct( $selectors, $rules, $strictImports = null ) {
$this->selectors = $selectors;
$this->rules = $rules;
- $this->lookups = array();
+ $this->lookups = [];
$this->strictImports = $strictImports;
$this->SetRulesetIndex();
}
- public function accept( $visitor ){
- if( $this->paths ){
- $paths_len = count($this->paths);
- for($i = 0,$paths_len; $i < $paths_len; $i++ ){
- $this->paths[$i] = $visitor->visitArray($this->paths[$i]);
+ public function accept( $visitor ) {
+ if ( $this->paths !== null ) {
+ $paths_len = count( $this->paths );
+ for ( $i = 0; $i < $paths_len; $i++ ) {
+ $this->paths[$i] = $visitor->visitArray( $this->paths[$i] );
}
- }elseif( $this->selectors ){
- $this->selectors = $visitor->visitArray($this->selectors);
+ } elseif ( $this->selectors ) {
+ $this->selectors = $visitor->visitArray( $this->selectors );
}
- if( $this->rules ){
- $this->rules = $visitor->visitArray($this->rules);
+ if ( $this->rules ) {
+ $this->rules = $visitor->visitArray( $this->rules );
}
}
- public function compile($env){
-
- $ruleset = $this->PrepareRuleset($env);
-
+ /**
+ * @param Less_Environment $env
+ * @return Less_Tree_Ruleset
+ * @see less-2.5.3.js#Ruleset.prototype.eval
+ */
+ public function compile( $env ) {
+ $ruleset = $this->PrepareRuleset( $env );
// Store the frames around mixin definitions,
// so they can be evaluated like closures when the time comes.
- $rsRuleCnt = count($ruleset->rules);
- for( $i = 0; $i < $rsRuleCnt; $i++ ){
- if( $ruleset->rules[$i] instanceof Less_Tree_Mixin_Definition || $ruleset->rules[$i] instanceof Less_Tree_DetachedRuleset ){
- $ruleset->rules[$i] = $ruleset->rules[$i]->compile($env);
+ $rsRuleCnt = count( $ruleset->rules );
+ for ( $i = 0; $i < $rsRuleCnt; $i++ ) {
+ // These checks are the equivalent of the rule.evalFirst property in less.js
+ if ( $ruleset->rules[$i] instanceof Less_Tree_Mixin_Definition || $ruleset->rules[$i] instanceof Less_Tree_DetachedRuleset ) {
+ $ruleset->rules[$i] = $ruleset->rules[$i]->compile( $env );
}
}
- $mediaBlockCount = 0;
- if( $env instanceof Less_Environment ){
- $mediaBlockCount = count($env->mediaBlocks);
- }
+ $mediaBlockCount = count( $env->mediaBlocks );
// Evaluate mixin calls.
$this->EvalMixinCalls( $ruleset, $env, $rsRuleCnt );
-
// Evaluate everything else
- for( $i=0; $i<$rsRuleCnt; $i++ ){
- if(! ($ruleset->rules[$i] instanceof Less_Tree_Mixin_Definition || $ruleset->rules[$i] instanceof Less_Tree_DetachedRuleset) ){
- $ruleset->rules[$i] = $ruleset->rules[$i]->compile($env);
+ for ( $i = 0; $i < $rsRuleCnt; $i++ ) {
+ if ( !( $ruleset->rules[$i] instanceof Less_Tree_Mixin_Definition || $ruleset->rules[$i] instanceof Less_Tree_DetachedRuleset ) ) {
+ $ruleset->rules[$i] = $ruleset->rules[$i]->compile( $env );
}
}
- // Evaluate everything else
- for( $i=0; $i<$rsRuleCnt; $i++ ){
+ // Evaluate everything else
+ for ( $i = 0; $i < $rsRuleCnt; $i++ ) {
$rule = $ruleset->rules[$i];
- // for rulesets, check if it is a css guard and can be removed
- if( $rule instanceof Less_Tree_Ruleset && $rule->selectors && count($rule->selectors) === 1 ){
+ // for rulesets, check if it is a css guard and can be removed
+ if ( $rule instanceof Less_Tree_Ruleset && $rule->selectors && count( $rule->selectors ) === 1 ) {
- // check if it can be folded in (e.g. & where)
- if( $rule->selectors[0]->isJustParentSelector() ){
- array_splice($ruleset->rules,$i--,1);
+ // check if it can be folded in (e.g. & where)
+ if ( $rule->selectors[0]->isJustParentSelector() ) {
+ array_splice( $ruleset->rules, $i--, 1 );
$rsRuleCnt--;
- for($j = 0; $j < count($rule->rules); $j++ ){
+ for ( $j = 0; $j < count( $rule->rules ); $j++ ) {
$subRule = $rule->rules[$j];
- if( !($subRule instanceof Less_Tree_Rule) || !$subRule->variable ){
- array_splice($ruleset->rules, ++$i, 0, array($subRule));
+ if ( !( $subRule instanceof Less_Tree_Rule ) || !$subRule->variable ) {
+ array_splice( $ruleset->rules, ++$i, 0, [ $subRule ] );
$rsRuleCnt++;
}
}
- }
- }
- }
-
+ }
+ }
+ }
// Pop the stack
$env->shiftFrame();
- if ($mediaBlockCount) {
- $len = count($env->mediaBlocks);
- for($i = $mediaBlockCount; $i < $len; $i++ ){
- $env->mediaBlocks[$i]->bubbleSelectors($ruleset->selectors);
+ if ( $mediaBlockCount ) {
+ $len = count( $env->mediaBlocks );
+ for ( $i = $mediaBlockCount; $i < $len; $i++ ) {
+ $env->mediaBlocks[$i]->bubbleSelectors( $ruleset->selectors );
}
}
@@ -137,71 +137,76 @@ class Less_Tree_Ruleset extends Less_Tree{
* Compile Less_Tree_Mixin_Call objects
*
* @param Less_Tree_Ruleset $ruleset
- * @param integer $rsRuleCnt
+ * @param int $rsRuleCnt
*/
- private function EvalMixinCalls( $ruleset, $env, &$rsRuleCnt ){
- for($i=0; $i < $rsRuleCnt; $i++){
+ private function EvalMixinCalls( $ruleset, $env, &$rsRuleCnt ) {
+ for ( $i = 0; $i < $rsRuleCnt; $i++ ) {
$rule = $ruleset->rules[$i];
- if( $rule instanceof Less_Tree_Mixin_Call ){
- $rule = $rule->compile($env);
+ if ( $rule instanceof Less_Tree_Mixin_Call ) {
+ $rule = $rule->compile( $env );
- $temp = array();
- foreach($rule as $r){
- if( ($r instanceof Less_Tree_Rule) && $r->variable ){
+ $temp = [];
+ foreach ( $rule as $r ) {
+ if ( ( $r instanceof Less_Tree_Rule ) && $r->variable ) {
// do not pollute the scope if the variable is
// already there. consider returning false here
// but we need a way to "return" variable from mixins
- if( !$ruleset->variable($r->name) ){
+ if ( !$ruleset->variable( $r->name ) ) {
$temp[] = $r;
}
- }else{
+ } else {
$temp[] = $r;
}
}
- $temp_count = count($temp)-1;
- array_splice($ruleset->rules, $i, 1, $temp);
+ $temp_count = count( $temp ) - 1;
+ array_splice( $ruleset->rules, $i, 1, $temp );
$rsRuleCnt += $temp_count;
$i += $temp_count;
$ruleset->resetCache();
- }elseif( $rule instanceof Less_Tree_RulesetCall ){
+ } elseif ( $rule instanceof Less_Tree_RulesetCall ) {
- $rule = $rule->compile($env);
- $rules = array();
- foreach($rule->rules as $r){
- if( ($r instanceof Less_Tree_Rule) && $r->variable ){
+ $rule = $rule->compile( $env );
+ $rules = [];
+ foreach ( $rule->rules as $r ) {
+ if ( ( $r instanceof Less_Tree_Rule ) && $r->variable ) {
continue;
}
$rules[] = $r;
}
- array_splice($ruleset->rules, $i, 1, $rules);
- $temp_count = count($rules);
+ array_splice( $ruleset->rules, $i, 1, $rules );
+ $temp_count = count( $rules );
$rsRuleCnt += $temp_count - 1;
- $i += $temp_count-1;
+ $i += $temp_count - 1;
$ruleset->resetCache();
}
}
}
-
/**
* Compile the selectors and create a new ruleset object for the compile() method
*
+ * @param Less_Environment $env
+ * @return Less_Tree_Ruleset
*/
- private function PrepareRuleset($env){
-
+ private function PrepareRuleset( $env ) {
+ // NOTE: Preserve distinction between null and empty array when compiling
+ // $this->selectors to $selectors
+ $thisSelectors = $this->selectors;
+ $selectors = null;
$hasOnePassingSelector = false;
- $selectors = array();
- if( $this->selectors ){
- Less_Tree_DefaultFunc::error("it is currently only allowed in parametric mixin guards,");
- foreach($this->selectors as $s){
- $selector = $s->compile($env);
+ if ( $thisSelectors ) {
+ Less_Tree_DefaultFunc::error( "it is currently only allowed in parametric mixin guards," );
+
+ $selectors = [];
+ foreach ( $thisSelectors as $s ) {
+ $selector = $s->compile( $env );
$selectors[] = $selector;
- if( $selector->evaldCondition ){
+ if ( $selector->evaldCondition ) {
$hasOnePassingSelector = true;
}
}
@@ -211,48 +216,45 @@ class Less_Tree_Ruleset extends Less_Tree{
$hasOnePassingSelector = true;
}
- if( $this->rules && $hasOnePassingSelector ){
+ if ( $this->rules && $hasOnePassingSelector ) {
+ // Copy the array (no need for slice in PHP)
$rules = $this->rules;
- }else{
- $rules = array();
+ } else {
+ $rules = [];
}
- $ruleset = new Less_Tree_Ruleset($selectors, $rules, $this->strictImports);
+ $ruleset = new Less_Tree_Ruleset( $selectors, $rules, $this->strictImports );
$ruleset->originalRuleset = $this->ruleset_id;
-
$ruleset->root = $this->root;
$ruleset->firstRoot = $this->firstRoot;
$ruleset->allowImports = $this->allowImports;
-
// push the current ruleset to the frames stack
- $env->unshiftFrame($ruleset);
-
+ $env->unshiftFrame( $ruleset );
// Evaluate imports
- if( $ruleset->root || $ruleset->allowImports || !$ruleset->strictImports ){
- $ruleset->evalImports($env);
+ if ( $ruleset->root || $ruleset->allowImports || !$ruleset->strictImports ) {
+ $ruleset->evalImports( $env );
}
return $ruleset;
}
- function evalImports($env) {
-
- $rules_len = count($this->rules);
- for($i=0; $i < $rules_len; $i++){
+ function evalImports( $env ) {
+ $rules_len = count( $this->rules );
+ for ( $i = 0; $i < $rules_len; $i++ ) {
$rule = $this->rules[$i];
- if( $rule instanceof Less_Tree_Import ){
- $rules = $rule->compile($env);
- if( is_array($rules) ){
- array_splice($this->rules, $i, 1, $rules);
- $temp_count = count($rules)-1;
+ if ( $rule instanceof Less_Tree_Import ) {
+ $rules = $rule->compile( $env );
+ if ( is_array( $rules ) ) {
+ array_splice( $this->rules, $i, 1, $rules );
+ $temp_count = count( $rules ) - 1;
$i += $temp_count;
$rules_len += $temp_count;
- }else{
- array_splice($this->rules, $i, 1, array($rules));
+ } else {
+ array_splice( $this->rules, $i, 1, [ $rules ] );
}
$this->resetCache();
@@ -260,84 +262,85 @@ class Less_Tree_Ruleset extends Less_Tree{
}
}
- function makeImportant(){
-
- $important_rules = array();
- foreach($this->rules as $rule){
- if( $rule instanceof Less_Tree_Rule || $rule instanceof Less_Tree_Ruleset || $rule instanceof Less_Tree_NameValue ){
+ function makeImportant() {
+ $important_rules = [];
+ foreach ( $this->rules as $rule ) {
+ if ( $rule instanceof Less_Tree_Rule || $rule instanceof Less_Tree_Ruleset || $rule instanceof Less_Tree_NameValue ) {
$important_rules[] = $rule->makeImportant();
- }else{
+ } else {
$important_rules[] = $rule;
}
}
- return new Less_Tree_Ruleset($this->selectors, $important_rules, $this->strictImports );
+ return new Less_Tree_Ruleset( $this->selectors, $important_rules, $this->strictImports );
}
- public function matchArgs($args){
+ public function matchArgs( $args, $env = null ) {
return !$args;
}
// lets you call a css selector with a guard
- public function matchCondition( $args, $env ){
- $lastSelector = end($this->selectors);
+ public function matchCondition( $args, $env ) {
+ $lastSelector = end( $this->selectors );
- if( !$lastSelector->evaldCondition ){
+ if ( !$lastSelector->evaldCondition ) {
return false;
}
- if( $lastSelector->condition && !$lastSelector->condition->compile( $env->copyEvalEnv( $env->frames ) ) ){
+ if ( $lastSelector->condition && !$lastSelector->condition->compile( $env->copyEvalEnv( $env->frames ) ) ) {
return false;
}
return true;
}
- function resetCache(){
+ function resetCache() {
$this->_rulesets = null;
$this->_variables = null;
- $this->lookups = array();
+ $this->lookups = [];
}
- public function variables(){
- $this->_variables = array();
- foreach( $this->rules as $r){
- if ($r instanceof Less_Tree_Rule && $r->variable === true) {
+ public function variables() {
+ $this->_variables = [];
+ foreach ( $this->rules as $r ) {
+ if ( $r instanceof Less_Tree_Rule && $r->variable === true ) {
$this->_variables[$r->name] = $r;
}
}
}
- public function variable($name){
-
- if( is_null($this->_variables) ){
+ /**
+ * @param string $name
+ * @return Less_Tree_Rule|null
+ */
+ public function variable( $name ) {
+ if ( $this->_variables === null ) {
$this->variables();
}
- return isset($this->_variables[$name]) ? $this->_variables[$name] : null;
+ return $this->_variables[$name] ?? null;
}
- public function find( $selector, $self = null ){
+ public function find( $selector, $self = null ) {
+ $key = implode( ' ', $selector->_oelements );
- $key = implode(' ',$selector->_oelements);
+ if ( !isset( $this->lookups[$key] ) ) {
- if( !isset($this->lookups[$key]) ){
-
- if( !$self ){
+ if ( !$self ) {
$self = $this->ruleset_id;
}
- $this->lookups[$key] = array();
+ $this->lookups[$key] = [];
$first_oelement = $selector->_oelements[0];
- foreach($this->rules as $rule){
- if( $rule instanceof Less_Tree_Ruleset && $rule->ruleset_id != $self ){
+ foreach ( $this->rules as $rule ) {
+ if ( $rule instanceof Less_Tree_Ruleset && $rule->ruleset_id != $self ) {
- if( isset($rule->first_oelements[$first_oelement]) ){
+ if ( isset( $rule->first_oelements[$first_oelement] ) ) {
- foreach( $rule->selectors as $ruleSelector ){
- $match = $selector->match($ruleSelector);
- if( $match ){
- if( $selector->elements_len > $match ){
- $this->lookups[$key] = array_merge($this->lookups[$key], $rule->find( new Less_Tree_Selector(array_slice($selector->elements, $match)), $self));
+ foreach ( $rule->selectors as $ruleSelector ) {
+ $match = $selector->match( $ruleSelector );
+ if ( $match ) {
+ if ( $selector->elements_len > $match ) {
+ $this->lookups[$key] = array_merge( $this->lookups[$key], $rule->find( new Less_Tree_Selector( array_slice( $selector->elements, $match ) ), $self ) );
} else {
$this->lookups[$key][] = $rule;
}
@@ -352,156 +355,160 @@ class Less_Tree_Ruleset extends Less_Tree{
return $this->lookups[$key];
}
-
/**
* @see Less_Tree::genCSS
*/
- public function genCSS( $output ){
-
- if( !$this->root ){
+ public function genCSS( $output ) {
+ if ( !$this->root ) {
Less_Environment::$tabLevel++;
}
$tabRuleStr = $tabSetStr = '';
- if( !Less_Parser::$options['compress'] ){
- if( Less_Environment::$tabLevel ){
- $tabRuleStr = "\n".str_repeat( Less_Parser::$options['indentation'] , Less_Environment::$tabLevel );
- $tabSetStr = "\n".str_repeat( Less_Parser::$options['indentation'] , Less_Environment::$tabLevel-1 );
- }else{
+ if ( !Less_Parser::$options['compress'] ) {
+ if ( Less_Environment::$tabLevel ) {
+ $tabRuleStr = "\n" . str_repeat( Less_Parser::$options['indentation'], Less_Environment::$tabLevel );
+ $tabSetStr = "\n" . str_repeat( Less_Parser::$options['indentation'], Less_Environment::$tabLevel - 1 );
+ } else {
$tabSetStr = $tabRuleStr = "\n";
}
}
+ $ruleNodes = [];
+ $rulesetNodes = [];
+ foreach ( $this->rules as $rule ) {
- $ruleNodes = array();
- $rulesetNodes = array();
- foreach($this->rules as $rule){
-
- $class = get_class($rule);
- if( ($class === 'Less_Tree_Media') || ($class === 'Less_Tree_Directive') || ($this->root && $class === 'Less_Tree_Comment') || ($class === 'Less_Tree_Ruleset' && $rule->rules) ){
+ $class = get_class( $rule );
+ if (
+ ( $class === 'Less_Tree_Media' ) ||
+ ( $class === 'Less_Tree_Directive' ) ||
+ ( $this->root && $class === 'Less_Tree_Comment' ) ||
+ ( $rule instanceof Less_Tree_Ruleset && $rule->rules )
+ ) {
$rulesetNodes[] = $rule;
- }else{
+ } else {
$ruleNodes[] = $rule;
}
}
// If this is the root node, we don't render
// a selector, or {}.
- if( !$this->root ){
-
- /*
- debugInfo = tree.debugInfo(env, this, tabSetStr);
-
- if (debugInfo) {
- output.add(debugInfo);
- output.add(tabSetStr);
- }
- */
-
- $paths_len = count($this->paths);
- for( $i = 0; $i < $paths_len; $i++ ){
+ if ( !$this->root ) {
+ $paths_len = count( $this->paths );
+ for ( $i = 0; $i < $paths_len; $i++ ) {
$path = $this->paths[$i];
$firstSelector = true;
- foreach($path as $p){
+ foreach ( $path as $p ) {
$p->genCSS( $output, $firstSelector );
$firstSelector = false;
}
- if( $i + 1 < $paths_len ){
+ if ( $i + 1 < $paths_len ) {
$output->add( ',' . $tabSetStr );
}
}
- $output->add( (Less_Parser::$options['compress'] ? '{' : " {") . $tabRuleStr );
+ $output->add( ( Less_Parser::$options['compress'] ? '{' : " {" ) . $tabRuleStr );
}
// Compile rules and rulesets
- $ruleNodes_len = count($ruleNodes);
- $rulesetNodes_len = count($rulesetNodes);
- for( $i = 0; $i < $ruleNodes_len; $i++ ){
+ $ruleNodes_len = count( $ruleNodes );
+ $rulesetNodes_len = count( $rulesetNodes );
+ for ( $i = 0; $i < $ruleNodes_len; $i++ ) {
$rule = $ruleNodes[$i];
// @page{ directive ends up with root elements inside it, a mix of rules and rulesets
// In this instance we do not know whether it is the last property
- if( $i + 1 === $ruleNodes_len && (!$this->root || $rulesetNodes_len === 0 || $this->firstRoot ) ){
+ if ( $i + 1 === $ruleNodes_len && ( !$this->root || $rulesetNodes_len === 0 || $this->firstRoot ) ) {
Less_Environment::$lastRule = true;
}
$rule->genCSS( $output );
- if( !Less_Environment::$lastRule ){
+ if ( !Less_Environment::$lastRule ) {
$output->add( $tabRuleStr );
- }else{
+ } else {
Less_Environment::$lastRule = false;
}
}
- if( !$this->root ){
+ if ( !$this->root ) {
$output->add( $tabSetStr . '}' );
Less_Environment::$tabLevel--;
}
$firstRuleset = true;
- $space = ($this->root ? $tabRuleStr : $tabSetStr);
- for( $i = 0; $i < $rulesetNodes_len; $i++ ){
+ $space = ( $this->root ? $tabRuleStr : $tabSetStr );
+ for ( $i = 0; $i < $rulesetNodes_len; $i++ ) {
- if( $ruleNodes_len && $firstRuleset ){
+ if ( $ruleNodes_len && $firstRuleset ) {
$output->add( $space );
- }elseif( !$firstRuleset ){
+ } elseif ( !$firstRuleset ) {
$output->add( $space );
}
$firstRuleset = false;
- $rulesetNodes[$i]->genCSS( $output);
+ $rulesetNodes[$i]->genCSS( $output );
}
- if( !Less_Parser::$options['compress'] && $this->firstRoot ){
+ if ( !Less_Parser::$options['compress'] && $this->firstRoot ) {
$output->add( "\n" );
}
-
}
-
- function markReferenced(){
- if( !$this->selectors ){
+ function markReferenced() {
+ if ( !$this->selectors ) {
return;
}
- foreach($this->selectors as $selector){
+ foreach ( $this->selectors as $selector ) {
$selector->markReferenced();
}
}
- public function joinSelectors( $context, $selectors ){
- $paths = array();
- if( is_array($selectors) ){
- foreach($selectors as $selector) {
- $this->joinSelector( $paths, $context, $selector);
+ /**
+ * @param Less_Tree_Selector[][] $context
+ * @param Less_Tree_Selector[]|null $selectors
+ * @return Less_Tree_Selector[][]
+ */
+ public function joinSelectors( $context, $selectors ) {
+ $paths = [];
+ if ( $selectors !== null ) {
+ foreach ( $selectors as $selector ) {
+ $this->joinSelector( $paths, $context, $selector );
}
}
return $paths;
}
- public function joinSelector( &$paths, $context, $selector){
+ public function joinSelector( array &$paths, array $context, Less_Tree_Selector $selector ) {
+ $newPaths = [];
+ $hadParentSelector = $this->replaceParentSelector( $newPaths, $context, $selector );
- $hasParentSelector = false;
-
- foreach($selector->elements as $el) {
- if( $el->value === '&') {
- $hasParentSelector = true;
- }
- }
-
- if( !$hasParentSelector ){
- if( $context ){
- foreach($context as $context_el){
- $paths[] = array_merge($context_el, array($selector) );
+ if ( !$hadParentSelector ) {
+ if ( $context ) {
+ $newPaths = [];
+ foreach ( $context as $path ) {
+ $newPaths[] = array_merge( $path, [ $selector ] );
}
- }else {
- $paths[] = array($selector);
+ } else {
+ $newPaths = [ [ $selector ] ];
}
- return;
}
+ foreach ( $newPaths as $newPath ) {
+ $paths[] = $newPath;
+ }
+ }
+
+ /**
+ * Replace all parent selectors inside $inSelector with $context.
+ *
+ * @param array &$paths Resulting selectors are appended to $paths.
+ * @param mixed $context
+ * @param Less_Tree_Selector $inSelector Inner selector from Less_Tree_Paren
+ * @return bool True if $inSelector contained at least one parent selector
+ */
+ private function replaceParentSelector( array &$paths, $context, Less_Tree_Selector $inSelector ) {
+ $hadParentSelector = false;
// The paths are [[Selector]]
// The first list is a list of comma separated selectors
@@ -515,88 +522,70 @@ class Less_Tree_Ruleset extends Less_Tree{
//
// the elements from the current selector so far
- $currentElements = array();
+ $currentElements = [];
// the current list of new selectors to add to the path.
// We will build it up. We initiate it with one empty selector as we "multiply" the new selectors
// by the parents
- $newSelectors = array(array());
+ $newSelectors = [
+ []
+ ];
+ foreach ( $inSelector->elements as $el ) {
+ // non-parent reference elements just get added
+ if ( $el->value !== '&' ) {
+ $nestedSelector = $this->findNestedSelector( $el );
+ if ( $nestedSelector !== null ) {
+ $this->mergeElementsOnToSelectors( $currentElements, $newSelectors );
- foreach( $selector->elements as $el){
+ $nestedPaths = [];
+ $replacedNewSelectors = [];
+ $replaced = $this->replaceParentSelector( $nestedPaths, $context, $nestedSelector );
+ $hadParentSelector = $hadParentSelector || $replaced;
+ // $nestedPaths is populated by replaceParentSelector()
+ // $nestedPaths should have exactly one TODO, replaceParentSelector does not multiply selectors
+ foreach ( $nestedPaths as $nestedPath ) {
+ $replacementSelector = $this->createSelector( $nestedPath, $el );
- // non parent reference elements just get added
- if( $el->value !== '&' ){
- $currentElements[] = $el;
+ // join selector path from $newSelectors with every selector path in $addPaths array.
+ // $el contains the element that is being replaced by $addPaths
+ //
+ // @see less-2.5.3.js#Ruleset-addAllReplacementsIntoPath
+ $addPaths = [ $replacementSelector ];
+ foreach ( $newSelectors as $newSelector ) {
+ $replacedNewSelectors[] = $this->addReplacementIntoPath( $newSelector, $addPaths, $el, $inSelector );
+ }
+ }
+ $newSelectors = $replacedNewSelectors;
+ $currentElements = [];
+ } else {
+ $currentElements[] = $el;
+ }
} else {
+ $hadParentSelector = true;
+
// the new list of selectors to add
- $selectorsMultiplied = array();
+ $selectorsMultiplied = [];
// merge the current list of non parent selector elements
// on to the current list of selectors to add
- if( $currentElements ){
- $this->mergeElementsOnToSelectors( $currentElements, $newSelectors);
- }
-
- // loop through our current selectors
- foreach($newSelectors as $sel){
+ $this->mergeElementsOnToSelectors( $currentElements, $newSelectors );
+ foreach ( $newSelectors as $sel ) {
// if we don't have any parent paths, the & might be in a mixin so that it can be used
// whether there are parents or not
- if( !$context ){
+ if ( !$context ) {
// the combinator used on el should now be applied to the next element instead so that
// it is not lost
- if( $sel ){
- $sel[0]->elements = array_slice($sel[0]->elements,0);
- $sel[0]->elements[] = new Less_Tree_Element($el->combinator, '', $el->index, $el->currentFileInfo );
+ if ( $sel ) {
+ $sel[0]->elements[] = new Less_Tree_Element( $el->combinator, '', $el->index, $el->currentFileInfo );
}
$selectorsMultiplied[] = $sel;
- }else {
-
+ } else {
// and the parent selectors
- foreach($context as $parentSel){
+ foreach ( $context as $parentSel ) {
// We need to put the current selectors
// then join the last selector's elements on to the parents selectors
-
- // our new selector path
- $newSelectorPath = array();
- // selectors from the parent after the join
- $afterParentJoin = array();
- $newJoinedSelectorEmpty = true;
-
- //construct the joined selector - if & is the first thing this will be empty,
- // if not newJoinedSelector will be the last set of elements in the selector
- if( $sel ){
- $newSelectorPath = $sel;
- $lastSelector = array_pop($newSelectorPath);
- $newJoinedSelector = $selector->createDerived( array_slice($lastSelector->elements,0) );
- $newJoinedSelectorEmpty = false;
- }
- else {
- $newJoinedSelector = $selector->createDerived(array());
- }
-
- //put together the parent selectors after the join
- if ( count($parentSel) > 1) {
- $afterParentJoin = array_merge($afterParentJoin, array_slice($parentSel,1) );
- }
-
- if ( $parentSel ){
- $newJoinedSelectorEmpty = false;
-
- // join the elements so far with the first part of the parent
- $newJoinedSelector->elements[] = new Less_Tree_Element( $el->combinator, $parentSel[0]->elements[0]->value, $el->index, $el->currentFileInfo);
-
- $newJoinedSelector->elements = array_merge( $newJoinedSelector->elements, array_slice($parentSel[0]->elements, 1) );
- }
-
- if (!$newJoinedSelectorEmpty) {
- // now add the joined selector
- $newSelectorPath[] = $newJoinedSelector;
- }
-
- // and the rest of the parent
- $newSelectorPath = array_merge($newSelectorPath, $afterParentJoin);
-
+ $newSelectorPath = $this->addReplacementIntoPath( $sel, $parentSel, $el, $inSelector );
// add that to our new set of selectors
$selectorsMultiplied[] = $newSelectorPath;
}
@@ -605,37 +594,135 @@ class Less_Tree_Ruleset extends Less_Tree{
// our new selectors has been multiplied, so reset the state
$newSelectors = $selectorsMultiplied;
- $currentElements = array();
+ $currentElements = [];
}
}
// if we have any elements left over (e.g. .a& .b == .b)
// add them on to all the current selectors
- if( $currentElements ){
- $this->mergeElementsOnToSelectors($currentElements, $newSelectors);
- }
- foreach( $newSelectors as $new_sel){
- if( $new_sel ){
- $paths[] = $new_sel;
+ $this->mergeElementsOnToSelectors( $currentElements, $newSelectors );
+
+ foreach ( $newSelectors as &$sel ) {
+ $length = count( $sel );
+ if ( $length ) {
+ $paths[] = $sel;
+ $lastSelector = $sel[$length - 1];
+ $sel[$length - 1] = $lastSelector->createDerived( $lastSelector->elements, $inSelector->extendList );
}
}
+
+ return $hadParentSelector;
}
- function mergeElementsOnToSelectors( $elements, &$selectors){
+ /**
+ * @param array $elementsToPak
+ * @param Less_Tree_Element $originalElement
+ * @return Less_Tree_Selector
+ */
+ private function createSelector( array $elementsToPak, $originalElement ) {
+ if ( !$elementsToPak ) {
+ // This is an invalid call. Kept to match less.js. Appears unreachable.
+ // @phan-suppress-next-line PhanTypeMismatchArgumentProbablyReal
+ $containedElement = new Less_Tree_Paren( null );
+ } else {
+ $insideParent = [];
+ foreach ( $elementsToPak as $elToPak ) {
+ $insideParent[] = new Less_Tree_Element( null, $elToPak, $originalElement->index, $originalElement->currentFileInfo );
+ }
+ $containedElement = new Less_Tree_Paren( new Less_Tree_Selector( $insideParent ) );
+ }
- if( !$selectors ){
- $selectors[] = array( new Less_Tree_Selector($elements) );
+ $element = new Less_Tree_Element( null, $containedElement, $originalElement->index, $originalElement->currentFileInfo );
+ return new Less_Tree_Selector( [ $element ] );
+ }
+
+ /**
+ * @param Less_Tree_Element $element
+ * @return Less_Tree_Selector|null
+ */
+ private function findNestedSelector( $element ) {
+ $maybeParen = $element->value;
+ if ( !( $maybeParen instanceof Less_Tree_Paren ) ) {
+ return null;
+ }
+ $maybeSelector = $maybeParen->value;
+ if ( !( $maybeSelector instanceof Less_Tree_Selector ) ) {
+ return null;
+ }
+ return $maybeSelector;
+ }
+
+ /**
+ * joins selector path from $beginningPath with selector path in $addPath.
+ *
+ * $replacedElement contains the element that is being replaced by $addPath
+ *
+ * @param Less_Tree_Selector[] $beginningPath
+ * @param Less_Tree_Selector[] $addPath
+ * @param Less_Tree_Element $replacedElement
+ * @param Less_Tree_Selector $originalSelector
+ * @return Less_Tree_Selector[] Concatenated path
+ * @see less-2.5.3.js#Ruleset-addReplacementIntoPath
+ */
+ private function addReplacementIntoPath( array $beginningPath, array $addPath, $replacedElement, $originalSelector ) {
+ // our new selector path
+ $newSelectorPath = [];
+
+ // construct the joined selector - if `&` is the first thing this will be empty,
+ // if not newJoinedSelector will be the last set of elements in the selector
+ if ( $beginningPath ) {
+ // NOTE: less.js uses Array slice() to copy. In PHP, arrays are naturally copied by value.
+ $newSelectorPath = $beginningPath;
+ $lastSelector = array_pop( $newSelectorPath );
+ $newJoinedSelector = $originalSelector->createDerived( $lastSelector->elements );
+ } else {
+ $newJoinedSelector = $originalSelector->createDerived( [] );
+ }
+
+ if ( $addPath ) {
+ // if the & does not have a combinator that is "" or " " then
+ // and there is a combinator on the parent, then grab that.
+ // this also allows `+ a { & .b { .a & { ...`
+ $combinator = $replacedElement->combinator;
+ $parentEl = $addPath[0]->elements[0];
+ if ( $replacedElement->combinatorIsEmptyOrWhitespace && !$parentEl->combinatorIsEmptyOrWhitespace ) {
+ $combinator = $parentEl->combinator;
+ }
+ // join the elements so far with the first part of the parent
+ $newJoinedSelector->elements[] = new Less_Tree_Element( $combinator, $parentEl->value, $replacedElement->index, $replacedElement->currentFileInfo );
+ $newJoinedSelector->elements = array_merge(
+ $newJoinedSelector->elements,
+ array_slice( $addPath[0]->elements, 1 )
+ );
+ }
+
+ // now add the joined selector - but only if it is not empty
+ if ( $newJoinedSelector->elements ) {
+ $newSelectorPath[] = $newJoinedSelector;
+ }
+
+ // put together the parent selectors after the join (e.g. the rest of the parent)
+ if ( count( $addPath ) > 1 ) {
+ $newSelectorPath = array_merge( $newSelectorPath, array_slice( $addPath, 1 ) );
+ }
+ return $newSelectorPath;
+ }
+
+ function mergeElementsOnToSelectors( $elements, &$selectors ) {
+ if ( !$elements ) {
+ return;
+ }
+ if ( !$selectors ) {
+ $selectors[] = [ new Less_Tree_Selector( $elements ) ];
return;
}
-
- foreach( $selectors as &$sel){
-
+ foreach ( $selectors as &$sel ) {
// if the previous thing in sel is a parent this needs to join on to it
- if( $sel ){
- $last = count($sel)-1;
- $sel[$last] = $sel[$last]->createDerived( array_merge($sel[$last]->elements, $elements) );
- }else{
+ if ( $sel ) {
+ $last = count( $sel ) - 1;
+ $sel[$last] = $sel[$last]->createDerived( array_merge( $sel[$last]->elements, $elements ) );
+ } else {
$sel[] = new Less_Tree_Selector( $elements );
}
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/RulesetCall.php b/vendor/wikimedia/less.php/lib/Less/Tree/RulesetCall.php
index ed4c72373..9c162b8c9 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/RulesetCall.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/RulesetCall.php
@@ -1,26 +1,26 @@
variable = $variable;
}
- public function accept($visitor) {}
+ public function accept( $visitor ) {
+ }
- public function compile( $env ){
- $variable = new Less_Tree_Variable($this->variable);
- $detachedRuleset = $variable->compile($env);
- return $detachedRuleset->callEval($env);
+ public function compile( $env ) {
+ $variable = new Less_Tree_Variable( $this->variable );
+ $detachedRuleset = $variable->compile( $env );
+ '@phan-var Less_Tree_DetachedRuleset $detachedRuleset';
+ return $detachedRuleset->callEval( $env );
}
}
-
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Selector.php b/vendor/wikimedia/less.php/lib/Less/Tree/Selector.php
index 6b9dae612..71182da80 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Selector.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Selector.php
@@ -1,77 +1,79 @@
elements = $elements;
- $this->elements_len = count($elements);
+ $this->elements_len = count( $elements );
$this->extendList = $extendList;
$this->condition = $condition;
- if( $currentFileInfo ){
+ if ( $currentFileInfo ) {
$this->currentFileInfo = $currentFileInfo;
}
$this->isReferenced = $isReferenced;
- if( !$condition ){
+ if ( !$condition ) {
$this->evaldCondition = true;
}
$this->CacheElements();
}
- public function accept($visitor) {
- $this->elements = $visitor->visitArray($this->elements);
- $this->extendList = $visitor->visitArray($this->extendList);
- if( $this->condition ){
- $this->condition = $visitor->visitObj($this->condition);
+ public function accept( $visitor ) {
+ $this->elements = $visitor->visitArray( $this->elements );
+ $this->extendList = $visitor->visitArray( $this->extendList );
+ if ( $this->condition ) {
+ $this->condition = $visitor->visitObj( $this->condition );
}
- if( $visitor instanceof Less_Visitor_extendFinder ){
+ if ( $visitor instanceof Less_Visitor_extendFinder ) {
$this->CacheElements();
}
}
- public function createDerived( $elements, $extendList = null, $evaldCondition = null ){
- $newSelector = new Less_Tree_Selector( $elements, ($extendList ? $extendList : $this->extendList), null, $this->index, $this->currentFileInfo, $this->isReferenced);
- $newSelector->evaldCondition = $evaldCondition ? $evaldCondition : $this->evaldCondition;
+ public function createDerived( $elements, $extendList = null, $evaldCondition = null ) {
+ $newSelector = new Less_Tree_Selector(
+ $elements,
+ ( $extendList ?: $this->extendList ),
+ null,
+ $this->index,
+ $this->currentFileInfo,
+ $this->isReferenced
+ );
+ $newSelector->evaldCondition = $evaldCondition ?: $this->evaldCondition;
+ $newSelector->mediaEmpty = $this->mediaEmpty;
return $newSelector;
}
-
- public function match( $other ){
-
- if( !$other->_oelements || ($this->elements_len < $other->_oelements_len) ){
+ public function match( $other ) {
+ if ( !$other->_oelements || ( $this->elements_len < $other->_oelements_len ) ) {
return 0;
}
- for( $i = 0; $i < $other->_oelements_len; $i++ ){
- if( $this->elements[$i]->value !== $other->_oelements[$i]) {
+ for ( $i = 0; $i < $other->_oelements_len; $i++ ) {
+ if ( $this->elements[$i]->value !== $other->_oelements[$i] ) {
return 0;
}
}
@@ -79,89 +81,88 @@ class Less_Tree_Selector extends Less_Tree{
return $other->_oelements_len; // return number of matched elements
}
+ public function CacheElements() {
+ $this->_oelements = [];
+ $this->_oelements_assoc = [];
- public function CacheElements(){
-
- $this->_oelements = array();
$css = '';
- foreach($this->elements as $v){
+ foreach ( $this->elements as $v ) {
$css .= $v->combinator;
- if( !$v->value_is_object ){
+ if ( !$v->value_is_object ) {
$css .= $v->value;
continue;
}
- if( !property_exists($v->value,'value') || !is_string($v->value->value) ){
+ if ( !property_exists( $v->value, 'value' ) || !is_string( $v->value->value ) ) {
$this->cacheable = false;
return;
}
$css .= $v->value->value;
}
- $this->_oelements_len = preg_match_all('/[,\.\w-](?:[\w-]|(?:\\\\.))*/', $css, $matches);
- if( $this->_oelements_len ){
+ $this->_oelements_len = preg_match_all( '/[,\.\w-](?:[\w-]|(?:\\\\.))*/', $css, $matches );
+ if ( $this->_oelements_len ) {
$this->_oelements = $matches[0];
- if( $this->_oelements[0] === '&' ){
- array_shift($this->_oelements);
+ if ( $this->_oelements[0] === '&' ) {
+ array_shift( $this->_oelements );
$this->_oelements_len--;
}
+
+ $this->_oelements_assoc = array_fill_keys( $this->_oelements, true );
}
}
- public function isJustParentSelector(){
+ public function isJustParentSelector() {
return !$this->mediaEmpty &&
- count($this->elements) === 1 &&
+ count( $this->elements ) === 1 &&
$this->elements[0]->value === '&' &&
- ($this->elements[0]->combinator === ' ' || $this->elements[0]->combinator === '');
+ ( $this->elements[0]->combinator === ' ' || $this->elements[0]->combinator === '' );
}
- public function compile($env) {
-
- $elements = array();
- foreach($this->elements as $el){
- $elements[] = $el->compile($env);
+ public function compile( $env ) {
+ $elements = [];
+ foreach ( $this->elements as $el ) {
+ $elements[] = $el->compile( $env );
}
- $extendList = array();
- foreach($this->extendList as $el){
- $extendList[] = $el->compile($el);
+ $extendList = [];
+ foreach ( $this->extendList as $el ) {
+ $extendList[] = $el->compile( $el );
}
$evaldCondition = false;
- if( $this->condition ){
- $evaldCondition = $this->condition->compile($env);
+ if ( $this->condition ) {
+ $evaldCondition = $this->condition->compile( $env );
}
return $this->createDerived( $elements, $extendList, $evaldCondition );
}
-
/**
* @see Less_Tree::genCSS
*/
- public function genCSS( $output, $firstSelector = true ){
-
- if( !$firstSelector && $this->elements[0]->combinator === "" ){
- $output->add(' ', $this->currentFileInfo, $this->index);
+ public function genCSS( $output, $firstSelector = true ) {
+ if ( !$firstSelector && $this->elements[0]->combinator === "" ) {
+ $output->add( ' ', $this->currentFileInfo, $this->index );
}
- foreach($this->elements as $element){
+ foreach ( $this->elements as $element ) {
$element->genCSS( $output );
}
}
- public function markReferenced(){
+ public function markReferenced() {
$this->isReferenced = true;
}
- public function getIsReferenced(){
- return !isset($this->currentFileInfo['reference']) || !$this->currentFileInfo['reference'] || $this->isReferenced;
+ public function getIsReferenced() {
+ return !isset( $this->currentFileInfo['reference'] ) || !$this->currentFileInfo['reference'] || $this->isReferenced;
}
- public function getIsOutput(){
+ public function getIsOutput() {
return $this->evaldCondition;
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/UnicodeDescriptor.php b/vendor/wikimedia/less.php/lib/Less/Tree/UnicodeDescriptor.php
index 8c4707efd..304d191e8 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/UnicodeDescriptor.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/UnicodeDescriptor.php
@@ -1,29 +1,20 @@
value = $value;
}
- /**
- * @see Less_Tree::genCSS
- */
- public function genCSS( $output ){
+ /**
+ * @see Less_Tree::genCSS
+ */
+ public function genCSS( $output ) {
$output->add( $this->value );
}
-
- public function compile(){
- return $this;
- }
}
-
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Unit.php b/vendor/wikimedia/less.php/lib/Less/Tree/Unit.php
index e13b100e2..2fd892766 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Unit.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Unit.php
@@ -1,98 +1,91 @@
numerator = $numerator;
$this->denominator = $denominator;
$this->backupUnit = $backupUnit;
}
- public function __clone(){
+ public function __clone() {
}
- /**
- * @see Less_Tree::genCSS
- */
- public function genCSS( $output ){
-
- if( $this->numerator ){
+ /**
+ * @see Less_Tree::genCSS
+ */
+ public function genCSS( $output ) {
+ if ( $this->numerator ) {
$output->add( $this->numerator[0] );
- }elseif( $this->denominator ){
+ } elseif ( $this->denominator ) {
$output->add( $this->denominator[0] );
- }elseif( !Less_Parser::$options['strictUnits'] && $this->backupUnit ){
+ } elseif ( !Less_Parser::$options['strictUnits'] && $this->backupUnit ) {
$output->add( $this->backupUnit );
- return ;
+ return;
}
}
- public function toString(){
- $returnStr = implode('*',$this->numerator);
- foreach($this->denominator as $d){
- $returnStr .= '/'.$d;
+ public function toString() {
+ $returnStr = implode( '*', $this->numerator );
+ foreach ( $this->denominator as $d ) {
+ $returnStr .= '/' . $d;
}
return $returnStr;
}
- public function __toString(){
+ public function __toString() {
return $this->toString();
}
-
/**
* @param Less_Tree_Unit $other
*/
- public function compare($other) {
+ public function compare( $other ) {
return $this->is( $other->toString() ) ? 0 : -1;
}
- public function is($unitString){
+ public function is( $unitString ) {
return $this->toString() === $unitString;
}
- public function isLength(){
+ public function isLength() {
$css = $this->toCSS();
- return !!preg_match('/px|em|%|in|cm|mm|pc|pt|ex/',$css);
+ return (bool)preg_match( '/px|em|%|in|cm|mm|pc|pt|ex/', $css );
}
- public function isAngle() {
+ public function isAngle() {
return isset( Less_Tree_UnitConversions::$angle[$this->toCSS()] );
}
- public function isEmpty(){
+ public function isEmpty() {
return !$this->numerator && !$this->denominator;
}
- public function isSingular() {
- return count($this->numerator) <= 1 && !$this->denominator;
+ public function isSingular() {
+ return count( $this->numerator ) <= 1 && !$this->denominator;
}
+ public function usedUnits() {
+ $result = [];
- public function usedUnits(){
- $result = array();
-
- foreach(Less_Tree_UnitConversions::$groups as $groupName){
+ foreach ( Less_Tree_UnitConversions::$groups as $groupName ) {
$group = Less_Tree_UnitConversions::${$groupName};
- foreach($this->numerator as $atomicUnit){
- if( isset($group[$atomicUnit]) && !isset($result[$groupName]) ){
+ foreach ( $this->numerator as $atomicUnit ) {
+ if ( isset( $group[$atomicUnit] ) && !isset( $result[$groupName] ) ) {
$result[$groupName] = $atomicUnit;
}
}
- foreach($this->denominator as $atomicUnit){
- if( isset($group[$atomicUnit]) && !isset($result[$groupName]) ){
+ foreach ( $this->denominator as $atomicUnit ) {
+ if ( isset( $group[$atomicUnit] ) && !isset( $result[$groupName] ) ) {
$result[$groupName] = $atomicUnit;
}
}
@@ -101,47 +94,45 @@ class Less_Tree_Unit extends Less_Tree{
return $result;
}
- public function cancel(){
- $counter = array();
+ public function cancel() {
+ $counter = [];
$backup = null;
- foreach($this->numerator as $atomicUnit){
- if( !$backup ){
+ foreach ( $this->numerator as $atomicUnit ) {
+ if ( !$backup ) {
$backup = $atomicUnit;
}
- $counter[$atomicUnit] = ( isset($counter[$atomicUnit]) ? $counter[$atomicUnit] : 0) + 1;
+ $counter[$atomicUnit] = ( $counter[$atomicUnit] ?? 0 ) + 1;
}
- foreach($this->denominator as $atomicUnit){
- if( !$backup ){
+ foreach ( $this->denominator as $atomicUnit ) {
+ if ( !$backup ) {
$backup = $atomicUnit;
}
- $counter[$atomicUnit] = ( isset($counter[$atomicUnit]) ? $counter[$atomicUnit] : 0) - 1;
+ $counter[$atomicUnit] = ( $counter[$atomicUnit] ?? 0 ) - 1;
}
- $this->numerator = array();
- $this->denominator = array();
+ $this->numerator = [];
+ $this->denominator = [];
- foreach($counter as $atomicUnit => $count){
- if( $count > 0 ){
- for( $i = 0; $i < $count; $i++ ){
+ foreach ( $counter as $atomicUnit => $count ) {
+ if ( $count > 0 ) {
+ for ( $i = 0; $i < $count; $i++ ) {
$this->numerator[] = $atomicUnit;
}
- }elseif( $count < 0 ){
- for( $i = 0; $i < -$count; $i++ ){
+ } elseif ( $count < 0 ) {
+ for ( $i = 0; $i < -$count; $i++ ) {
$this->denominator[] = $atomicUnit;
}
}
}
- if( !$this->numerator && !$this->denominator && $backup ){
+ if ( !$this->numerator && !$this->denominator && $backup ) {
$this->backupUnit = $backup;
}
- sort($this->numerator);
- sort($this->denominator);
+ sort( $this->numerator );
+ sort( $this->denominator );
}
-
}
-
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/UnitConversions.php b/vendor/wikimedia/less.php/lib/Less/Tree/UnitConversions.php
index c86b2907b..31efe1ccf 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/UnitConversions.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/UnitConversions.php
@@ -1,35 +1,31 @@
1,
- 'cm'=> 0.01,
- 'mm'=> 0.001,
- 'in'=> 0.0254,
- 'px'=> 0.000264583, // 0.0254 / 96,
- 'pt'=> 0.000352778, // 0.0254 / 72,
- 'pc'=> 0.004233333, // 0.0254 / 72 * 12
- );
+ public static $length = [
+ 'm' => 1,
+ 'cm' => 0.01,
+ 'mm' => 0.001,
+ 'in' => 0.0254,
+ 'px' => 0.000264583, // 0.0254 / 96,
+ 'pt' => 0.000352778, // 0.0254 / 72,
+ 'pc' => 0.004233333, // 0.0254 / 72 * 12
+ ];
- public static $duration = array(
- 's'=> 1,
- 'ms'=> 0.001
- );
+ public static $duration = [
+ 's' => 1,
+ 'ms' => 0.001
+ ];
- public static $angle = array(
+ public static $angle = [
'rad' => 0.1591549430919, // 1/(2*M_PI),
'deg' => 0.002777778, // 1/360,
- 'grad'=> 0.0025, // 1/400,
- 'turn'=> 1
- );
+ 'grad' => 0.0025, // 1/400,
+ 'turn' => 1
+ ];
-}
\ No newline at end of file
+}
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Url.php b/vendor/wikimedia/less.php/lib/Less/Tree/Url.php
index ef9c3c68c..6ae3518e9 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Url.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Url.php
@@ -1,12 +1,8 @@
value = $value;
$this->currentFileInfo = $currentFileInfo;
$this->isEvald = $isEvald;
}
- public function accept( $visitor ){
- $this->value = $visitor->visitObj($this->value);
+ public function accept( $visitor ) {
+ $this->value = $visitor->visitObj( $this->value );
}
- /**
- * @see Less_Tree::genCSS
- */
- public function genCSS( $output ){
+ /**
+ * @see Less_Tree::genCSS
+ */
+ public function genCSS( $output ) {
$output->add( 'url(' );
$this->value->genCSS( $output );
$output->add( ')' );
}
/**
- * @param Less_Functions $ctx
+ * @param Less_Environment $ctx
*/
- public function compile($ctx){
- $val = $this->value->compile($ctx);
+ public function compile( $ctx ) {
+ $val = $this->value->compile( $ctx );
- if( !$this->isEvald ){
+ if ( !$this->isEvald ) {
// Add the base path if the URL is relative
- if( Less_Parser::$options['relativeUrls']
+ if ( Less_Parser::$options['relativeUrls']
&& $this->currentFileInfo
- && is_string($val->value)
- && Less_Environment::isPathRelative($val->value)
- ){
+ && is_string( $val->value )
+ && Less_Environment::isPathRelative( $val->value )
+ ) {
$rootpath = $this->currentFileInfo['uri_root'];
- if ( !$val->quote ){
- $rootpath = preg_replace('/[\(\)\'"\s]/', '\\$1', $rootpath );
+ if ( !$val->quote ) {
+ $rootpath = preg_replace( '/[\(\)\'"\s]/', '\\$1', $rootpath );
}
$val->value = $rootpath . $val->value;
}
- $val->value = Less_Environment::normalizePath( $val->value);
+ $val->value = Less_Environment::normalizePath( $val->value );
}
// Add cache buster if enabled
- if( Less_Parser::$options['urlArgs'] ){
- if( !preg_match('/^\s*data:/',$val->value) ){
- $delimiter = strpos($val->value,'?') === false ? '?' : '&';
+ if ( Less_Parser::$options['urlArgs'] ) {
+ if ( !preg_match( '/^\s*data:/', $val->value ) ) {
+ $delimiter = strpos( $val->value, '?' ) === false ? '?' : '&';
$urlArgs = $delimiter . Less_Parser::$options['urlArgs'];
- $hash_pos = strpos($val->value,'#');
- if( $hash_pos !== false ){
- $val->value = substr_replace($val->value,$urlArgs, $hash_pos, 0);
+ $hash_pos = strpos( $val->value, '#' );
+ if ( $hash_pos !== false ) {
+ $val->value = substr_replace( $val->value, $urlArgs, $hash_pos, 0 );
} else {
$val->value .= $urlArgs;
}
}
}
- return new Less_Tree_URL($val, $this->currentFileInfo, true);
+ return new Less_Tree_URL( $val, $this->currentFileInfo, true );
}
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Value.php b/vendor/wikimedia/less.php/lib/Less/Tree/Value.php
index 9f077bc56..bf45caf36 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Value.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Value.php
@@ -1,45 +1,43 @@
$value
+ */
+ public function __construct( $value ) {
$this->value = $value;
}
- public function accept($visitor) {
- $this->value = $visitor->visitArray($this->value);
+ public function accept( $visitor ) {
+ $this->value = $visitor->visitArray( $this->value );
}
- public function compile($env){
-
- $ret = array();
+ public function compile( $env ) {
+ $ret = [];
$i = 0;
- foreach($this->value as $i => $v){
- $ret[] = $v->compile($env);
+ foreach ( $this->value as $i => $v ) {
+ $ret[] = $v->compile( $env );
}
- if( $i > 0 ){
- return new Less_Tree_Value($ret);
+ if ( $i > 0 ) {
+ return new Less_Tree_Value( $ret );
}
return $ret[0];
}
- /**
- * @see Less_Tree::genCSS
- */
- function genCSS( $output ){
- $len = count($this->value);
- for($i = 0; $i < $len; $i++ ){
+ /**
+ * @see Less_Tree::genCSS
+ */
+ function genCSS( $output ) {
+ $len = count( $this->value );
+ for ( $i = 0; $i < $len; $i++ ) {
$this->value[$i]->genCSS( $output );
- if( $i+1 < $len ){
+ if ( $i + 1 < $len ) {
$output->add( Less_Environment::$_outputMap[','] );
}
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Variable.php b/vendor/wikimedia/less.php/lib/Less/Tree/Variable.php
index cc0182cde..dcb1823ad 100644
--- a/vendor/wikimedia/less.php/lib/Less/Tree/Variable.php
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Variable.php
@@ -1,12 +1,8 @@
name = $name;
- $this->index = $index;
+ /**
+ * @param string $name
+ */
+ public function __construct( $name, $index = null, $currentFileInfo = null ) {
+ $this->name = $name;
+ $this->index = $index;
$this->currentFileInfo = $currentFileInfo;
- }
+ }
- public function compile($env) {
-
- if( $this->name[1] === '@' ){
- $v = new Less_Tree_Variable(substr($this->name, 1), $this->index + 1, $this->currentFileInfo);
- $name = '@' . $v->compile($env)->value;
- }else{
+ /**
+ * @param Less_Environment $env
+ * @return Less_Tree
+ * @see less-2.5.3.js#Ruleset.prototype.eval
+ */
+ public function compile( $env ) {
+ if ( $this->name[1] === '@' ) {
+ $v = new Less_Tree_Variable( substr( $this->name, 1 ), $this->index + 1, $this->currentFileInfo );
+ // While some Less_Tree nodes have no 'value', we know these can't ocurr after a variable
+ // assignment (would have been a ParseError).
+ // TODO: Solve better (https://phabricator.wikimedia.org/T327082).
+ // @phan-suppress-next-line PhanUndeclaredProperty
+ $name = '@' . $v->compile( $env )->value;
+ } else {
$name = $this->name;
}
- if ($this->evaluating) {
- throw new Less_Exception_Compiler("Recursive variable definition for " . $name, null, $this->index, $this->currentFileInfo);
+ if ( $this->evaluating ) {
+ throw new Less_Exception_Compiler( "Recursive variable definition for " . $name, null, $this->index, $this->currentFileInfo );
}
$this->evaluating = true;
- foreach($env->frames as $frame){
- if( $v = $frame->variable($name) ){
- $r = $v->value->compile($env);
+ foreach ( $env->frames as $frame ) {
+ if ( $v = $frame->variable( $name ) ) {
+ $r = $v->value->compile( $env );
$this->evaluating = false;
return $r;
}
}
- throw new Less_Exception_Compiler("variable " . $name . " is undefined in file ".$this->currentFileInfo["filename"], null, $this->index, $this->currentFileInfo);
+ throw new Less_Exception_Compiler( "variable " . $name . " is undefined in file " . $this->currentFileInfo["filename"], null, $this->index, $this->currentFileInfo );
}
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Version.php b/vendor/wikimedia/less.php/lib/Less/Version.php
index 388594983..1c96e8e08 100644
--- a/vendor/wikimedia/less.php/lib/Less/Version.php
+++ b/vendor/wikimedia/less.php/lib/Less/Version.php
@@ -2,14 +2,11 @@
/**
* Release numbers
- *
- * @package Less
- * @subpackage version
*/
-class Less_Version{
+class Less_Version {
- const version = '1.8.3'; // The current build number of less.php
- const less_version = '2.5.3'; // The less.js version that this build should be compatible with
- const cache_version = '253'; // The parser cache version
+ public const version = '3.2.1'; // The current build number of less.php
+ public const less_version = '2.5.3'; // The less.js version that this build should be compatible with
+ public const cache_version = '253'; // The parser cache version
}
diff --git a/vendor/wikimedia/less.php/lib/Less/Visitor.php b/vendor/wikimedia/less.php/lib/Less/Visitor.php
index d85f1d910..582f3233c 100644
--- a/vendor/wikimedia/less.php/lib/Less/Visitor.php
+++ b/vendor/wikimedia/less.php/lib/Less/Visitor.php
@@ -1,49 +1,44 @@
_visitFnCache = get_class_methods(get_class($this));
- $this->_visitFnCache = array_flip($this->_visitFnCache);
+ public function __construct() {
+ $this->_visitFnCache = get_class_methods( get_class( $this ) );
+ $this->_visitFnCache = array_flip( $this->_visitFnCache );
}
- public function visitObj( $node ){
-
- $funcName = 'visit'.$node->type;
- if( isset($this->_visitFnCache[$funcName]) ){
+ public function visitObj( $node ) {
+ $funcName = 'visit' . $node->type;
+ if ( isset( $this->_visitFnCache[$funcName] ) ) {
$visitDeeper = true;
$this->$funcName( $node, $visitDeeper );
- if( $visitDeeper ){
- $node->accept($this);
+ if ( $visitDeeper ) {
+ $node->accept( $this );
}
- $funcName = $funcName . "Out";
- if( isset($this->_visitFnCache[$funcName]) ){
+ $funcName .= "Out";
+ if ( isset( $this->_visitFnCache[$funcName] ) ) {
$this->$funcName( $node );
}
- }else{
- $node->accept($this);
+ } else {
+ $node->accept( $this );
}
return $node;
}
- public function visitArray( $nodes ){
-
- array_map( array($this,'visitObj'), $nodes);
+ public function visitArray( $nodes ) {
+ foreach ( $nodes as $node ) {
+ $this->visitObj( $node );
+ }
return $nodes;
}
}
-
diff --git a/vendor/wikimedia/less.php/lib/Less/Visitor/extendFinder.php b/vendor/wikimedia/less.php/lib/Less/Visitor/extendFinder.php
index 22b3aac99..8b3238da3 100644
--- a/vendor/wikimedia/less.php/lib/Less/Visitor/extendFinder.php
+++ b/vendor/wikimedia/less.php/lib/Less/Visitor/extendFinder.php
@@ -1,114 +1,105 @@
contexts = array();
- $this->allExtendsStack = array(array());
+ public function __construct() {
+ $this->contexts = [];
+ $this->allExtendsStack = [ [] ];
parent::__construct();
}
/**
* @param Less_Tree_Ruleset $root
*/
- public function run($root){
- $root = $this->visitObj($root);
+ public function run( $root ) {
+ $root = $this->visitObj( $root );
$root->allExtends =& $this->allExtendsStack[0];
return $root;
}
- public function visitRule($ruleNode, &$visitDeeper ){
+ public function visitRule( $ruleNode, &$visitDeeper ) {
$visitDeeper = false;
}
- public function visitMixinDefinition( $mixinDefinitionNode, &$visitDeeper ){
+ public function visitMixinDefinition( $mixinDefinitionNode, &$visitDeeper ) {
$visitDeeper = false;
}
- public function visitRuleset($rulesetNode){
-
- if( $rulesetNode->root ){
+ public function visitRuleset( $rulesetNode ) {
+ if ( $rulesetNode->root ) {
return;
}
- $allSelectorsExtendList = array();
+ $allSelectorsExtendList = [];
// get &:extend(.a); rules which apply to all selectors in this ruleset
- if( $rulesetNode->rules ){
- foreach($rulesetNode->rules as $rule){
- if( $rule instanceof Less_Tree_Extend ){
+ if ( $rulesetNode->rules ) {
+ foreach ( $rulesetNode->rules as $rule ) {
+ if ( $rule instanceof Less_Tree_Extend ) {
$allSelectorsExtendList[] = $rule;
$rulesetNode->extendOnEveryPath = true;
}
}
}
-
// now find every selector and apply the extends that apply to all extends
// and the ones which apply to an individual extend
- foreach($rulesetNode->paths as $selectorPath){
- $selector = end($selectorPath); //$selectorPath[ count($selectorPath)-1];
+ foreach ( $rulesetNode->paths as $selectorPath ) {
+ $selector = end( $selectorPath ); // $selectorPath[ count($selectorPath)-1];
$j = 0;
- foreach($selector->extendList as $extend){
- $this->allExtendsStackPush($rulesetNode, $selectorPath, $extend, $j);
+ foreach ( $selector->extendList as $extend ) {
+ $this->allExtendsStackPush( $rulesetNode, $selectorPath, $extend, $j );
}
- foreach($allSelectorsExtendList as $extend){
- $this->allExtendsStackPush($rulesetNode, $selectorPath, $extend, $j);
+ foreach ( $allSelectorsExtendList as $extend ) {
+ $this->allExtendsStackPush( $rulesetNode, $selectorPath, $extend, $j );
}
}
$this->contexts[] = $rulesetNode->selectors;
}
- public function allExtendsStackPush($rulesetNode, $selectorPath, $extend, &$j){
+ public function allExtendsStackPush( $rulesetNode, $selectorPath, $extend, &$j ) {
$this->foundExtends = true;
$extend = clone $extend;
$extend->findSelfSelectors( $selectorPath );
$extend->ruleset = $rulesetNode;
- if( $j === 0 ){
+ if ( $j === 0 ) {
$extend->firstExtendOnThisSelectorPath = true;
}
- $end_key = count($this->allExtendsStack)-1;
+ $end_key = count( $this->allExtendsStack ) - 1;
$this->allExtendsStack[$end_key][] = $extend;
$j++;
}
-
- public function visitRulesetOut( $rulesetNode ){
- if( !is_object($rulesetNode) || !$rulesetNode->root ){
- array_pop($this->contexts);
+ public function visitRulesetOut( $rulesetNode ) {
+ if ( !is_object( $rulesetNode ) || !$rulesetNode->root ) {
+ array_pop( $this->contexts );
}
}
- public function visitMedia( $mediaNode ){
- $mediaNode->allExtends = array();
+ public function visitMedia( $mediaNode ) {
+ $mediaNode->allExtends = [];
$this->allExtendsStack[] =& $mediaNode->allExtends;
}
- public function visitMediaOut(){
- array_pop($this->allExtendsStack);
+ public function visitMediaOut() {
+ array_pop( $this->allExtendsStack );
}
- public function visitDirective( $directiveNode ){
- $directiveNode->allExtends = array();
+ public function visitDirective( $directiveNode ) {
+ $directiveNode->allExtends = [];
$this->allExtendsStack[] =& $directiveNode->allExtends;
}
- public function visitDirectiveOut(){
- array_pop($this->allExtendsStack);
+ public function visitDirectiveOut() {
+ array_pop( $this->allExtendsStack );
}
}
-
-
diff --git a/vendor/wikimedia/less.php/lib/Less/Visitor/import.php b/vendor/wikimedia/less.php/lib/Less/Visitor/import.php
index f79a36dac..7af96ebd1 100644
--- a/vendor/wikimedia/less.php/lib/Less/Visitor/import.php
+++ b/vendor/wikimedia/less.php/lib/Less/Visitor/import.php
@@ -135,5 +135,3 @@ class Less_Visitor_import extends Less_VisitorReplacing{
}
*/
-
-
diff --git a/vendor/wikimedia/less.php/lib/Less/Visitor/joinSelector.php b/vendor/wikimedia/less.php/lib/Less/Visitor/joinSelector.php
index f62af1a98..a10683048 100644
--- a/vendor/wikimedia/less.php/lib/Less/Visitor/joinSelector.php
+++ b/vendor/wikimedia/less.php/lib/Less/Visitor/joinSelector.php
@@ -1,70 +1,67 @@
visitObj($root);
+ public function run( $root ) {
+ return $this->visitObj( $root );
}
- public function visitRule( $ruleNode, &$visitDeeper ){
+ public function visitRule( $ruleNode, &$visitDeeper ) {
$visitDeeper = false;
}
- public function visitMixinDefinition( $mixinDefinitionNode, &$visitDeeper ){
+ public function visitMixinDefinition( $mixinDefinitionNode, &$visitDeeper ) {
$visitDeeper = false;
}
- public function visitRuleset( $rulesetNode ){
+ public function visitRuleset( $rulesetNode ) {
+ $context = end( $this->contexts );
+ $paths = [];
- $paths = array();
-
- if( !$rulesetNode->root ){
- $selectors = array();
-
- if( $rulesetNode->selectors && $rulesetNode->selectors ){
- foreach($rulesetNode->selectors as $selector){
- if( $selector->getIsOutput() ){
- $selectors[] = $selector;
+ if ( !$rulesetNode->root ) {
+ $selectors = $rulesetNode->selectors;
+ if ( $selectors !== null ) {
+ $filtered = [];
+ foreach ( $selectors as $selector ) {
+ if ( $selector->getIsOutput() ) {
+ $filtered[] = $selector;
}
}
+ $selectors = $rulesetNode->selectors = $filtered ?: null;
+ if ( $selectors ) {
+ $paths = $rulesetNode->joinSelectors( $context, $selectors );
+ }
}
- if( !$selectors ){
- $rulesetNode->selectors = null;
+ if ( $selectors === null ) {
$rulesetNode->rules = null;
- }else{
- $context = end($this->contexts); //$context = $this->contexts[ count($this->contexts) - 1];
- $paths = $rulesetNode->joinSelectors( $context, $selectors);
}
$rulesetNode->paths = $paths;
}
- $this->contexts[] = $paths; //different from less.js. Placed after joinSelectors() so that $this->contexts will get correct $paths
+ // NOTE: Assigned here instead of at the start like less.js,
+ // because PHP arrays aren't by-ref
+ $this->contexts[] = $paths;
}
- public function visitRulesetOut(){
- array_pop($this->contexts);
+ public function visitRulesetOut() {
+ array_pop( $this->contexts );
}
- public function visitMedia($mediaNode) {
- $context = end($this->contexts); //$context = $this->contexts[ count($this->contexts) - 1];
+ public function visitMedia( $mediaNode ) {
+ $context = end( $this->contexts );
- if( !count($context) || (is_object($context[0]) && $context[0]->multiMedia) ){
+ if ( count( $context ) === 0 || ( is_object( $context[0] ) && $context[0]->multiMedia ) ) {
$mediaNode->rules[0]->root = true;
}
}
}
-
diff --git a/vendor/wikimedia/less.php/lib/Less/Visitor/processExtends.php b/vendor/wikimedia/less.php/lib/Less/Visitor/processExtends.php
index bb5f08246..9491f3c65 100644
--- a/vendor/wikimedia/less.php/lib/Less/Visitor/processExtends.php
+++ b/vendor/wikimedia/less.php/lib/Less/Visitor/processExtends.php
@@ -1,34 +1,30 @@
run( $root );
- if( !$extendFinder->foundExtends){
+ if ( !$extendFinder->foundExtends ) {
return $root;
}
- $root->allExtends = $this->doExtendChaining( $root->allExtends, $root->allExtends);
+ $root->allExtends = $this->doExtendChaining( $root->allExtends, $root->allExtends );
- $this->allExtendsStack = array();
+ $this->allExtendsStack = [];
$this->allExtendsStack[] = &$root->allExtends;
return $this->visitObj( $root );
}
- private function doExtendChaining( $extendsList, $extendsListTarget, $iterationCount = 0){
+ private function doExtendChaining( $extendsList, $extendsListTarget, $iterationCount = 0 ) {
//
// chaining is different from normal extension.. if we extend an extend then we are not just copying, altering and pasting
// the selector we would do normally, but we are also adding an extend with the same target selector
@@ -38,59 +34,57 @@ class Less_Visitor_processExtends extends Less_Visitor{
// this is also the most expensive.. and a match on one selector can cause an extension of a selector we had already processed if
// we look at each selector at a time, as is done in visitRuleset
- $extendsToAdd = array();
+ $extendsToAdd = [];
-
- //loop through comparing every extend with every target extend.
+ // loop through comparing every extend with every target extend.
// a target extend is the one on the ruleset we are looking at copy/edit/pasting in place
// e.g. .a:extend(.b) {} and .b:extend(.c) {} then the first extend extends the second one
// and the second is the target.
// the separation into two lists allows us to process a subset of chains with a bigger set, as is the
// case when processing media queries
- for( $extendIndex = 0, $extendsList_len = count($extendsList); $extendIndex < $extendsList_len; $extendIndex++ ){
- for( $targetExtendIndex = 0; $targetExtendIndex < count($extendsListTarget); $targetExtendIndex++ ){
+ for ( $extendIndex = 0, $extendsList_len = count( $extendsList ); $extendIndex < $extendsList_len; $extendIndex++ ) {
+ for ( $targetExtendIndex = 0; $targetExtendIndex < count( $extendsListTarget ); $targetExtendIndex++ ) {
$extend = $extendsList[$extendIndex];
$targetExtend = $extendsListTarget[$targetExtendIndex];
- // look for circular references
- if( in_array($targetExtend->object_id, $extend->parent_ids,true) ){
+ // Optimisation: Explicit reference,
+ if ( \array_key_exists( $targetExtend->object_id, $extend->parent_ids ) ) {
+ // ignore circular references
continue;
}
// find a match in the target extends self selector (the bit before :extend)
- $selectorPath = array( $targetExtend->selfSelectors[0] );
- $matches = $this->findMatch( $extend, $selectorPath);
+ $selectorPath = [ $targetExtend->selfSelectors[0] ];
+ $matches = $this->findMatch( $extend, $selectorPath );
-
- if( $matches ){
+ if ( $matches ) {
// we found a match, so for each self selector..
- foreach($extend->selfSelectors as $selfSelector ){
-
+ foreach ( $extend->selfSelectors as $selfSelector ) {
// process the extend as usual
- $newSelector = $this->extendSelector( $matches, $selectorPath, $selfSelector);
+ $newSelector = $this->extendSelector( $matches, $selectorPath, $selfSelector );
// but now we create a new extend from it
- $newExtend = new Less_Tree_Extend( $targetExtend->selector, $targetExtend->option, 0);
+ $newExtend = new Less_Tree_Extend( $targetExtend->selector, $targetExtend->option, 0 );
$newExtend->selfSelectors = $newSelector;
// add the extend onto the list of extends for that selector
- end($newSelector)->extendList = array($newExtend);
- //$newSelector[ count($newSelector)-1]->extendList = array($newExtend);
+ end( $newSelector )->extendList = [ $newExtend ];
+ // $newSelector[ count($newSelector)-1]->extendList = array($newExtend);
// record that we need to add it.
$extendsToAdd[] = $newExtend;
$newExtend->ruleset = $targetExtend->ruleset;
- //remember its parents for circular references
- $newExtend->parent_ids = array_merge($newExtend->parent_ids,$targetExtend->parent_ids,$extend->parent_ids);
+ // remember its parents for circular references
+ $newExtend->parent_ids = array_merge( $newExtend->parent_ids, $targetExtend->parent_ids, $extend->parent_ids );
// only process the selector once.. if we have :extend(.a,.b) then multiple
// extends will look at the same selector path, so when extending
// we know that any others will be duplicates in terms of what is added to the css
- if( $targetExtend->firstExtendOnThisSelectorPath ){
+ if ( $targetExtend->firstExtendOnThisSelectorPath ) {
$newExtend->firstExtendOnThisSelectorPath = true;
$targetExtend->ruleset->paths[] = $newSelector;
}
@@ -99,151 +93,144 @@ class Less_Visitor_processExtends extends Less_Visitor{
}
}
- if( $extendsToAdd ){
+ if ( $extendsToAdd ) {
// try to detect circular references to stop a stack overflow.
// may no longer be needed. $this->extendChainCount++;
- if( $iterationCount > 100) {
+ if ( $iterationCount > 100 ) {
try{
$selectorOne = $extendsToAdd[0]->selfSelectors[0]->toCSS();
$selectorTwo = $extendsToAdd[0]->selector->toCSS();
- }catch(Exception $e){
+ }catch ( Exception $e ) {
$selectorOne = "{unable to calculate}";
$selectorTwo = "{unable to calculate}";
}
- throw new Less_Exception_Parser("extend circular reference detected. One of the circular extends is currently:" . $selectorOne . ":extend(" . $selectorTwo . ")");
+ throw new Less_Exception_Parser( "extend circular reference detected. One of the circular extends is currently:" . $selectorOne . ":extend(" . $selectorTwo . ")" );
}
// now process the new extends on the existing rules so that we can handle a extending b extending c ectending d extending e...
- $extendsToAdd = $this->doExtendChaining( $extendsToAdd, $extendsListTarget, $iterationCount+1);
+ $extendsToAdd = $this->doExtendChaining( $extendsToAdd, $extendsListTarget, $iterationCount + 1 );
}
- return array_merge($extendsList, $extendsToAdd);
+ return array_merge( $extendsList, $extendsToAdd );
}
-
- protected function visitRule( $ruleNode, &$visitDeeper ){
+ protected function visitRule( $ruleNode, &$visitDeeper ) {
$visitDeeper = false;
}
- protected function visitMixinDefinition( $mixinDefinitionNode, &$visitDeeper ){
+ protected function visitMixinDefinition( $mixinDefinitionNode, &$visitDeeper ) {
$visitDeeper = false;
}
- protected function visitSelector( $selectorNode, &$visitDeeper ){
+ protected function visitSelector( $selectorNode, &$visitDeeper ) {
$visitDeeper = false;
}
- protected function visitRuleset($rulesetNode){
-
-
- if( $rulesetNode->root ){
+ protected function visitRuleset( $rulesetNode ) {
+ if ( $rulesetNode->root ) {
return;
}
- $allExtends = end($this->allExtendsStack);
- $paths_len = count($rulesetNode->paths);
+ $allExtends = end( $this->allExtendsStack );
+ $paths_len = count( $rulesetNode->paths );
// look at each selector path in the ruleset, find any extend matches and then copy, find and replace
- foreach($allExtends as $allExtend){
- for($pathIndex = 0; $pathIndex < $paths_len; $pathIndex++ ){
+ foreach ( $allExtends as $allExtend ) {
+ for ( $pathIndex = 0; $pathIndex < $paths_len; $pathIndex++ ) {
// extending extends happens initially, before the main pass
- if( isset($rulesetNode->extendOnEveryPath) && $rulesetNode->extendOnEveryPath ){
+ if ( isset( $rulesetNode->extendOnEveryPath ) && $rulesetNode->extendOnEveryPath ) {
continue;
}
$selectorPath = $rulesetNode->paths[$pathIndex];
- if( end($selectorPath)->extendList ){
+ if ( end( $selectorPath )->extendList ) {
continue;
}
- $this->ExtendMatch( $rulesetNode, $allExtend, $selectorPath);
+ $this->ExtendMatch( $rulesetNode, $allExtend, $selectorPath );
}
}
}
+ private function ExtendMatch( $rulesetNode, $extend, $selectorPath ) {
+ $matches = $this->findMatch( $extend, $selectorPath );
- private function ExtendMatch( $rulesetNode, $extend, $selectorPath ){
- $matches = $this->findMatch($extend, $selectorPath);
-
- if( $matches ){
- foreach($extend->selfSelectors as $selfSelector ){
- $rulesetNode->paths[] = $this->extendSelector($matches, $selectorPath, $selfSelector);
+ if ( $matches ) {
+ foreach ( $extend->selfSelectors as $selfSelector ) {
+ $rulesetNode->paths[] = $this->extendSelector( $matches, $selectorPath, $selfSelector );
}
}
}
-
-
- private function findMatch($extend, $haystackSelectorPath ){
-
-
- if( !$this->HasMatches($extend, $haystackSelectorPath) ){
+ /**
+ * @param Less_Tree_Extend $extend
+ * @param Less_Tree_Selector[] $haystackSelectorPath
+ * @return false|array
+ */
+ private function findMatch( $extend, $haystackSelectorPath ) {
+ if ( !$this->HasMatches( $extend, $haystackSelectorPath ) ) {
return false;
}
-
//
// look through the haystack selector path to try and find the needle - extend.selector
// returns an array of selector matches that can then be replaced
//
$needleElements = $extend->selector->elements;
- $potentialMatches = array();
+ $potentialMatches = [];
$potentialMatches_len = 0;
$potentialMatch = null;
- $matches = array();
-
-
+ $matches = [];
// loop through the haystack elements
- $haystack_path_len = count($haystackSelectorPath);
- for($haystackSelectorIndex = 0; $haystackSelectorIndex < $haystack_path_len; $haystackSelectorIndex++ ){
+ $haystack_path_len = count( $haystackSelectorPath );
+ for ( $haystackSelectorIndex = 0; $haystackSelectorIndex < $haystack_path_len; $haystackSelectorIndex++ ) {
$hackstackSelector = $haystackSelectorPath[$haystackSelectorIndex];
- $haystack_elements_len = count($hackstackSelector->elements);
- for($hackstackElementIndex = 0; $hackstackElementIndex < $haystack_elements_len; $hackstackElementIndex++ ){
+ $haystack_elements_len = count( $hackstackSelector->elements );
+ for ( $hackstackElementIndex = 0; $hackstackElementIndex < $haystack_elements_len; $hackstackElementIndex++ ) {
$haystackElement = $hackstackSelector->elements[$hackstackElementIndex];
// if we allow elements before our match we can add a potential match every time. otherwise only at the first element.
- if( $extend->allowBefore || ($haystackSelectorIndex === 0 && $hackstackElementIndex === 0) ){
- $potentialMatches[] = array('pathIndex'=> $haystackSelectorIndex, 'index'=> $hackstackElementIndex, 'matched'=> 0, 'initialCombinator'=> $haystackElement->combinator);
+ if ( $extend->allowBefore || ( $haystackSelectorIndex === 0 && $hackstackElementIndex === 0 ) ) {
+ $potentialMatches[] = [ 'pathIndex' => $haystackSelectorIndex, 'index' => $hackstackElementIndex, 'matched' => 0, 'initialCombinator' => $haystackElement->combinator ];
$potentialMatches_len++;
}
- for($i = 0; $i < $potentialMatches_len; $i++ ){
+ for ( $i = 0; $i < $potentialMatches_len; $i++ ) {
$potentialMatch = &$potentialMatches[$i];
$potentialMatch = $this->PotentialMatch( $potentialMatch, $needleElements, $haystackElement, $hackstackElementIndex );
-
// if we are still valid and have finished, test whether we have elements after and whether these are allowed
- if( $potentialMatch && $potentialMatch['matched'] === $extend->selector->elements_len ){
+ if ( $potentialMatch && $potentialMatch['matched'] === $extend->selector->elements_len ) {
$potentialMatch['finished'] = true;
- if( !$extend->allowAfter && ($hackstackElementIndex+1 < $haystack_elements_len || $haystackSelectorIndex+1 < $haystack_path_len) ){
+ if ( !$extend->allowAfter && ( $hackstackElementIndex + 1 < $haystack_elements_len || $haystackSelectorIndex + 1 < $haystack_path_len ) ) {
$potentialMatch = null;
}
}
// if null we remove, if not, we are still valid, so either push as a valid match or continue
- if( $potentialMatch ){
- if( $potentialMatch['finished'] ){
+ if ( $potentialMatch ) {
+ if ( $potentialMatch['finished'] ) {
$potentialMatch['length'] = $extend->selector->elements_len;
$potentialMatch['endPathIndex'] = $haystackSelectorIndex;
$potentialMatch['endPathElementIndex'] = $hackstackElementIndex + 1; // index after end of match
- $potentialMatches = array(); // we don't allow matches to overlap, so start matching again
+ $potentialMatches = []; // we don't allow matches to overlap, so start matching again
$potentialMatches_len = 0;
$matches[] = $potentialMatch;
}
continue;
}
- array_splice($potentialMatches, $i, 1);
+ array_splice( $potentialMatches, $i, 1 );
$potentialMatches_len--;
$i--;
}
@@ -253,23 +240,22 @@ class Less_Visitor_processExtends extends Less_Visitor{
return $matches;
}
-
// Before going through all the nested loops, lets check to see if a match is possible
// Reduces Bootstrap 3.1 compile time from ~6.5s to ~5.6s
- private function HasMatches($extend, $haystackSelectorPath){
-
- if( !$extend->selector->cacheable ){
+ private function HasMatches( $extend, $haystackSelectorPath ) {
+ if ( !$extend->selector->cacheable ) {
return true;
}
$first_el = $extend->selector->_oelements[0];
- foreach($haystackSelectorPath as $hackstackSelector){
- if( !$hackstackSelector->cacheable ){
+ foreach ( $haystackSelectorPath as $hackstackSelector ) {
+ if ( !$hackstackSelector->cacheable ) {
return true;
}
- if( in_array($first_el, $hackstackSelector->_oelements) ){
+ // Optimisation: Explicit reference,
+ if ( \array_key_exists( $first_el, $hackstackSelector->_oelements_assoc ) ) {
return true;
}
}
@@ -277,30 +263,27 @@ class Less_Visitor_processExtends extends Less_Visitor{
return false;
}
-
/**
- * @param integer $hackstackElementIndex
+ * @param int $hackstackElementIndex
*/
- private function PotentialMatch( $potentialMatch, $needleElements, $haystackElement, $hackstackElementIndex ){
-
-
- if( $potentialMatch['matched'] > 0 ){
+ private function PotentialMatch( $potentialMatch, $needleElements, $haystackElement, $hackstackElementIndex ) {
+ if ( $potentialMatch['matched'] > 0 ) {
// selectors add " " onto the first element. When we use & it joins the selectors together, but if we don't
// then each selector in haystackSelectorPath has a space before it added in the toCSS phase. so we need to work out
// what the resulting combinator will be
$targetCombinator = $haystackElement->combinator;
- if( $targetCombinator === '' && $hackstackElementIndex === 0 ){
+ if ( $targetCombinator === '' && $hackstackElementIndex === 0 ) {
$targetCombinator = ' ';
}
- if( $needleElements[ $potentialMatch['matched'] ]->combinator !== $targetCombinator ){
+ if ( $needleElements[ $potentialMatch['matched'] ]->combinator !== $targetCombinator ) {
return null;
}
}
// if we don't match, null our match to indicate failure
- if( !$this->isElementValuesEqual( $needleElements[$potentialMatch['matched'] ]->value, $haystackElement->value) ){
+ if ( !$this->isElementValuesEqual( $needleElements[$potentialMatch['matched'] ]->value, $haystackElement->value ) ) {
return null;
}
@@ -310,49 +293,50 @@ class Less_Visitor_processExtends extends Less_Visitor{
return $potentialMatch;
}
-
- private function isElementValuesEqual( $elementValue1, $elementValue2 ){
-
- if( $elementValue1 === $elementValue2 ){
+ /**
+ * @param string|Less_Tree_Attribute|Less_Tree_Dimension|Less_Tree_Keyword $elementValue1
+ * @param string|Less_Tree_Attribute|Less_Tree_Dimension|Less_Tree_Keyword $elementValue2
+ * @return bool
+ */
+ private function isElementValuesEqual( $elementValue1, $elementValue2 ) {
+ if ( $elementValue1 === $elementValue2 ) {
return true;
}
- if( is_string($elementValue1) || is_string($elementValue2) ) {
+ if ( is_string( $elementValue1 ) || is_string( $elementValue2 ) ) {
return false;
}
- if( $elementValue1 instanceof Less_Tree_Attribute ){
+ if ( $elementValue1 instanceof Less_Tree_Attribute ) {
return $this->isAttributeValuesEqual( $elementValue1, $elementValue2 );
}
$elementValue1 = $elementValue1->value;
- if( $elementValue1 instanceof Less_Tree_Selector ){
+ if ( $elementValue1 instanceof Less_Tree_Selector ) {
return $this->isSelectorValuesEqual( $elementValue1, $elementValue2 );
}
return false;
}
-
/**
* @param Less_Tree_Selector $elementValue1
*/
- private function isSelectorValuesEqual( $elementValue1, $elementValue2 ){
-
+ private function isSelectorValuesEqual( $elementValue1, $elementValue2 ) {
$elementValue2 = $elementValue2->value;
- if( !($elementValue2 instanceof Less_Tree_Selector) || $elementValue1->elements_len !== $elementValue2->elements_len ){
+ if ( !( $elementValue2 instanceof Less_Tree_Selector ) || $elementValue1->elements_len !== $elementValue2->elements_len ) {
return false;
}
- for( $i = 0; $i < $elementValue1->elements_len; $i++ ){
+ for ( $i = 0; $i < $elementValue1->elements_len; $i++ ) {
- if( $elementValue1->elements[$i]->combinator !== $elementValue2->elements[$i]->combinator ){
- if( $i !== 0 || ($elementValue1->elements[$i]->combinator || ' ') !== ($elementValue2->elements[$i]->combinator || ' ') ){
+ if ( $elementValue1->elements[$i]->combinator !== $elementValue2->elements[$i]->combinator ) {
+ if ( $i !== 0 || ( $elementValue1->elements[$i]->combinator || ' ' ) !== ( $elementValue2->elements[$i]->combinator || ' ' ) ) {
return false;
}
}
- if( !$this->isElementValuesEqual($elementValue1->elements[$i]->value, $elementValue2->elements[$i]->value) ){
+ if ( !$this->isElementValuesEqual( $elementValue1->elements[$i]->value, $elementValue2->elements[$i]->value ) ) {
return false;
}
}
@@ -360,41 +344,36 @@ class Less_Visitor_processExtends extends Less_Visitor{
return true;
}
-
/**
* @param Less_Tree_Attribute $elementValue1
*/
- private function isAttributeValuesEqual( $elementValue1, $elementValue2 ){
-
- if( $elementValue1->op !== $elementValue2->op || $elementValue1->key !== $elementValue2->key ){
+ private function isAttributeValuesEqual( $elementValue1, $elementValue2 ) {
+ if ( $elementValue1->op !== $elementValue2->op || $elementValue1->key !== $elementValue2->key ) {
return false;
}
- if( !$elementValue1->value || !$elementValue2->value ){
- if( $elementValue1->value || $elementValue2->value ) {
+ if ( !$elementValue1->value || !$elementValue2->value ) {
+ if ( $elementValue1->value || $elementValue2->value ) {
return false;
}
return true;
}
- $elementValue1 = ($elementValue1->value->value ? $elementValue1->value->value : $elementValue1->value );
- $elementValue2 = ($elementValue2->value->value ? $elementValue2->value->value : $elementValue2->value );
+ $elementValue1 = ( $elementValue1->value->value ?: $elementValue1->value );
+ $elementValue2 = ( $elementValue2->value->value ?: $elementValue2->value );
return $elementValue1 === $elementValue2;
}
-
- private function extendSelector($matches, $selectorPath, $replacementSelector){
-
- //for a set of matches, replace each match with the replacement selector
+ private function extendSelector( $matches, $selectorPath, $replacementSelector ) {
+ // for a set of matches, replace each match with the replacement selector
$currentSelectorPathIndex = 0;
$currentSelectorPathElementIndex = 0;
- $path = array();
- $selectorPath_len = count($selectorPath);
-
- for($matchIndex = 0, $matches_len = count($matches); $matchIndex < $matches_len; $matchIndex++ ){
+ $path = [];
+ $selectorPath_len = count( $selectorPath );
+ for ( $matchIndex = 0, $matches_len = count( $matches ); $matchIndex < $matches_len; $matchIndex++ ) {
$match = $matches[$matchIndex];
$selector = $selectorPath[ $match['pathIndex'] ];
@@ -406,64 +385,63 @@ class Less_Visitor_processExtends extends Less_Visitor{
$replacementSelector->elements[0]->currentFileInfo
);
- if( $match['pathIndex'] > $currentSelectorPathIndex && $currentSelectorPathElementIndex > 0 ){
- $last_path = end($path);
- $last_path->elements = array_merge( $last_path->elements, array_slice( $selectorPath[$currentSelectorPathIndex]->elements, $currentSelectorPathElementIndex));
+ if ( $match['pathIndex'] > $currentSelectorPathIndex && $currentSelectorPathElementIndex > 0 ) {
+ $last_path = end( $path );
+ $last_path->elements = array_merge( $last_path->elements, array_slice( $selectorPath[$currentSelectorPathIndex]->elements, $currentSelectorPathElementIndex ) );
$currentSelectorPathElementIndex = 0;
$currentSelectorPathIndex++;
}
$newElements = array_merge(
- array_slice($selector->elements, $currentSelectorPathElementIndex, ($match['index'] - $currentSelectorPathElementIndex) ) // last parameter of array_slice is different than the last parameter of javascript's slice
- , array($firstElement)
- , array_slice($replacementSelector->elements,1)
+ array_slice( $selector->elements, $currentSelectorPathElementIndex, ( $match['index'] - $currentSelectorPathElementIndex ) ), // last parameter of array_slice is different than the last parameter of javascript's slice
+ [ $firstElement ],
+ array_slice( $replacementSelector->elements, 1 )
);
- if( $currentSelectorPathIndex === $match['pathIndex'] && $matchIndex > 0 ){
- $last_key = count($path)-1;
- $path[$last_key]->elements = array_merge($path[$last_key]->elements,$newElements);
- }else{
- $path = array_merge( $path, array_slice( $selectorPath, $currentSelectorPathIndex, $match['pathIndex'] ));
+ if ( $currentSelectorPathIndex === $match['pathIndex'] && $matchIndex > 0 ) {
+ $last_key = count( $path ) - 1;
+ $path[$last_key]->elements = array_merge( $path[$last_key]->elements, $newElements );
+ } else {
+ $path = array_merge( $path, array_slice( $selectorPath, $currentSelectorPathIndex, $match['pathIndex'] ) );
$path[] = new Less_Tree_Selector( $newElements );
}
$currentSelectorPathIndex = $match['endPathIndex'];
$currentSelectorPathElementIndex = $match['endPathElementIndex'];
- if( $currentSelectorPathElementIndex >= count($selectorPath[$currentSelectorPathIndex]->elements) ){
+ if ( $currentSelectorPathElementIndex >= count( $selectorPath[$currentSelectorPathIndex]->elements ) ) {
$currentSelectorPathElementIndex = 0;
$currentSelectorPathIndex++;
}
}
- if( $currentSelectorPathIndex < $selectorPath_len && $currentSelectorPathElementIndex > 0 ){
- $last_path = end($path);
- $last_path->elements = array_merge( $last_path->elements, array_slice($selectorPath[$currentSelectorPathIndex]->elements, $currentSelectorPathElementIndex));
+ if ( $currentSelectorPathIndex < $selectorPath_len && $currentSelectorPathElementIndex > 0 ) {
+ $last_path = end( $path );
+ $last_path->elements = array_merge( $last_path->elements, array_slice( $selectorPath[$currentSelectorPathIndex]->elements, $currentSelectorPathElementIndex ) );
$currentSelectorPathIndex++;
}
$slice_len = $selectorPath_len - $currentSelectorPathIndex;
- $path = array_merge($path, array_slice($selectorPath, $currentSelectorPathIndex, $slice_len));
+ $path = array_merge( $path, array_slice( $selectorPath, $currentSelectorPathIndex, $slice_len ) );
return $path;
}
-
- protected function visitMedia( $mediaNode ){
- $newAllExtends = array_merge( $mediaNode->allExtends, end($this->allExtendsStack) );
- $this->allExtendsStack[] = $this->doExtendChaining($newAllExtends, $mediaNode->allExtends);
+ protected function visitMedia( $mediaNode ) {
+ $newAllExtends = array_merge( $mediaNode->allExtends, end( $this->allExtendsStack ) );
+ $this->allExtendsStack[] = $this->doExtendChaining( $newAllExtends, $mediaNode->allExtends );
}
- protected function visitMediaOut(){
+ protected function visitMediaOut() {
array_pop( $this->allExtendsStack );
}
- protected function visitDirective( $directiveNode ){
- $newAllExtends = array_merge( $directiveNode->allExtends, end($this->allExtendsStack) );
- $this->allExtendsStack[] = $this->doExtendChaining($newAllExtends, $directiveNode->allExtends);
+ protected function visitDirective( $directiveNode ) {
+ $newAllExtends = array_merge( $directiveNode->allExtends, end( $this->allExtendsStack ) );
+ $this->allExtendsStack[] = $this->doExtendChaining( $newAllExtends, $directiveNode->allExtends );
}
- protected function visitDirectiveOut(){
- array_pop($this->allExtendsStack);
+ protected function visitDirectiveOut() {
+ array_pop( $this->allExtendsStack );
}
-}
\ No newline at end of file
+}
diff --git a/vendor/wikimedia/less.php/lib/Less/Visitor/toCSS.php b/vendor/wikimedia/less.php/lib/Less/Visitor/toCSS.php
index 8aaca9637..6c476d294 100644
--- a/vendor/wikimedia/less.php/lib/Less/Visitor/toCSS.php
+++ b/vendor/wikimedia/less.php/lib/Less/Visitor/toCSS.php
@@ -1,188 +1,174 @@
visitObj($root);
+ public function run( $root ) {
+ return $this->visitObj( $root );
}
- public function visitRule( $ruleNode ){
- if( $ruleNode->variable ){
- return array();
+ public function visitRule( $ruleNode ) {
+ if ( $ruleNode->variable ) {
+ return [];
}
return $ruleNode;
}
- public function visitMixinDefinition($mixinNode){
+ public function visitMixinDefinition( $mixinNode ) {
// mixin definitions do not get eval'd - this means they keep state
// so we have to clear that state here so it isn't used if toCSS is called twice
- $mixinNode->frames = array();
- return array();
+ $mixinNode->frames = [];
+ return [];
}
- public function visitExtend(){
- return array();
+ public function visitExtend() {
+ return [];
}
- public function visitComment( $commentNode ){
- if( $commentNode->isSilent() ){
- return array();
+ public function visitComment( $commentNode ) {
+ if ( $commentNode->isSilent() ) {
+ return [];
}
return $commentNode;
}
- public function visitMedia( $mediaNode, &$visitDeeper ){
- $mediaNode->accept($this);
+ public function visitMedia( $mediaNode, &$visitDeeper ) {
+ $mediaNode->accept( $this );
$visitDeeper = false;
- if( !$mediaNode->rules ){
- return array();
+ if ( !$mediaNode->rules ) {
+ return [];
}
return $mediaNode;
}
- public function visitDirective( $directiveNode ){
- if( isset($directiveNode->currentFileInfo['reference']) && (!property_exists($directiveNode,'isReferenced') || !$directiveNode->isReferenced) ){
- return array();
+ public function visitDirective( $directiveNode ) {
+ if ( isset( $directiveNode->currentFileInfo['reference'] ) && ( !property_exists( $directiveNode, 'isReferenced' ) || !$directiveNode->isReferenced ) ) {
+ return [];
}
- if( $directiveNode->name === '@charset' ){
+ if ( $directiveNode->name === '@charset' ) {
// Only output the debug info together with subsequent @charset definitions
// a comment (or @media statement) before the actual @charset directive would
// be considered illegal css as it has to be on the first line
- if( isset($this->charset) && $this->charset ){
+ if ( isset( $this->charset ) && $this->charset ) {
- //if( $directiveNode->debugInfo ){
+ // if( $directiveNode->debugInfo ){
// $comment = new Less_Tree_Comment('/* ' . str_replace("\n",'',$directiveNode->toCSS())." */\n");
// $comment->debugInfo = $directiveNode->debugInfo;
// return $this->visit($comment);
//}
-
- return array();
+ return [];
}
$this->charset = true;
}
return $directiveNode;
}
- public function checkPropertiesInRoot( $rulesetNode ){
-
- if( !$rulesetNode->firstRoot ){
+ public function checkPropertiesInRoot( $rulesetNode ) {
+ if ( !$rulesetNode->firstRoot ) {
return;
}
- foreach($rulesetNode->rules as $ruleNode){
- if( $ruleNode instanceof Less_Tree_Rule && !$ruleNode->variable ){
- $msg = "properties must be inside selector blocks, they cannot be in the root. Index ".$ruleNode->index.($ruleNode->currentFileInfo ? (' Filename: '.$ruleNode->currentFileInfo['filename']) : null);
- throw new Less_Exception_Compiler($msg);
+ foreach ( $rulesetNode->rules as $ruleNode ) {
+ if ( $ruleNode instanceof Less_Tree_Rule && !$ruleNode->variable ) {
+ $msg = "properties must be inside selector blocks, they cannot be in the root. Index " . $ruleNode->index . ( $ruleNode->currentFileInfo ? ( ' Filename: ' . $ruleNode->currentFileInfo['filename'] ) : null );
+ throw new Less_Exception_Compiler( $msg );
}
}
}
-
- public function visitRuleset( $rulesetNode, &$visitDeeper ){
-
+ public function visitRuleset( $rulesetNode, &$visitDeeper ) {
$visitDeeper = false;
$this->checkPropertiesInRoot( $rulesetNode );
- if( $rulesetNode->root ){
+ if ( $rulesetNode->root ) {
return $this->visitRulesetRoot( $rulesetNode );
}
- $rulesets = array();
- $rulesetNode->paths = $this->visitRulesetPaths($rulesetNode);
-
+ $rulesets = [];
+ $rulesetNode->paths = $this->visitRulesetPaths( $rulesetNode );
// Compile rules and rulesets
- $nodeRuleCnt = $rulesetNode->rules?count($rulesetNode->rules):0;
- for( $i = 0; $i < $nodeRuleCnt; ){
+ $nodeRuleCnt = $rulesetNode->rules ? count( $rulesetNode->rules ) : 0;
+ for ( $i = 0; $i < $nodeRuleCnt; ) {
$rule = $rulesetNode->rules[$i];
- if( property_exists($rule,'rules') ){
+ if ( property_exists( $rule, 'rules' ) ) {
// visit because we are moving them out from being a child
- $rulesets[] = $this->visitObj($rule);
- array_splice($rulesetNode->rules,$i,1);
+ $rulesets[] = $this->visitObj( $rule );
+ array_splice( $rulesetNode->rules, $i, 1 );
$nodeRuleCnt--;
continue;
}
$i++;
}
-
// accept the visitor to remove rules and refactor itself
// then we can decide now whether we want it or not
- if( $nodeRuleCnt > 0 ){
- $rulesetNode->accept($this);
+ if ( $nodeRuleCnt > 0 ) {
+ $rulesetNode->accept( $this );
- if( $rulesetNode->rules ){
+ if ( $rulesetNode->rules ) {
- if( count($rulesetNode->rules) > 1 ){
+ if ( count( $rulesetNode->rules ) > 1 ) {
$this->_mergeRules( $rulesetNode->rules );
$this->_removeDuplicateRules( $rulesetNode->rules );
}
// now decide whether we keep the ruleset
- if( $rulesetNode->paths ){
- //array_unshift($rulesets, $rulesetNode);
- array_splice($rulesets,0,0,array($rulesetNode));
+ if ( $rulesetNode->paths ) {
+ // array_unshift($rulesets, $rulesetNode);
+ array_splice( $rulesets, 0, 0, [ $rulesetNode ] );
}
}
}
-
- if( count($rulesets) === 1 ){
+ if ( count( $rulesets ) === 1 ) {
return $rulesets[0];
}
return $rulesets;
}
-
/**
* Helper function for visitiRuleset
*
* return array|Less_Tree_Ruleset
*/
- private function visitRulesetRoot( $rulesetNode ){
+ private function visitRulesetRoot( $rulesetNode ) {
$rulesetNode->accept( $this );
- if( $rulesetNode->firstRoot || $rulesetNode->rules ){
+ if ( $rulesetNode->firstRoot || $rulesetNode->rules ) {
return $rulesetNode;
}
- return array();
+ return [];
}
-
/**
* Helper function for visitRuleset()
*
* @return array
*/
- private function visitRulesetPaths($rulesetNode){
-
- $paths = array();
- foreach($rulesetNode->paths as $p){
- if( $p[0]->elements[0]->combinator === ' ' ){
+ private function visitRulesetPaths( $rulesetNode ) {
+ $paths = [];
+ foreach ( $rulesetNode->paths as $p ) {
+ if ( $p[0]->elements[0]->combinator === ' ' ) {
$p[0]->elements[0]->combinator = '';
}
- foreach($p as $pi){
- if( $pi->getIsReferenced() && $pi->getIsOutput() ){
+ foreach ( $p as $pi ) {
+ if ( $pi->getIsReferenced() && $pi->getIsOutput() ) {
$paths[] = $p;
break;
}
@@ -192,26 +178,26 @@ class Less_Visitor_toCSS extends Less_VisitorReplacing{
return $paths;
}
- protected function _removeDuplicateRules( &$rules ){
+ protected function _removeDuplicateRules( &$rules ) {
// remove duplicates
- $ruleCache = array();
- for( $i = count($rules)-1; $i >= 0 ; $i-- ){
+ $ruleCache = [];
+ for ( $i = count( $rules ) - 1; $i >= 0; $i-- ) {
$rule = $rules[$i];
- if( $rule instanceof Less_Tree_Rule || $rule instanceof Less_Tree_NameValue ){
+ if ( $rule instanceof Less_Tree_Rule || $rule instanceof Less_Tree_NameValue ) {
- if( !isset($ruleCache[$rule->name]) ){
+ if ( !isset( $ruleCache[$rule->name] ) ) {
$ruleCache[$rule->name] = $rule;
- }else{
+ } else {
$ruleList =& $ruleCache[$rule->name];
- if( $ruleList instanceof Less_Tree_Rule || $ruleList instanceof Less_Tree_NameValue ){
- $ruleList = $ruleCache[$rule->name] = array( $ruleCache[$rule->name]->toCSS() );
+ if ( $ruleList instanceof Less_Tree_Rule || $ruleList instanceof Less_Tree_NameValue ) {
+ $ruleList = $ruleCache[$rule->name] = [ $ruleCache[$rule->name]->toCSS() ];
}
$ruleCSS = $rule->toCSS();
- if( array_search($ruleCSS,$ruleList) !== false ){
- array_splice($rules,$i,1);
- }else{
+ if ( array_search( $ruleCSS, $ruleList ) !== false ) {
+ array_splice( $rules, $i, 1 );
+ } else {
$ruleList[] = $ruleCSS;
}
}
@@ -219,26 +205,26 @@ class Less_Visitor_toCSS extends Less_VisitorReplacing{
}
}
- protected function _mergeRules( &$rules ){
- $groups = array();
+ protected function _mergeRules( &$rules ) {
+ $groups = [];
- //obj($rules);
+ // obj($rules);
- $rules_len = count($rules);
- for( $i = 0; $i < $rules_len; $i++ ){
+ $rules_len = count( $rules );
+ for ( $i = 0; $i < $rules_len; $i++ ) {
$rule = $rules[$i];
- if( ($rule instanceof Less_Tree_Rule) && $rule->merge ){
+ if ( ( $rule instanceof Less_Tree_Rule ) && $rule->merge ) {
$key = $rule->name;
- if( $rule->important ){
+ if ( $rule->important ) {
$key .= ',!';
}
- if( !isset($groups[$key]) ){
- $groups[$key] = array();
- }else{
- array_splice($rules, $i--, 1);
+ if ( !isset( $groups[$key] ) ) {
+ $groups[$key] = [];
+ } else {
+ array_splice( $rules, $i--, 1 );
$rules_len--;
}
@@ -246,47 +232,44 @@ class Less_Visitor_toCSS extends Less_VisitorReplacing{
}
}
+ foreach ( $groups as $parts ) {
- foreach($groups as $parts){
-
- if( count($parts) > 1 ){
+ if ( count( $parts ) > 1 ) {
$rule = $parts[0];
- $spacedGroups = array();
- $lastSpacedGroup = array();
- $parts_mapped = array();
- foreach($parts as $p){
- if( $p->merge === '+' ){
- if( $lastSpacedGroup ){
- $spacedGroups[] = self::toExpression($lastSpacedGroup);
+ $spacedGroups = [];
+ $lastSpacedGroup = [];
+ $parts_mapped = [];
+ foreach ( $parts as $p ) {
+ if ( $p->merge === '+' ) {
+ if ( $lastSpacedGroup ) {
+ $spacedGroups[] = self::toExpression( $lastSpacedGroup );
}
- $lastSpacedGroup = array();
+ $lastSpacedGroup = [];
}
$lastSpacedGroup[] = $p;
}
- $spacedGroups[] = self::toExpression($lastSpacedGroup);
- $rule->value = self::toValue($spacedGroups);
+ $spacedGroups[] = self::toExpression( $lastSpacedGroup );
+ $rule->value = self::toValue( $spacedGroups );
}
}
-
}
- public static function toExpression($values){
- $mapped = array();
- foreach($values as $p){
+ public static function toExpression( $values ) {
+ $mapped = [];
+ foreach ( $values as $p ) {
$mapped[] = $p->value;
}
return new Less_Tree_Expression( $mapped );
}
- public static function toValue($values){
- //return new Less_Tree_Value($values); ??
+ public static function toValue( $values ) {
+ // return new Less_Tree_Value($values); ??
- $mapped = array();
- foreach($values as $p){
+ $mapped = [];
+ foreach ( $values as $p ) {
$mapped[] = $p;
}
- return new Less_Tree_Value($mapped);
+ return new Less_Tree_Value( $mapped );
}
}
-
diff --git a/vendor/wikimedia/less.php/lib/Less/VisitorReplacing.php b/vendor/wikimedia/less.php/lib/Less/VisitorReplacing.php
index 5923170e2..ae8b82e3c 100644
--- a/vendor/wikimedia/less.php/lib/Less/VisitorReplacing.php
+++ b/vendor/wikimedia/less.php/lib/Less/VisitorReplacing.php
@@ -1,48 +1,42 @@
type;
- if( isset($this->_visitFnCache[$funcName]) ){
+ public function visitObj( $node ) {
+ $funcName = 'visit' . $node->type;
+ if ( isset( $this->_visitFnCache[$funcName] ) ) {
$visitDeeper = true;
$node = $this->$funcName( $node, $visitDeeper );
- if( $node ){
- if( $visitDeeper && is_object($node) ){
- $node->accept($this);
+ if ( $node ) {
+ if ( $visitDeeper && is_object( $node ) ) {
+ $node->accept( $this );
}
- $funcName = $funcName . "Out";
- if( isset($this->_visitFnCache[$funcName]) ){
+ $funcName .= "Out";
+ if ( isset( $this->_visitFnCache[$funcName] ) ) {
$this->$funcName( $node );
}
}
- }else{
- $node->accept($this);
+ } else {
+ $node->accept( $this );
}
return $node;
}
- public function visitArray( $nodes ){
-
- $newNodes = array();
- foreach($nodes as $node){
- $evald = $this->visitObj($node);
- if( $evald ){
- if( is_array($evald) ){
- self::flatten($evald,$newNodes);
- }else{
+ public function visitArray( $nodes ) {
+ $newNodes = [];
+ foreach ( $nodes as $node ) {
+ $evald = $this->visitObj( $node );
+ if ( $evald ) {
+ if ( is_array( $evald ) ) {
+ self::flatten( $evald, $newNodes );
+ } else {
$newNodes[] = $evald;
}
}
@@ -50,18 +44,17 @@ class Less_VisitorReplacing extends Less_Visitor{
return $newNodes;
}
- public function flatten( $arr, &$out ){
-
- foreach($arr as $item){
- if( !is_array($item) ){
+ public function flatten( $arr, &$out ) {
+ foreach ( $arr as $item ) {
+ if ( !is_array( $item ) ) {
$out[] = $item;
continue;
}
- foreach($item as $nestedItem){
- if( is_array($nestedItem) ){
- self::flatten( $nestedItem, $out);
- }else{
+ foreach ( $item as $nestedItem ) {
+ if ( is_array( $nestedItem ) ) {
+ self::flatten( $nestedItem, $out );
+ } else {
$out[] = $nestedItem;
}
}
@@ -71,5 +64,3 @@ class Less_VisitorReplacing extends Less_Visitor{
}
}
-
-