@@ -13,13 +13,13 @@ |
||
| 13 | 13 | */ |
| 14 | 14 | class NetworkException extends TransferException implements PsrNetworkException |
| 15 | 15 | { |
| 16 | - use RequestAwareTrait; |
|
| 17 | - /** |
|
| 18 | - * @param string $message |
|
| 19 | - */ |
|
| 20 | - public function __construct($message, RequestInterface $request, ?\Exception $previous = null) |
|
| 21 | - { |
|
| 22 | - $this->setRequest($request); |
|
| 23 | - parent::__construct($message, 0, $previous); |
|
| 24 | - } |
|
| 16 | + use RequestAwareTrait; |
|
| 17 | + /** |
|
| 18 | + * @param string $message |
|
| 19 | + */ |
|
| 20 | + public function __construct($message, RequestInterface $request, ?\Exception $previous = null) |
|
| 21 | + { |
|
| 22 | + $this->setRequest($request); |
|
| 23 | + parent::__construct($message, 0, $previous); |
|
| 24 | + } |
|
| 25 | 25 | } |
@@ -14,13 +14,13 @@ |
||
| 14 | 14 | */ |
| 15 | 15 | class RequestException extends TransferException implements PsrRequestException |
| 16 | 16 | { |
| 17 | - use RequestAwareTrait; |
|
| 18 | - /** |
|
| 19 | - * @param string $message |
|
| 20 | - */ |
|
| 21 | - public function __construct($message, RequestInterface $request, ?\Exception $previous = null) |
|
| 22 | - { |
|
| 23 | - $this->setRequest($request); |
|
| 24 | - parent::__construct($message, 0, $previous); |
|
| 25 | - } |
|
| 17 | + use RequestAwareTrait; |
|
| 18 | + /** |
|
| 19 | + * @param string $message |
|
| 20 | + */ |
|
| 21 | + public function __construct($message, RequestInterface $request, ?\Exception $previous = null) |
|
| 22 | + { |
|
| 23 | + $this->setRequest($request); |
|
| 24 | + parent::__construct($message, 0, $previous); |
|
| 25 | + } |
|
| 26 | 26 | } |
@@ -5,16 +5,16 @@ |
||
| 5 | 5 | use OCA\FullTextSearch_Elasticsearch\Vendor\Psr\Http\Message\RequestInterface; |
| 6 | 6 | trait RequestAwareTrait |
| 7 | 7 | { |
| 8 | - /** |
|
| 9 | - * @var RequestInterface |
|
| 10 | - */ |
|
| 11 | - private $request; |
|
| 12 | - private function setRequest(RequestInterface $request) |
|
| 13 | - { |
|
| 14 | - $this->request = $request; |
|
| 15 | - } |
|
| 16 | - public function getRequest() : RequestInterface |
|
| 17 | - { |
|
| 18 | - return $this->request; |
|
| 19 | - } |
|
| 8 | + /** |
|
| 9 | + * @var RequestInterface |
|
| 10 | + */ |
|
| 11 | + private $request; |
|
| 12 | + private function setRequest(RequestInterface $request) |
|
| 13 | + { |
|
| 14 | + $this->request = $request; |
|
| 15 | + } |
|
| 16 | + public function getRequest() : RequestInterface |
|
| 17 | + { |
|
| 18 | + return $this->request; |
|
| 19 | + } |
|
| 20 | 20 | } |
@@ -13,34 +13,34 @@ |
||
| 13 | 13 | */ |
| 14 | 14 | class HttpException extends RequestException |
| 15 | 15 | { |
| 16 | - /** |
|
| 17 | - * @var ResponseInterface |
|
| 18 | - */ |
|
| 19 | - protected $response; |
|
| 20 | - /** |
|
| 21 | - * @param string $message |
|
| 22 | - */ |
|
| 23 | - public function __construct($message, RequestInterface $request, ResponseInterface $response, ?\Exception $previous = null) |
|
| 24 | - { |
|
| 25 | - parent::__construct($message, $request, $previous); |
|
| 26 | - $this->response = $response; |
|
| 27 | - $this->code = $response->getStatusCode(); |
|
| 28 | - } |
|
| 29 | - /** |
|
| 30 | - * Returns the response. |
|
| 31 | - * |
|
| 32 | - * @return ResponseInterface |
|
| 33 | - */ |
|
| 34 | - public function getResponse() |
|
| 35 | - { |
|
| 36 | - return $this->response; |
|
| 37 | - } |
|
| 38 | - /** |
|
| 39 | - * Factory method to create a new exception with a normalized error message. |
|
| 40 | - */ |
|
| 41 | - public static function create(RequestInterface $request, ResponseInterface $response, ?\Exception $previous = null) |
|
| 42 | - { |
|
| 43 | - $message = \sprintf('[url] %s [http method] %s [status code] %s [reason phrase] %s', $request->getRequestTarget(), $request->getMethod(), $response->getStatusCode(), $response->getReasonPhrase()); |
|
| 44 | - return new static($message, $request, $response, $previous); |
|
| 45 | - } |
|
| 16 | + /** |
|
| 17 | + * @var ResponseInterface |
|
| 18 | + */ |
|
| 19 | + protected $response; |
|
| 20 | + /** |
|
| 21 | + * @param string $message |
|
| 22 | + */ |
|
| 23 | + public function __construct($message, RequestInterface $request, ResponseInterface $response, ?\Exception $previous = null) |
|
| 24 | + { |
|
| 25 | + parent::__construct($message, $request, $previous); |
|
| 26 | + $this->response = $response; |
|
| 27 | + $this->code = $response->getStatusCode(); |
|
| 28 | + } |
|
| 29 | + /** |
|
| 30 | + * Returns the response. |
|
| 31 | + * |
|
| 32 | + * @return ResponseInterface |
|
| 33 | + */ |
|
| 34 | + public function getResponse() |
|
| 35 | + { |
|
| 36 | + return $this->response; |
|
| 37 | + } |
|
| 38 | + /** |
|
| 39 | + * Factory method to create a new exception with a normalized error message. |
|
| 40 | + */ |
|
| 41 | + public static function create(RequestInterface $request, ResponseInterface $response, ?\Exception $previous = null) |
|
| 42 | + { |
|
| 43 | + $message = \sprintf('[url] %s [http method] %s [status code] %s [reason phrase] %s', $request->getRequestTarget(), $request->getMethod(), $response->getStatusCode(), $response->getReasonPhrase()); |
|
| 44 | + return new static($message, $request, $response, $previous); |
|
| 45 | + } |
|
| 46 | 46 | } |
@@ -6,37 +6,37 @@ |
||
| 6 | 6 | use OCA\FullTextSearch_Elasticsearch\Vendor\Http\Promise\Promise; |
| 7 | 7 | final class HttpRejectedPromise implements Promise |
| 8 | 8 | { |
| 9 | - /** |
|
| 10 | - * @var Exception |
|
| 11 | - */ |
|
| 12 | - private $exception; |
|
| 13 | - public function __construct(Exception $exception) |
|
| 14 | - { |
|
| 15 | - $this->exception = $exception; |
|
| 16 | - } |
|
| 17 | - public function then(?callable $onFulfilled = null, ?callable $onRejected = null) |
|
| 18 | - { |
|
| 19 | - if (null === $onRejected) { |
|
| 20 | - return $this; |
|
| 21 | - } |
|
| 22 | - try { |
|
| 23 | - $result = $onRejected($this->exception); |
|
| 24 | - if ($result instanceof Promise) { |
|
| 25 | - return $result; |
|
| 26 | - } |
|
| 27 | - return new HttpFulfilledPromise($result); |
|
| 28 | - } catch (Exception $e) { |
|
| 29 | - return new self($e); |
|
| 30 | - } |
|
| 31 | - } |
|
| 32 | - public function getState() |
|
| 33 | - { |
|
| 34 | - return Promise::REJECTED; |
|
| 35 | - } |
|
| 36 | - public function wait($unwrap = \true) |
|
| 37 | - { |
|
| 38 | - if ($unwrap) { |
|
| 39 | - throw $this->exception; |
|
| 40 | - } |
|
| 41 | - } |
|
| 9 | + /** |
|
| 10 | + * @var Exception |
|
| 11 | + */ |
|
| 12 | + private $exception; |
|
| 13 | + public function __construct(Exception $exception) |
|
| 14 | + { |
|
| 15 | + $this->exception = $exception; |
|
| 16 | + } |
|
| 17 | + public function then(?callable $onFulfilled = null, ?callable $onRejected = null) |
|
| 18 | + { |
|
| 19 | + if (null === $onRejected) { |
|
| 20 | + return $this; |
|
| 21 | + } |
|
| 22 | + try { |
|
| 23 | + $result = $onRejected($this->exception); |
|
| 24 | + if ($result instanceof Promise) { |
|
| 25 | + return $result; |
|
| 26 | + } |
|
| 27 | + return new HttpFulfilledPromise($result); |
|
| 28 | + } catch (Exception $e) { |
|
| 29 | + return new self($e); |
|
| 30 | + } |
|
| 31 | + } |
|
| 32 | + public function getState() |
|
| 33 | + { |
|
| 34 | + return Promise::REJECTED; |
|
| 35 | + } |
|
| 36 | + public function wait($unwrap = \true) |
|
| 37 | + { |
|
| 38 | + if ($unwrap) { |
|
| 39 | + throw $this->exception; |
|
| 40 | + } |
|
| 41 | + } |
|
| 42 | 42 | } |
@@ -7,33 +7,33 @@ |
||
| 7 | 7 | use OCA\FullTextSearch_Elasticsearch\Vendor\Psr\Http\Message\ResponseInterface; |
| 8 | 8 | final class HttpFulfilledPromise implements Promise |
| 9 | 9 | { |
| 10 | - /** |
|
| 11 | - * @var ResponseInterface |
|
| 12 | - */ |
|
| 13 | - private $response; |
|
| 14 | - public function __construct(ResponseInterface $response) |
|
| 15 | - { |
|
| 16 | - $this->response = $response; |
|
| 17 | - } |
|
| 18 | - public function then(?callable $onFulfilled = null, ?callable $onRejected = null) |
|
| 19 | - { |
|
| 20 | - if (null === $onFulfilled) { |
|
| 21 | - return $this; |
|
| 22 | - } |
|
| 23 | - try { |
|
| 24 | - return new self($onFulfilled($this->response)); |
|
| 25 | - } catch (Exception $e) { |
|
| 26 | - return new HttpRejectedPromise($e); |
|
| 27 | - } |
|
| 28 | - } |
|
| 29 | - public function getState() |
|
| 30 | - { |
|
| 31 | - return Promise::FULFILLED; |
|
| 32 | - } |
|
| 33 | - public function wait($unwrap = \true) |
|
| 34 | - { |
|
| 35 | - if ($unwrap) { |
|
| 36 | - return $this->response; |
|
| 37 | - } |
|
| 38 | - } |
|
| 10 | + /** |
|
| 11 | + * @var ResponseInterface |
|
| 12 | + */ |
|
| 13 | + private $response; |
|
| 14 | + public function __construct(ResponseInterface $response) |
|
| 15 | + { |
|
| 16 | + $this->response = $response; |
|
| 17 | + } |
|
| 18 | + public function then(?callable $onFulfilled = null, ?callable $onRejected = null) |
|
| 19 | + { |
|
| 20 | + if (null === $onFulfilled) { |
|
| 21 | + return $this; |
|
| 22 | + } |
|
| 23 | + try { |
|
| 24 | + return new self($onFulfilled($this->response)); |
|
| 25 | + } catch (Exception $e) { |
|
| 26 | + return new HttpRejectedPromise($e); |
|
| 27 | + } |
|
| 28 | + } |
|
| 29 | + public function getState() |
|
| 30 | + { |
|
| 31 | + return Promise::FULFILLED; |
|
| 32 | + } |
|
| 33 | + public function wait($unwrap = \true) |
|
| 34 | + { |
|
| 35 | + if ($unwrap) { |
|
| 36 | + return $this->response; |
|
| 37 | + } |
|
| 38 | + } |
|
| 39 | 39 | } |
@@ -21,20 +21,20 @@ |
||
| 21 | 21 | */ |
| 22 | 22 | class Psr18Client extends Psr17Factory implements ClientInterface |
| 23 | 23 | { |
| 24 | - private $client; |
|
| 25 | - public function __construct(?ClientInterface $client = null, ?RequestFactoryInterface $requestFactory = null, ?ResponseFactoryInterface $responseFactory = null, ?ServerRequestFactoryInterface $serverRequestFactory = null, ?StreamFactoryInterface $streamFactory = null, ?UploadedFileFactoryInterface $uploadedFileFactory = null, ?UriFactoryInterface $uriFactory = null) |
|
| 26 | - { |
|
| 27 | - $requestFactory ?? ($requestFactory = $client instanceof RequestFactoryInterface ? $client : null); |
|
| 28 | - $responseFactory ?? ($responseFactory = $client instanceof ResponseFactoryInterface ? $client : null); |
|
| 29 | - $serverRequestFactory ?? ($serverRequestFactory = $client instanceof ServerRequestFactoryInterface ? $client : null); |
|
| 30 | - $streamFactory ?? ($streamFactory = $client instanceof StreamFactoryInterface ? $client : null); |
|
| 31 | - $uploadedFileFactory ?? ($uploadedFileFactory = $client instanceof UploadedFileFactoryInterface ? $client : null); |
|
| 32 | - $uriFactory ?? ($uriFactory = $client instanceof UriFactoryInterface ? $client : null); |
|
| 33 | - parent::__construct($requestFactory, $responseFactory, $serverRequestFactory, $streamFactory, $uploadedFileFactory, $uriFactory); |
|
| 34 | - $this->client = $client ?? Psr18ClientDiscovery::find(); |
|
| 35 | - } |
|
| 36 | - public function sendRequest(RequestInterface $request) : ResponseInterface |
|
| 37 | - { |
|
| 38 | - return $this->client->sendRequest($request); |
|
| 39 | - } |
|
| 24 | + private $client; |
|
| 25 | + public function __construct(?ClientInterface $client = null, ?RequestFactoryInterface $requestFactory = null, ?ResponseFactoryInterface $responseFactory = null, ?ServerRequestFactoryInterface $serverRequestFactory = null, ?StreamFactoryInterface $streamFactory = null, ?UploadedFileFactoryInterface $uploadedFileFactory = null, ?UriFactoryInterface $uriFactory = null) |
|
| 26 | + { |
|
| 27 | + $requestFactory ?? ($requestFactory = $client instanceof RequestFactoryInterface ? $client : null); |
|
| 28 | + $responseFactory ?? ($responseFactory = $client instanceof ResponseFactoryInterface ? $client : null); |
|
| 29 | + $serverRequestFactory ?? ($serverRequestFactory = $client instanceof ServerRequestFactoryInterface ? $client : null); |
|
| 30 | + $streamFactory ?? ($streamFactory = $client instanceof StreamFactoryInterface ? $client : null); |
|
| 31 | + $uploadedFileFactory ?? ($uploadedFileFactory = $client instanceof UploadedFileFactoryInterface ? $client : null); |
|
| 32 | + $uriFactory ?? ($uriFactory = $client instanceof UriFactoryInterface ? $client : null); |
|
| 33 | + parent::__construct($requestFactory, $responseFactory, $serverRequestFactory, $streamFactory, $uploadedFileFactory, $uriFactory); |
|
| 34 | + $this->client = $client ?? Psr18ClientDiscovery::find(); |
|
| 35 | + } |
|
| 36 | + public function sendRequest(RequestInterface $request) : ResponseInterface |
|
| 37 | + { |
|
| 38 | + return $this->client->sendRequest($request); |
|
| 39 | + } |
|
| 40 | 40 | } |
@@ -37,229 +37,229 @@ discard block |
||
| 37 | 37 | */ |
| 38 | 38 | class Plugin implements PluginInterface, EventSubscriberInterface |
| 39 | 39 | { |
| 40 | - /** |
|
| 41 | - * Describes, for every supported virtual implementation, which packages |
|
| 42 | - * provide said implementation and which extra dependencies each package |
|
| 43 | - * requires to provide the implementation. |
|
| 44 | - */ |
|
| 45 | - private const PROVIDE_RULES = ['php-http/async-client-implementation' => ['symfony/http-client:>=6.3' => ['guzzlehttp/promises', 'psr/http-factory-implementation', 'php-http/httplug'], 'symfony/http-client' => ['guzzlehttp/promises', 'php-http/message-factory', 'psr/http-factory-implementation', 'php-http/httplug'], 'php-http/guzzle7-adapter' => [], 'php-http/guzzle6-adapter' => [], 'php-http/curl-client' => [], 'php-http/react-adapter' => []], 'php-http/client-implementation' => ['symfony/http-client:>=6.3' => ['psr/http-factory-implementation', 'php-http/httplug'], 'symfony/http-client' => ['php-http/message-factory', 'psr/http-factory-implementation', 'php-http/httplug'], 'php-http/guzzle7-adapter' => [], 'php-http/guzzle6-adapter' => [], 'php-http/cakephp-adapter' => [], 'php-http/curl-client' => [], 'php-http/react-adapter' => [], 'php-http/buzz-adapter' => [], 'php-http/artax-adapter' => [], 'kriswallsmith/buzz:^1' => []], 'psr/http-client-implementation' => ['symfony/http-client' => ['psr/http-factory-implementation', 'psr/http-client'], 'guzzlehttp/guzzle' => [], 'kriswallsmith/buzz:^1' => []], 'psr/http-message-implementation' => ['php-http/discovery' => ['psr/http-factory-implementation']], 'psr/http-factory-implementation' => ['nyholm/psr7' => [], 'guzzlehttp/psr7:>=2' => [], 'slim/psr7' => [], 'laminas/laminas-diactoros' => [], 'phalcon/cphalcon:^4' => [], 'http-interop/http-factory-guzzle' => [], 'http-interop/http-factory-diactoros' => [], 'http-interop/http-factory-slim' => [], 'httpsoft/http-message' => []]]; |
|
| 46 | - /** |
|
| 47 | - * Describes which package should be preferred on the left side |
|
| 48 | - * depending on which one is already installed on the right side. |
|
| 49 | - */ |
|
| 50 | - private const STICKYNESS_RULES = ['symfony/http-client' => 'symfony/framework-bundle', 'php-http/guzzle7-adapter' => 'guzzlehttp/guzzle:^7', 'php-http/guzzle6-adapter' => 'guzzlehttp/guzzle:^6', 'php-http/guzzle5-adapter' => 'guzzlehttp/guzzle:^5', 'php-http/cakephp-adapter' => 'cakephp/cakephp', 'php-http/react-adapter' => 'react/event-loop', 'php-http/buzz-adapter' => 'kriswallsmith/buzz:^0.15.1', 'php-http/artax-adapter' => 'amphp/artax:^3', 'http-interop/http-factory-guzzle' => 'guzzlehttp/psr7:^1', 'http-interop/http-factory-slim' => 'slim/slim:^3']; |
|
| 51 | - private const INTERFACE_MAP = ['php-http/async-client-implementation' => ['OCA\\FullTextSearch_Elasticsearch\\Vendor\\Http\\Client\\HttpAsyncClient'], 'php-http/client-implementation' => ['OCA\\FullTextSearch_Elasticsearch\\Vendor\\Http\\Client\\HttpClient'], 'psr/http-client-implementation' => ['OCA\\FullTextSearch_Elasticsearch\\Vendor\\Psr\\Http\\Client\\ClientInterface'], 'psr/http-factory-implementation' => ['OCA\\FullTextSearch_Elasticsearch\\Vendor\\Psr\\Http\\Message\\RequestFactoryInterface', 'OCA\\FullTextSearch_Elasticsearch\\Vendor\\Psr\\Http\\Message\\ResponseFactoryInterface', 'OCA\\FullTextSearch_Elasticsearch\\Vendor\\Psr\\Http\\Message\\ServerRequestFactoryInterface', 'OCA\\FullTextSearch_Elasticsearch\\Vendor\\Psr\\Http\\Message\\StreamFactoryInterface', 'OCA\\FullTextSearch_Elasticsearch\\Vendor\\Psr\\Http\\Message\\UploadedFileFactoryInterface', 'OCA\\FullTextSearch_Elasticsearch\\Vendor\\Psr\\Http\\Message\\UriFactoryInterface']]; |
|
| 52 | - public static function getSubscribedEvents() : array |
|
| 53 | - { |
|
| 54 | - return [ScriptEvents::PRE_AUTOLOAD_DUMP => 'preAutoloadDump', ScriptEvents::POST_UPDATE_CMD => 'postUpdate']; |
|
| 55 | - } |
|
| 56 | - public function activate(Composer $composer, IOInterface $io) : void |
|
| 57 | - { |
|
| 58 | - } |
|
| 59 | - public function deactivate(Composer $composer, IOInterface $io) |
|
| 60 | - { |
|
| 61 | - } |
|
| 62 | - public function uninstall(Composer $composer, IOInterface $io) |
|
| 63 | - { |
|
| 64 | - } |
|
| 65 | - public function postUpdate(Event $event) |
|
| 66 | - { |
|
| 67 | - $composer = $event->getComposer(); |
|
| 68 | - $repo = $composer->getRepositoryManager()->getLocalRepository(); |
|
| 69 | - $requires = [$composer->getPackage()->getRequires(), $composer->getPackage()->getDevRequires()]; |
|
| 70 | - $pinnedAbstractions = []; |
|
| 71 | - $pinned = $composer->getPackage()->getExtra()['discovery'] ?? []; |
|
| 72 | - foreach (self::INTERFACE_MAP as $abstraction => $interfaces) { |
|
| 73 | - foreach (isset($pinned[$abstraction]) ? [] : $interfaces as $interface) { |
|
| 74 | - if (!isset($pinned[$interface])) { |
|
| 75 | - continue 2; |
|
| 76 | - } |
|
| 77 | - } |
|
| 78 | - $pinnedAbstractions[$abstraction] = \true; |
|
| 79 | - } |
|
| 80 | - $missingRequires = $this->getMissingRequires($repo, $requires, 'project' === $composer->getPackage()->getType(), $pinnedAbstractions); |
|
| 81 | - $missingRequires = ['require' => \array_fill_keys(\array_merge([], ...\array_values($missingRequires[0])), '*'), 'require-dev' => \array_fill_keys(\array_merge([], ...\array_values($missingRequires[1])), '*'), 'remove' => \array_fill_keys(\array_merge([], ...\array_values($missingRequires[2])), '*')]; |
|
| 82 | - if (!($missingRequires = \array_filter($missingRequires))) { |
|
| 83 | - return; |
|
| 84 | - } |
|
| 85 | - $composerJsonContents = \file_get_contents(Factory::getComposerFile()); |
|
| 86 | - $this->updateComposerJson($missingRequires, $composer->getConfig()->get('sort-packages')); |
|
| 87 | - $installer = null; |
|
| 88 | - // Find the composer installer, hack borrowed from symfony/flex |
|
| 89 | - foreach (\debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT) as $trace) { |
|
| 90 | - if (isset($trace['object']) && $trace['object'] instanceof Installer) { |
|
| 91 | - $installer = $trace['object']; |
|
| 92 | - break; |
|
| 93 | - } |
|
| 94 | - } |
|
| 95 | - if (!$installer) { |
|
| 96 | - return; |
|
| 97 | - } |
|
| 98 | - $event->stopPropagation(); |
|
| 99 | - $dispatcher = $composer->getEventDispatcher(); |
|
| 100 | - $disableScripts = !\method_exists($dispatcher, 'setRunScripts') || !((array) $dispatcher)["\x00*\x00runScripts"]; |
|
| 101 | - $composer = Factory::create($event->getIO(), null, \false, $disableScripts); |
|
| 102 | - /** @var Installer $installer */ |
|
| 103 | - $installer = clone $installer; |
|
| 104 | - if (\method_exists($installer, 'setAudit')) { |
|
| 105 | - $trace['object']->setAudit(\false); |
|
| 106 | - } |
|
| 107 | - // we need a clone of the installer to preserve its configuration state but with our own service objects |
|
| 108 | - $installer->__construct($event->getIO(), $composer->getConfig(), $composer->getPackage(), $composer->getDownloadManager(), $composer->getRepositoryManager(), $composer->getLocker(), $composer->getInstallationManager(), $composer->getEventDispatcher(), $composer->getAutoloadGenerator()); |
|
| 109 | - if (\method_exists($installer, 'setPlatformRequirementFilter')) { |
|
| 110 | - $installer->setPlatformRequirementFilter(((array) $trace['object'])["\x00*\x00platformRequirementFilter"]); |
|
| 111 | - } |
|
| 112 | - if (0 !== $installer->run()) { |
|
| 113 | - \file_put_contents(Factory::getComposerFile(), $composerJsonContents); |
|
| 114 | - return; |
|
| 115 | - } |
|
| 116 | - $versionSelector = new VersionSelector(ClassDiscovery::safeClassExists(RepositorySet::class) ? new RepositorySet() : new Pool()); |
|
| 117 | - $updateComposerJson = \false; |
|
| 118 | - foreach ($composer->getRepositoryManager()->getLocalRepository()->getPackages() as $package) { |
|
| 119 | - foreach (['require', 'require-dev'] as $key) { |
|
| 120 | - if (!isset($missingRequires[$key][$package->getName()])) { |
|
| 121 | - continue; |
|
| 122 | - } |
|
| 123 | - $updateComposerJson = \true; |
|
| 124 | - $missingRequires[$key][$package->getName()] = $versionSelector->findRecommendedRequireVersion($package); |
|
| 125 | - } |
|
| 126 | - } |
|
| 127 | - if ($updateComposerJson) { |
|
| 128 | - $this->updateComposerJson($missingRequires, $composer->getConfig()->get('sort-packages')); |
|
| 129 | - $this->updateComposerLock($composer, $event->getIO()); |
|
| 130 | - } |
|
| 131 | - } |
|
| 132 | - public function getMissingRequires(InstalledRepositoryInterface $repo, array $requires, bool $isProject, array $pinnedAbstractions) : array |
|
| 133 | - { |
|
| 134 | - $allPackages = []; |
|
| 135 | - $devPackages = \method_exists($repo, 'getDevPackageNames') ? \array_fill_keys($repo->getDevPackageNames(), \true) : []; |
|
| 136 | - // One must require "php-http/discovery" |
|
| 137 | - // to opt-in for auto-installation of virtual package implementations |
|
| 138 | - if (!isset($requires[0]['php-http/discovery'])) { |
|
| 139 | - $requires = [[], []]; |
|
| 140 | - } |
|
| 141 | - foreach ($repo->getPackages() as $package) { |
|
| 142 | - $allPackages[$package->getName()] = \true; |
|
| 143 | - if (1 < \count($names = $package->getNames(\false))) { |
|
| 144 | - $allPackages += \array_fill_keys($names, \false); |
|
| 145 | - if (isset($devPackages[$package->getName()])) { |
|
| 146 | - $devPackages += $names; |
|
| 147 | - } |
|
| 148 | - } |
|
| 149 | - if (isset($package->getRequires()['php-http/discovery'])) { |
|
| 150 | - $requires[(int) isset($devPackages[$package->getName()])] += $package->getRequires(); |
|
| 151 | - } |
|
| 152 | - } |
|
| 153 | - $missingRequires = [[], [], []]; |
|
| 154 | - $versionParser = new VersionParser(); |
|
| 155 | - if (ClassDiscovery::safeClassExists(\OCA\FullTextSearch_Elasticsearch\Vendor\Phalcon\Http\Message\RequestFactory::class, \false)) { |
|
| 156 | - $missingRequires[0]['psr/http-factory-implementation'] = []; |
|
| 157 | - $missingRequires[1]['psr/http-factory-implementation'] = []; |
|
| 158 | - } |
|
| 159 | - foreach ($requires as $dev => $rules) { |
|
| 160 | - $abstractions = []; |
|
| 161 | - $rules = \array_intersect_key(self::PROVIDE_RULES, $rules); |
|
| 162 | - while ($rules) { |
|
| 163 | - $abstraction = \key($rules); |
|
| 164 | - if (isset($pinnedAbstractions[$abstraction])) { |
|
| 165 | - unset($rules[$abstraction]); |
|
| 166 | - continue; |
|
| 167 | - } |
|
| 168 | - $abstractions[] = $abstraction; |
|
| 169 | - foreach (\array_shift($rules) as $candidate => $deps) { |
|
| 170 | - [$candidate, $version] = \explode(':', $candidate, 2) + [1 => null]; |
|
| 171 | - if (!isset($allPackages[$candidate])) { |
|
| 172 | - continue; |
|
| 173 | - } |
|
| 174 | - if (null !== $version && !$repo->findPackage($candidate, $versionParser->parseConstraints($version))) { |
|
| 175 | - continue; |
|
| 176 | - } |
|
| 177 | - if ($isProject && !$dev && isset($devPackages[$candidate])) { |
|
| 178 | - $missingRequires[0][$abstraction] = [$candidate]; |
|
| 179 | - $missingRequires[2][$abstraction] = [$candidate]; |
|
| 180 | - } else { |
|
| 181 | - $missingRequires[$dev][$abstraction] = []; |
|
| 182 | - } |
|
| 183 | - foreach ($deps as $dep) { |
|
| 184 | - if (isset(self::PROVIDE_RULES[$dep])) { |
|
| 185 | - $rules[$dep] = self::PROVIDE_RULES[$dep]; |
|
| 186 | - } elseif (!isset($allPackages[$dep])) { |
|
| 187 | - $missingRequires[$dev][$abstraction][] = $dep; |
|
| 188 | - } elseif ($isProject && !$dev && isset($devPackages[$dep])) { |
|
| 189 | - $missingRequires[0][$abstraction][] = $dep; |
|
| 190 | - $missingRequires[2][$abstraction][] = $dep; |
|
| 191 | - } |
|
| 192 | - } |
|
| 193 | - break; |
|
| 194 | - } |
|
| 195 | - } |
|
| 196 | - while ($abstractions) { |
|
| 197 | - $abstraction = \array_shift($abstractions); |
|
| 198 | - if (isset($missingRequires[$dev][$abstraction])) { |
|
| 199 | - continue; |
|
| 200 | - } |
|
| 201 | - $candidates = self::PROVIDE_RULES[$abstraction]; |
|
| 202 | - foreach ($candidates as $candidate => $deps) { |
|
| 203 | - [$candidate, $version] = \explode(':', $candidate, 2) + [1 => null]; |
|
| 204 | - if (null !== $version && !$repo->findPackage($candidate, $versionParser->parseConstraints($version))) { |
|
| 205 | - continue; |
|
| 206 | - } |
|
| 207 | - if (isset($allPackages[$candidate]) && (!$isProject || $dev || !isset($devPackages[$candidate]))) { |
|
| 208 | - continue 2; |
|
| 209 | - } |
|
| 210 | - } |
|
| 211 | - foreach (\array_intersect_key(self::STICKYNESS_RULES, $candidates) as $candidate => $stickyRule) { |
|
| 212 | - [$stickyName, $stickyVersion] = \explode(':', $stickyRule, 2) + [1 => null]; |
|
| 213 | - if (!isset($allPackages[$stickyName]) || $isProject && !$dev && isset($devPackages[$stickyName])) { |
|
| 214 | - continue; |
|
| 215 | - } |
|
| 216 | - if (null !== $stickyVersion && !$repo->findPackage($stickyName, $versionParser->parseConstraints($stickyVersion))) { |
|
| 217 | - continue; |
|
| 218 | - } |
|
| 219 | - $candidates = [$candidate => $candidates[$candidate]]; |
|
| 220 | - break; |
|
| 221 | - } |
|
| 222 | - $dep = \key($candidates); |
|
| 223 | - [$dep] = \explode(':', $dep, 2); |
|
| 224 | - $missingRequires[$dev][$abstraction] = [$dep]; |
|
| 225 | - if ($isProject && !$dev && isset($devPackages[$dep])) { |
|
| 226 | - $missingRequires[2][$abstraction][] = $dep; |
|
| 227 | - } |
|
| 228 | - } |
|
| 229 | - } |
|
| 230 | - $missingRequires[1] = \array_diff_key($missingRequires[1], $missingRequires[0]); |
|
| 231 | - return $missingRequires; |
|
| 232 | - } |
|
| 233 | - public function preAutoloadDump(Event $event) |
|
| 234 | - { |
|
| 235 | - $filesystem = new Filesystem(); |
|
| 236 | - // Double realpath() on purpose, see https://bugs.php.net/72738 |
|
| 237 | - $vendorDir = $filesystem->normalizePath(\realpath(\realpath($event->getComposer()->getConfig()->get('vendor-dir')))); |
|
| 238 | - $filesystem->ensureDirectoryExists($vendorDir . '/composer'); |
|
| 239 | - $pinned = $event->getComposer()->getPackage()->getExtra()['discovery'] ?? []; |
|
| 240 | - $candidates = []; |
|
| 241 | - $allInterfaces = \array_merge(...\array_values(self::INTERFACE_MAP)); |
|
| 242 | - foreach ($pinned as $abstraction => $class) { |
|
| 243 | - if (isset(self::INTERFACE_MAP[$abstraction])) { |
|
| 244 | - $interfaces = self::INTERFACE_MAP[$abstraction]; |
|
| 245 | - } elseif (\false !== ($k = \array_search($abstraction, $allInterfaces, \true))) { |
|
| 246 | - $interfaces = [$allInterfaces[$k]]; |
|
| 247 | - } else { |
|
| 248 | - throw new \UnexpectedValueException(\sprintf('Invalid "extra.discovery" pinned in composer.json: "%s" is not one of ["%s"].', $abstraction, \implode('", "', \array_keys(self::INTERFACE_MAP)))); |
|
| 249 | - } |
|
| 250 | - foreach ($interfaces as $interface) { |
|
| 251 | - $candidates[] = \sprintf("case %s: return [['class' => %s]];\n", \var_export($interface, \true), \var_export($class, \true)); |
|
| 252 | - } |
|
| 253 | - } |
|
| 254 | - $file = $vendorDir . '/composer/GeneratedDiscoveryStrategy.php'; |
|
| 255 | - if (!$candidates) { |
|
| 256 | - if (\file_exists($file)) { |
|
| 257 | - \unlink($file); |
|
| 258 | - } |
|
| 259 | - return; |
|
| 260 | - } |
|
| 261 | - $candidates = \implode(' ', $candidates); |
|
| 262 | - $code = <<<EOPHP |
|
| 40 | + /** |
|
| 41 | + * Describes, for every supported virtual implementation, which packages |
|
| 42 | + * provide said implementation and which extra dependencies each package |
|
| 43 | + * requires to provide the implementation. |
|
| 44 | + */ |
|
| 45 | + private const PROVIDE_RULES = ['php-http/async-client-implementation' => ['symfony/http-client:>=6.3' => ['guzzlehttp/promises', 'psr/http-factory-implementation', 'php-http/httplug'], 'symfony/http-client' => ['guzzlehttp/promises', 'php-http/message-factory', 'psr/http-factory-implementation', 'php-http/httplug'], 'php-http/guzzle7-adapter' => [], 'php-http/guzzle6-adapter' => [], 'php-http/curl-client' => [], 'php-http/react-adapter' => []], 'php-http/client-implementation' => ['symfony/http-client:>=6.3' => ['psr/http-factory-implementation', 'php-http/httplug'], 'symfony/http-client' => ['php-http/message-factory', 'psr/http-factory-implementation', 'php-http/httplug'], 'php-http/guzzle7-adapter' => [], 'php-http/guzzle6-adapter' => [], 'php-http/cakephp-adapter' => [], 'php-http/curl-client' => [], 'php-http/react-adapter' => [], 'php-http/buzz-adapter' => [], 'php-http/artax-adapter' => [], 'kriswallsmith/buzz:^1' => []], 'psr/http-client-implementation' => ['symfony/http-client' => ['psr/http-factory-implementation', 'psr/http-client'], 'guzzlehttp/guzzle' => [], 'kriswallsmith/buzz:^1' => []], 'psr/http-message-implementation' => ['php-http/discovery' => ['psr/http-factory-implementation']], 'psr/http-factory-implementation' => ['nyholm/psr7' => [], 'guzzlehttp/psr7:>=2' => [], 'slim/psr7' => [], 'laminas/laminas-diactoros' => [], 'phalcon/cphalcon:^4' => [], 'http-interop/http-factory-guzzle' => [], 'http-interop/http-factory-diactoros' => [], 'http-interop/http-factory-slim' => [], 'httpsoft/http-message' => []]]; |
|
| 46 | + /** |
|
| 47 | + * Describes which package should be preferred on the left side |
|
| 48 | + * depending on which one is already installed on the right side. |
|
| 49 | + */ |
|
| 50 | + private const STICKYNESS_RULES = ['symfony/http-client' => 'symfony/framework-bundle', 'php-http/guzzle7-adapter' => 'guzzlehttp/guzzle:^7', 'php-http/guzzle6-adapter' => 'guzzlehttp/guzzle:^6', 'php-http/guzzle5-adapter' => 'guzzlehttp/guzzle:^5', 'php-http/cakephp-adapter' => 'cakephp/cakephp', 'php-http/react-adapter' => 'react/event-loop', 'php-http/buzz-adapter' => 'kriswallsmith/buzz:^0.15.1', 'php-http/artax-adapter' => 'amphp/artax:^3', 'http-interop/http-factory-guzzle' => 'guzzlehttp/psr7:^1', 'http-interop/http-factory-slim' => 'slim/slim:^3']; |
|
| 51 | + private const INTERFACE_MAP = ['php-http/async-client-implementation' => ['OCA\\FullTextSearch_Elasticsearch\\Vendor\\Http\\Client\\HttpAsyncClient'], 'php-http/client-implementation' => ['OCA\\FullTextSearch_Elasticsearch\\Vendor\\Http\\Client\\HttpClient'], 'psr/http-client-implementation' => ['OCA\\FullTextSearch_Elasticsearch\\Vendor\\Psr\\Http\\Client\\ClientInterface'], 'psr/http-factory-implementation' => ['OCA\\FullTextSearch_Elasticsearch\\Vendor\\Psr\\Http\\Message\\RequestFactoryInterface', 'OCA\\FullTextSearch_Elasticsearch\\Vendor\\Psr\\Http\\Message\\ResponseFactoryInterface', 'OCA\\FullTextSearch_Elasticsearch\\Vendor\\Psr\\Http\\Message\\ServerRequestFactoryInterface', 'OCA\\FullTextSearch_Elasticsearch\\Vendor\\Psr\\Http\\Message\\StreamFactoryInterface', 'OCA\\FullTextSearch_Elasticsearch\\Vendor\\Psr\\Http\\Message\\UploadedFileFactoryInterface', 'OCA\\FullTextSearch_Elasticsearch\\Vendor\\Psr\\Http\\Message\\UriFactoryInterface']]; |
|
| 52 | + public static function getSubscribedEvents() : array |
|
| 53 | + { |
|
| 54 | + return [ScriptEvents::PRE_AUTOLOAD_DUMP => 'preAutoloadDump', ScriptEvents::POST_UPDATE_CMD => 'postUpdate']; |
|
| 55 | + } |
|
| 56 | + public function activate(Composer $composer, IOInterface $io) : void |
|
| 57 | + { |
|
| 58 | + } |
|
| 59 | + public function deactivate(Composer $composer, IOInterface $io) |
|
| 60 | + { |
|
| 61 | + } |
|
| 62 | + public function uninstall(Composer $composer, IOInterface $io) |
|
| 63 | + { |
|
| 64 | + } |
|
| 65 | + public function postUpdate(Event $event) |
|
| 66 | + { |
|
| 67 | + $composer = $event->getComposer(); |
|
| 68 | + $repo = $composer->getRepositoryManager()->getLocalRepository(); |
|
| 69 | + $requires = [$composer->getPackage()->getRequires(), $composer->getPackage()->getDevRequires()]; |
|
| 70 | + $pinnedAbstractions = []; |
|
| 71 | + $pinned = $composer->getPackage()->getExtra()['discovery'] ?? []; |
|
| 72 | + foreach (self::INTERFACE_MAP as $abstraction => $interfaces) { |
|
| 73 | + foreach (isset($pinned[$abstraction]) ? [] : $interfaces as $interface) { |
|
| 74 | + if (!isset($pinned[$interface])) { |
|
| 75 | + continue 2; |
|
| 76 | + } |
|
| 77 | + } |
|
| 78 | + $pinnedAbstractions[$abstraction] = \true; |
|
| 79 | + } |
|
| 80 | + $missingRequires = $this->getMissingRequires($repo, $requires, 'project' === $composer->getPackage()->getType(), $pinnedAbstractions); |
|
| 81 | + $missingRequires = ['require' => \array_fill_keys(\array_merge([], ...\array_values($missingRequires[0])), '*'), 'require-dev' => \array_fill_keys(\array_merge([], ...\array_values($missingRequires[1])), '*'), 'remove' => \array_fill_keys(\array_merge([], ...\array_values($missingRequires[2])), '*')]; |
|
| 82 | + if (!($missingRequires = \array_filter($missingRequires))) { |
|
| 83 | + return; |
|
| 84 | + } |
|
| 85 | + $composerJsonContents = \file_get_contents(Factory::getComposerFile()); |
|
| 86 | + $this->updateComposerJson($missingRequires, $composer->getConfig()->get('sort-packages')); |
|
| 87 | + $installer = null; |
|
| 88 | + // Find the composer installer, hack borrowed from symfony/flex |
|
| 89 | + foreach (\debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT) as $trace) { |
|
| 90 | + if (isset($trace['object']) && $trace['object'] instanceof Installer) { |
|
| 91 | + $installer = $trace['object']; |
|
| 92 | + break; |
|
| 93 | + } |
|
| 94 | + } |
|
| 95 | + if (!$installer) { |
|
| 96 | + return; |
|
| 97 | + } |
|
| 98 | + $event->stopPropagation(); |
|
| 99 | + $dispatcher = $composer->getEventDispatcher(); |
|
| 100 | + $disableScripts = !\method_exists($dispatcher, 'setRunScripts') || !((array) $dispatcher)["\x00*\x00runScripts"]; |
|
| 101 | + $composer = Factory::create($event->getIO(), null, \false, $disableScripts); |
|
| 102 | + /** @var Installer $installer */ |
|
| 103 | + $installer = clone $installer; |
|
| 104 | + if (\method_exists($installer, 'setAudit')) { |
|
| 105 | + $trace['object']->setAudit(\false); |
|
| 106 | + } |
|
| 107 | + // we need a clone of the installer to preserve its configuration state but with our own service objects |
|
| 108 | + $installer->__construct($event->getIO(), $composer->getConfig(), $composer->getPackage(), $composer->getDownloadManager(), $composer->getRepositoryManager(), $composer->getLocker(), $composer->getInstallationManager(), $composer->getEventDispatcher(), $composer->getAutoloadGenerator()); |
|
| 109 | + if (\method_exists($installer, 'setPlatformRequirementFilter')) { |
|
| 110 | + $installer->setPlatformRequirementFilter(((array) $trace['object'])["\x00*\x00platformRequirementFilter"]); |
|
| 111 | + } |
|
| 112 | + if (0 !== $installer->run()) { |
|
| 113 | + \file_put_contents(Factory::getComposerFile(), $composerJsonContents); |
|
| 114 | + return; |
|
| 115 | + } |
|
| 116 | + $versionSelector = new VersionSelector(ClassDiscovery::safeClassExists(RepositorySet::class) ? new RepositorySet() : new Pool()); |
|
| 117 | + $updateComposerJson = \false; |
|
| 118 | + foreach ($composer->getRepositoryManager()->getLocalRepository()->getPackages() as $package) { |
|
| 119 | + foreach (['require', 'require-dev'] as $key) { |
|
| 120 | + if (!isset($missingRequires[$key][$package->getName()])) { |
|
| 121 | + continue; |
|
| 122 | + } |
|
| 123 | + $updateComposerJson = \true; |
|
| 124 | + $missingRequires[$key][$package->getName()] = $versionSelector->findRecommendedRequireVersion($package); |
|
| 125 | + } |
|
| 126 | + } |
|
| 127 | + if ($updateComposerJson) { |
|
| 128 | + $this->updateComposerJson($missingRequires, $composer->getConfig()->get('sort-packages')); |
|
| 129 | + $this->updateComposerLock($composer, $event->getIO()); |
|
| 130 | + } |
|
| 131 | + } |
|
| 132 | + public function getMissingRequires(InstalledRepositoryInterface $repo, array $requires, bool $isProject, array $pinnedAbstractions) : array |
|
| 133 | + { |
|
| 134 | + $allPackages = []; |
|
| 135 | + $devPackages = \method_exists($repo, 'getDevPackageNames') ? \array_fill_keys($repo->getDevPackageNames(), \true) : []; |
|
| 136 | + // One must require "php-http/discovery" |
|
| 137 | + // to opt-in for auto-installation of virtual package implementations |
|
| 138 | + if (!isset($requires[0]['php-http/discovery'])) { |
|
| 139 | + $requires = [[], []]; |
|
| 140 | + } |
|
| 141 | + foreach ($repo->getPackages() as $package) { |
|
| 142 | + $allPackages[$package->getName()] = \true; |
|
| 143 | + if (1 < \count($names = $package->getNames(\false))) { |
|
| 144 | + $allPackages += \array_fill_keys($names, \false); |
|
| 145 | + if (isset($devPackages[$package->getName()])) { |
|
| 146 | + $devPackages += $names; |
|
| 147 | + } |
|
| 148 | + } |
|
| 149 | + if (isset($package->getRequires()['php-http/discovery'])) { |
|
| 150 | + $requires[(int) isset($devPackages[$package->getName()])] += $package->getRequires(); |
|
| 151 | + } |
|
| 152 | + } |
|
| 153 | + $missingRequires = [[], [], []]; |
|
| 154 | + $versionParser = new VersionParser(); |
|
| 155 | + if (ClassDiscovery::safeClassExists(\OCA\FullTextSearch_Elasticsearch\Vendor\Phalcon\Http\Message\RequestFactory::class, \false)) { |
|
| 156 | + $missingRequires[0]['psr/http-factory-implementation'] = []; |
|
| 157 | + $missingRequires[1]['psr/http-factory-implementation'] = []; |
|
| 158 | + } |
|
| 159 | + foreach ($requires as $dev => $rules) { |
|
| 160 | + $abstractions = []; |
|
| 161 | + $rules = \array_intersect_key(self::PROVIDE_RULES, $rules); |
|
| 162 | + while ($rules) { |
|
| 163 | + $abstraction = \key($rules); |
|
| 164 | + if (isset($pinnedAbstractions[$abstraction])) { |
|
| 165 | + unset($rules[$abstraction]); |
|
| 166 | + continue; |
|
| 167 | + } |
|
| 168 | + $abstractions[] = $abstraction; |
|
| 169 | + foreach (\array_shift($rules) as $candidate => $deps) { |
|
| 170 | + [$candidate, $version] = \explode(':', $candidate, 2) + [1 => null]; |
|
| 171 | + if (!isset($allPackages[$candidate])) { |
|
| 172 | + continue; |
|
| 173 | + } |
|
| 174 | + if (null !== $version && !$repo->findPackage($candidate, $versionParser->parseConstraints($version))) { |
|
| 175 | + continue; |
|
| 176 | + } |
|
| 177 | + if ($isProject && !$dev && isset($devPackages[$candidate])) { |
|
| 178 | + $missingRequires[0][$abstraction] = [$candidate]; |
|
| 179 | + $missingRequires[2][$abstraction] = [$candidate]; |
|
| 180 | + } else { |
|
| 181 | + $missingRequires[$dev][$abstraction] = []; |
|
| 182 | + } |
|
| 183 | + foreach ($deps as $dep) { |
|
| 184 | + if (isset(self::PROVIDE_RULES[$dep])) { |
|
| 185 | + $rules[$dep] = self::PROVIDE_RULES[$dep]; |
|
| 186 | + } elseif (!isset($allPackages[$dep])) { |
|
| 187 | + $missingRequires[$dev][$abstraction][] = $dep; |
|
| 188 | + } elseif ($isProject && !$dev && isset($devPackages[$dep])) { |
|
| 189 | + $missingRequires[0][$abstraction][] = $dep; |
|
| 190 | + $missingRequires[2][$abstraction][] = $dep; |
|
| 191 | + } |
|
| 192 | + } |
|
| 193 | + break; |
|
| 194 | + } |
|
| 195 | + } |
|
| 196 | + while ($abstractions) { |
|
| 197 | + $abstraction = \array_shift($abstractions); |
|
| 198 | + if (isset($missingRequires[$dev][$abstraction])) { |
|
| 199 | + continue; |
|
| 200 | + } |
|
| 201 | + $candidates = self::PROVIDE_RULES[$abstraction]; |
|
| 202 | + foreach ($candidates as $candidate => $deps) { |
|
| 203 | + [$candidate, $version] = \explode(':', $candidate, 2) + [1 => null]; |
|
| 204 | + if (null !== $version && !$repo->findPackage($candidate, $versionParser->parseConstraints($version))) { |
|
| 205 | + continue; |
|
| 206 | + } |
|
| 207 | + if (isset($allPackages[$candidate]) && (!$isProject || $dev || !isset($devPackages[$candidate]))) { |
|
| 208 | + continue 2; |
|
| 209 | + } |
|
| 210 | + } |
|
| 211 | + foreach (\array_intersect_key(self::STICKYNESS_RULES, $candidates) as $candidate => $stickyRule) { |
|
| 212 | + [$stickyName, $stickyVersion] = \explode(':', $stickyRule, 2) + [1 => null]; |
|
| 213 | + if (!isset($allPackages[$stickyName]) || $isProject && !$dev && isset($devPackages[$stickyName])) { |
|
| 214 | + continue; |
|
| 215 | + } |
|
| 216 | + if (null !== $stickyVersion && !$repo->findPackage($stickyName, $versionParser->parseConstraints($stickyVersion))) { |
|
| 217 | + continue; |
|
| 218 | + } |
|
| 219 | + $candidates = [$candidate => $candidates[$candidate]]; |
|
| 220 | + break; |
|
| 221 | + } |
|
| 222 | + $dep = \key($candidates); |
|
| 223 | + [$dep] = \explode(':', $dep, 2); |
|
| 224 | + $missingRequires[$dev][$abstraction] = [$dep]; |
|
| 225 | + if ($isProject && !$dev && isset($devPackages[$dep])) { |
|
| 226 | + $missingRequires[2][$abstraction][] = $dep; |
|
| 227 | + } |
|
| 228 | + } |
|
| 229 | + } |
|
| 230 | + $missingRequires[1] = \array_diff_key($missingRequires[1], $missingRequires[0]); |
|
| 231 | + return $missingRequires; |
|
| 232 | + } |
|
| 233 | + public function preAutoloadDump(Event $event) |
|
| 234 | + { |
|
| 235 | + $filesystem = new Filesystem(); |
|
| 236 | + // Double realpath() on purpose, see https://bugs.php.net/72738 |
|
| 237 | + $vendorDir = $filesystem->normalizePath(\realpath(\realpath($event->getComposer()->getConfig()->get('vendor-dir')))); |
|
| 238 | + $filesystem->ensureDirectoryExists($vendorDir . '/composer'); |
|
| 239 | + $pinned = $event->getComposer()->getPackage()->getExtra()['discovery'] ?? []; |
|
| 240 | + $candidates = []; |
|
| 241 | + $allInterfaces = \array_merge(...\array_values(self::INTERFACE_MAP)); |
|
| 242 | + foreach ($pinned as $abstraction => $class) { |
|
| 243 | + if (isset(self::INTERFACE_MAP[$abstraction])) { |
|
| 244 | + $interfaces = self::INTERFACE_MAP[$abstraction]; |
|
| 245 | + } elseif (\false !== ($k = \array_search($abstraction, $allInterfaces, \true))) { |
|
| 246 | + $interfaces = [$allInterfaces[$k]]; |
|
| 247 | + } else { |
|
| 248 | + throw new \UnexpectedValueException(\sprintf('Invalid "extra.discovery" pinned in composer.json: "%s" is not one of ["%s"].', $abstraction, \implode('", "', \array_keys(self::INTERFACE_MAP)))); |
|
| 249 | + } |
|
| 250 | + foreach ($interfaces as $interface) { |
|
| 251 | + $candidates[] = \sprintf("case %s: return [['class' => %s]];\n", \var_export($interface, \true), \var_export($class, \true)); |
|
| 252 | + } |
|
| 253 | + } |
|
| 254 | + $file = $vendorDir . '/composer/GeneratedDiscoveryStrategy.php'; |
|
| 255 | + if (!$candidates) { |
|
| 256 | + if (\file_exists($file)) { |
|
| 257 | + \unlink($file); |
|
| 258 | + } |
|
| 259 | + return; |
|
| 260 | + } |
|
| 261 | + $candidates = \implode(' ', $candidates); |
|
| 262 | + $code = <<<EOPHP |
|
| 263 | 263 | <?php |
| 264 | 264 | |
| 265 | 265 | namespace Http\\Discovery\\Strategy; |
@@ -276,44 +276,44 @@ discard block |
||
| 276 | 276 | } |
| 277 | 277 | |
| 278 | 278 | EOPHP; |
| 279 | - if (!\file_exists($file) || $code !== \file_get_contents($file)) { |
|
| 280 | - \file_put_contents($file, $code); |
|
| 281 | - } |
|
| 282 | - $rootPackage = $event->getComposer()->getPackage(); |
|
| 283 | - $autoload = $rootPackage->getAutoload(); |
|
| 284 | - $autoload['classmap'][] = $vendorDir . '/composer/GeneratedDiscoveryStrategy.php'; |
|
| 285 | - $rootPackage->setAutoload($autoload); |
|
| 286 | - } |
|
| 287 | - private function updateComposerJson(array $missingRequires, bool $sortPackages) |
|
| 288 | - { |
|
| 289 | - $file = Factory::getComposerFile(); |
|
| 290 | - $contents = \file_get_contents($file); |
|
| 291 | - $manipulator = new JsonManipulator($contents); |
|
| 292 | - foreach ($missingRequires as $key => $packages) { |
|
| 293 | - foreach ($packages as $package => $constraint) { |
|
| 294 | - if ('remove' === $key) { |
|
| 295 | - $manipulator->removeSubNode('require-dev', $package); |
|
| 296 | - } else { |
|
| 297 | - $manipulator->addLink($key, $package, $constraint, $sortPackages); |
|
| 298 | - } |
|
| 299 | - } |
|
| 300 | - } |
|
| 301 | - \file_put_contents($file, $manipulator->getContents()); |
|
| 302 | - } |
|
| 303 | - private function updateComposerLock(Composer $composer, IOInterface $io) |
|
| 304 | - { |
|
| 305 | - if (\false === $composer->getConfig()->get('lock')) { |
|
| 306 | - return; |
|
| 307 | - } |
|
| 308 | - $lock = \substr(Factory::getComposerFile(), 0, -4) . 'lock'; |
|
| 309 | - $composerJson = \file_get_contents(Factory::getComposerFile()); |
|
| 310 | - $lockFile = new JsonFile($lock, null, $io); |
|
| 311 | - $locker = ClassDiscovery::safeClassExists(RepositorySet::class) ? new Locker($io, $lockFile, $composer->getInstallationManager(), $composerJson) : new Locker($io, $lockFile, $composer->getRepositoryManager(), $composer->getInstallationManager(), $composerJson); |
|
| 312 | - if (!$locker->isLocked()) { |
|
| 313 | - return; |
|
| 314 | - } |
|
| 315 | - $lockData = $locker->getLockData(); |
|
| 316 | - $lockData['content-hash'] = Locker::getContentHash($composerJson); |
|
| 317 | - $lockFile->write($lockData); |
|
| 318 | - } |
|
| 279 | + if (!\file_exists($file) || $code !== \file_get_contents($file)) { |
|
| 280 | + \file_put_contents($file, $code); |
|
| 281 | + } |
|
| 282 | + $rootPackage = $event->getComposer()->getPackage(); |
|
| 283 | + $autoload = $rootPackage->getAutoload(); |
|
| 284 | + $autoload['classmap'][] = $vendorDir . '/composer/GeneratedDiscoveryStrategy.php'; |
|
| 285 | + $rootPackage->setAutoload($autoload); |
|
| 286 | + } |
|
| 287 | + private function updateComposerJson(array $missingRequires, bool $sortPackages) |
|
| 288 | + { |
|
| 289 | + $file = Factory::getComposerFile(); |
|
| 290 | + $contents = \file_get_contents($file); |
|
| 291 | + $manipulator = new JsonManipulator($contents); |
|
| 292 | + foreach ($missingRequires as $key => $packages) { |
|
| 293 | + foreach ($packages as $package => $constraint) { |
|
| 294 | + if ('remove' === $key) { |
|
| 295 | + $manipulator->removeSubNode('require-dev', $package); |
|
| 296 | + } else { |
|
| 297 | + $manipulator->addLink($key, $package, $constraint, $sortPackages); |
|
| 298 | + } |
|
| 299 | + } |
|
| 300 | + } |
|
| 301 | + \file_put_contents($file, $manipulator->getContents()); |
|
| 302 | + } |
|
| 303 | + private function updateComposerLock(Composer $composer, IOInterface $io) |
|
| 304 | + { |
|
| 305 | + if (\false === $composer->getConfig()->get('lock')) { |
|
| 306 | + return; |
|
| 307 | + } |
|
| 308 | + $lock = \substr(Factory::getComposerFile(), 0, -4) . 'lock'; |
|
| 309 | + $composerJson = \file_get_contents(Factory::getComposerFile()); |
|
| 310 | + $lockFile = new JsonFile($lock, null, $io); |
|
| 311 | + $locker = ClassDiscovery::safeClassExists(RepositorySet::class) ? new Locker($io, $lockFile, $composer->getInstallationManager(), $composerJson) : new Locker($io, $lockFile, $composer->getRepositoryManager(), $composer->getInstallationManager(), $composerJson); |
|
| 312 | + if (!$locker->isLocked()) { |
|
| 313 | + return; |
|
| 314 | + } |
|
| 315 | + $lockData = $locker->getLockData(); |
|
| 316 | + $lockData['content-hash'] = Locker::getContentHash($composerJson); |
|
| 317 | + $lockFile->write($lockData); |
|
| 318 | + } |
|
| 319 | 319 | } |
@@ -97,7 +97,7 @@ discard block |
||
| 97 | 97 | } |
| 98 | 98 | $event->stopPropagation(); |
| 99 | 99 | $dispatcher = $composer->getEventDispatcher(); |
| 100 | - $disableScripts = !\method_exists($dispatcher, 'setRunScripts') || !((array) $dispatcher)["\x00*\x00runScripts"]; |
|
| 100 | + $disableScripts = !\method_exists($dispatcher, 'setRunScripts') || !((array)$dispatcher)["\x00*\x00runScripts"]; |
|
| 101 | 101 | $composer = Factory::create($event->getIO(), null, \false, $disableScripts); |
| 102 | 102 | /** @var Installer $installer */ |
| 103 | 103 | $installer = clone $installer; |
@@ -107,7 +107,7 @@ discard block |
||
| 107 | 107 | // we need a clone of the installer to preserve its configuration state but with our own service objects |
| 108 | 108 | $installer->__construct($event->getIO(), $composer->getConfig(), $composer->getPackage(), $composer->getDownloadManager(), $composer->getRepositoryManager(), $composer->getLocker(), $composer->getInstallationManager(), $composer->getEventDispatcher(), $composer->getAutoloadGenerator()); |
| 109 | 109 | if (\method_exists($installer, 'setPlatformRequirementFilter')) { |
| 110 | - $installer->setPlatformRequirementFilter(((array) $trace['object'])["\x00*\x00platformRequirementFilter"]); |
|
| 110 | + $installer->setPlatformRequirementFilter(((array)$trace['object'])["\x00*\x00platformRequirementFilter"]); |
|
| 111 | 111 | } |
| 112 | 112 | if (0 !== $installer->run()) { |
| 113 | 113 | \file_put_contents(Factory::getComposerFile(), $composerJsonContents); |
@@ -147,7 +147,7 @@ discard block |
||
| 147 | 147 | } |
| 148 | 148 | } |
| 149 | 149 | if (isset($package->getRequires()['php-http/discovery'])) { |
| 150 | - $requires[(int) isset($devPackages[$package->getName()])] += $package->getRequires(); |
|
| 150 | + $requires[(int)isset($devPackages[$package->getName()])] += $package->getRequires(); |
|
| 151 | 151 | } |
| 152 | 152 | } |
| 153 | 153 | $missingRequires = [[], [], []]; |
@@ -235,7 +235,7 @@ discard block |
||
| 235 | 235 | $filesystem = new Filesystem(); |
| 236 | 236 | // Double realpath() on purpose, see https://bugs.php.net/72738 |
| 237 | 237 | $vendorDir = $filesystem->normalizePath(\realpath(\realpath($event->getComposer()->getConfig()->get('vendor-dir')))); |
| 238 | - $filesystem->ensureDirectoryExists($vendorDir . '/composer'); |
|
| 238 | + $filesystem->ensureDirectoryExists($vendorDir.'/composer'); |
|
| 239 | 239 | $pinned = $event->getComposer()->getPackage()->getExtra()['discovery'] ?? []; |
| 240 | 240 | $candidates = []; |
| 241 | 241 | $allInterfaces = \array_merge(...\array_values(self::INTERFACE_MAP)); |
@@ -251,7 +251,7 @@ discard block |
||
| 251 | 251 | $candidates[] = \sprintf("case %s: return [['class' => %s]];\n", \var_export($interface, \true), \var_export($class, \true)); |
| 252 | 252 | } |
| 253 | 253 | } |
| 254 | - $file = $vendorDir . '/composer/GeneratedDiscoveryStrategy.php'; |
|
| 254 | + $file = $vendorDir.'/composer/GeneratedDiscoveryStrategy.php'; |
|
| 255 | 255 | if (!$candidates) { |
| 256 | 256 | if (\file_exists($file)) { |
| 257 | 257 | \unlink($file); |
@@ -281,7 +281,7 @@ discard block |
||
| 281 | 281 | } |
| 282 | 282 | $rootPackage = $event->getComposer()->getPackage(); |
| 283 | 283 | $autoload = $rootPackage->getAutoload(); |
| 284 | - $autoload['classmap'][] = $vendorDir . '/composer/GeneratedDiscoveryStrategy.php'; |
|
| 284 | + $autoload['classmap'][] = $vendorDir.'/composer/GeneratedDiscoveryStrategy.php'; |
|
| 285 | 285 | $rootPackage->setAutoload($autoload); |
| 286 | 286 | } |
| 287 | 287 | private function updateComposerJson(array $missingRequires, bool $sortPackages) |
@@ -305,7 +305,7 @@ discard block |
||
| 305 | 305 | if (\false === $composer->getConfig()->get('lock')) { |
| 306 | 306 | return; |
| 307 | 307 | } |
| 308 | - $lock = \substr(Factory::getComposerFile(), 0, -4) . 'lock'; |
|
| 308 | + $lock = \substr(Factory::getComposerFile(), 0, -4).'lock'; |
|
| 309 | 309 | $composerJson = \file_get_contents(Factory::getComposerFile()); |
| 310 | 310 | $lockFile = new JsonFile($lock, null, $io); |
| 311 | 311 | $locker = ClassDiscovery::safeClassExists(RepositorySet::class) ? new Locker($io, $lockFile, $composer->getInstallationManager(), $composerJson) : new Locker($io, $lockFile, $composer->getRepositoryManager(), $composer->getInstallationManager(), $composerJson); |
@@ -11,104 +11,104 @@ |
||
| 11 | 11 | */ |
| 12 | 12 | final class TransferStats |
| 13 | 13 | { |
| 14 | - /** |
|
| 15 | - * @var RequestInterface |
|
| 16 | - */ |
|
| 17 | - private $request; |
|
| 18 | - /** |
|
| 19 | - * @var ResponseInterface|null |
|
| 20 | - */ |
|
| 21 | - private $response; |
|
| 22 | - /** |
|
| 23 | - * @var float|null |
|
| 24 | - */ |
|
| 25 | - private $transferTime; |
|
| 26 | - /** |
|
| 27 | - * @var array |
|
| 28 | - */ |
|
| 29 | - private $handlerStats; |
|
| 30 | - /** |
|
| 31 | - * @var mixed|null |
|
| 32 | - */ |
|
| 33 | - private $handlerErrorData; |
|
| 34 | - /** |
|
| 35 | - * @param RequestInterface $request Request that was sent. |
|
| 36 | - * @param ResponseInterface|null $response Response received (if any) |
|
| 37 | - * @param float|null $transferTime Total handler transfer time. |
|
| 38 | - * @param mixed $handlerErrorData Handler error data. |
|
| 39 | - * @param array $handlerStats Handler specific stats. |
|
| 40 | - */ |
|
| 41 | - public function __construct(RequestInterface $request, ?ResponseInterface $response = null, ?float $transferTime = null, $handlerErrorData = null, array $handlerStats = []) |
|
| 42 | - { |
|
| 43 | - $this->request = $request; |
|
| 44 | - $this->response = $response; |
|
| 45 | - $this->transferTime = $transferTime; |
|
| 46 | - $this->handlerErrorData = $handlerErrorData; |
|
| 47 | - $this->handlerStats = $handlerStats; |
|
| 48 | - } |
|
| 49 | - public function getRequest() : RequestInterface |
|
| 50 | - { |
|
| 51 | - return $this->request; |
|
| 52 | - } |
|
| 53 | - /** |
|
| 54 | - * Returns the response that was received (if any). |
|
| 55 | - */ |
|
| 56 | - public function getResponse() : ?ResponseInterface |
|
| 57 | - { |
|
| 58 | - return $this->response; |
|
| 59 | - } |
|
| 60 | - /** |
|
| 61 | - * Returns true if a response was received. |
|
| 62 | - */ |
|
| 63 | - public function hasResponse() : bool |
|
| 64 | - { |
|
| 65 | - return $this->response !== null; |
|
| 66 | - } |
|
| 67 | - /** |
|
| 68 | - * Gets handler specific error data. |
|
| 69 | - * |
|
| 70 | - * This might be an exception, a integer representing an error code, or |
|
| 71 | - * anything else. Relying on this value assumes that you know what handler |
|
| 72 | - * you are using. |
|
| 73 | - * |
|
| 74 | - * @return mixed |
|
| 75 | - */ |
|
| 76 | - public function getHandlerErrorData() |
|
| 77 | - { |
|
| 78 | - return $this->handlerErrorData; |
|
| 79 | - } |
|
| 80 | - /** |
|
| 81 | - * Get the effective URI the request was sent to. |
|
| 82 | - */ |
|
| 83 | - public function getEffectiveUri() : UriInterface |
|
| 84 | - { |
|
| 85 | - return $this->request->getUri(); |
|
| 86 | - } |
|
| 87 | - /** |
|
| 88 | - * Get the estimated time the request was being transferred by the handler. |
|
| 89 | - * |
|
| 90 | - * @return float|null Time in seconds. |
|
| 91 | - */ |
|
| 92 | - public function getTransferTime() : ?float |
|
| 93 | - { |
|
| 94 | - return $this->transferTime; |
|
| 95 | - } |
|
| 96 | - /** |
|
| 97 | - * Gets an array of all of the handler specific transfer data. |
|
| 98 | - */ |
|
| 99 | - public function getHandlerStats() : array |
|
| 100 | - { |
|
| 101 | - return $this->handlerStats; |
|
| 102 | - } |
|
| 103 | - /** |
|
| 104 | - * Get a specific handler statistic from the handler by name. |
|
| 105 | - * |
|
| 106 | - * @param string $stat Handler specific transfer stat to retrieve. |
|
| 107 | - * |
|
| 108 | - * @return mixed|null |
|
| 109 | - */ |
|
| 110 | - public function getHandlerStat(string $stat) |
|
| 111 | - { |
|
| 112 | - return $this->handlerStats[$stat] ?? null; |
|
| 113 | - } |
|
| 14 | + /** |
|
| 15 | + * @var RequestInterface |
|
| 16 | + */ |
|
| 17 | + private $request; |
|
| 18 | + /** |
|
| 19 | + * @var ResponseInterface|null |
|
| 20 | + */ |
|
| 21 | + private $response; |
|
| 22 | + /** |
|
| 23 | + * @var float|null |
|
| 24 | + */ |
|
| 25 | + private $transferTime; |
|
| 26 | + /** |
|
| 27 | + * @var array |
|
| 28 | + */ |
|
| 29 | + private $handlerStats; |
|
| 30 | + /** |
|
| 31 | + * @var mixed|null |
|
| 32 | + */ |
|
| 33 | + private $handlerErrorData; |
|
| 34 | + /** |
|
| 35 | + * @param RequestInterface $request Request that was sent. |
|
| 36 | + * @param ResponseInterface|null $response Response received (if any) |
|
| 37 | + * @param float|null $transferTime Total handler transfer time. |
|
| 38 | + * @param mixed $handlerErrorData Handler error data. |
|
| 39 | + * @param array $handlerStats Handler specific stats. |
|
| 40 | + */ |
|
| 41 | + public function __construct(RequestInterface $request, ?ResponseInterface $response = null, ?float $transferTime = null, $handlerErrorData = null, array $handlerStats = []) |
|
| 42 | + { |
|
| 43 | + $this->request = $request; |
|
| 44 | + $this->response = $response; |
|
| 45 | + $this->transferTime = $transferTime; |
|
| 46 | + $this->handlerErrorData = $handlerErrorData; |
|
| 47 | + $this->handlerStats = $handlerStats; |
|
| 48 | + } |
|
| 49 | + public function getRequest() : RequestInterface |
|
| 50 | + { |
|
| 51 | + return $this->request; |
|
| 52 | + } |
|
| 53 | + /** |
|
| 54 | + * Returns the response that was received (if any). |
|
| 55 | + */ |
|
| 56 | + public function getResponse() : ?ResponseInterface |
|
| 57 | + { |
|
| 58 | + return $this->response; |
|
| 59 | + } |
|
| 60 | + /** |
|
| 61 | + * Returns true if a response was received. |
|
| 62 | + */ |
|
| 63 | + public function hasResponse() : bool |
|
| 64 | + { |
|
| 65 | + return $this->response !== null; |
|
| 66 | + } |
|
| 67 | + /** |
|
| 68 | + * Gets handler specific error data. |
|
| 69 | + * |
|
| 70 | + * This might be an exception, a integer representing an error code, or |
|
| 71 | + * anything else. Relying on this value assumes that you know what handler |
|
| 72 | + * you are using. |
|
| 73 | + * |
|
| 74 | + * @return mixed |
|
| 75 | + */ |
|
| 76 | + public function getHandlerErrorData() |
|
| 77 | + { |
|
| 78 | + return $this->handlerErrorData; |
|
| 79 | + } |
|
| 80 | + /** |
|
| 81 | + * Get the effective URI the request was sent to. |
|
| 82 | + */ |
|
| 83 | + public function getEffectiveUri() : UriInterface |
|
| 84 | + { |
|
| 85 | + return $this->request->getUri(); |
|
| 86 | + } |
|
| 87 | + /** |
|
| 88 | + * Get the estimated time the request was being transferred by the handler. |
|
| 89 | + * |
|
| 90 | + * @return float|null Time in seconds. |
|
| 91 | + */ |
|
| 92 | + public function getTransferTime() : ?float |
|
| 93 | + { |
|
| 94 | + return $this->transferTime; |
|
| 95 | + } |
|
| 96 | + /** |
|
| 97 | + * Gets an array of all of the handler specific transfer data. |
|
| 98 | + */ |
|
| 99 | + public function getHandlerStats() : array |
|
| 100 | + { |
|
| 101 | + return $this->handlerStats; |
|
| 102 | + } |
|
| 103 | + /** |
|
| 104 | + * Get a specific handler statistic from the handler by name. |
|
| 105 | + * |
|
| 106 | + * @param string $stat Handler specific transfer stat to retrieve. |
|
| 107 | + * |
|
| 108 | + * @return mixed|null |
|
| 109 | + */ |
|
| 110 | + public function getHandlerStat(string $stat) |
|
| 111 | + { |
|
| 112 | + return $this->handlerStats[$stat] ?? null; |
|
| 113 | + } |
|
| 114 | 114 | } |