@@ -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,38 +276,38 @@ 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 | - $lock = \substr(Factory::getComposerFile(), 0, -4) . 'lock'; |
|
| 306 | - $composerJson = \file_get_contents(Factory::getComposerFile()); |
|
| 307 | - $lockFile = new JsonFile($lock, null, $io); |
|
| 308 | - $locker = ClassDiscovery::safeClassExists(RepositorySet::class) ? new Locker($io, $lockFile, $composer->getInstallationManager(), $composerJson) : new Locker($io, $lockFile, $composer->getRepositoryManager(), $composer->getInstallationManager(), $composerJson); |
|
| 309 | - $lockData = $locker->getLockData(); |
|
| 310 | - $lockData['content-hash'] = Locker::getContentHash($composerJson); |
|
| 311 | - $lockFile->write($lockData); |
|
| 312 | - } |
|
| 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 | + $lock = \substr(Factory::getComposerFile(), 0, -4) . 'lock'; |
|
| 306 | + $composerJson = \file_get_contents(Factory::getComposerFile()); |
|
| 307 | + $lockFile = new JsonFile($lock, null, $io); |
|
| 308 | + $locker = ClassDiscovery::safeClassExists(RepositorySet::class) ? new Locker($io, $lockFile, $composer->getInstallationManager(), $composerJson) : new Locker($io, $lockFile, $composer->getRepositoryManager(), $composer->getInstallationManager(), $composerJson); |
|
| 309 | + $lockData = $locker->getLockData(); |
|
| 310 | + $lockData['content-hash'] = Locker::getContentHash($composerJson); |
|
| 311 | + $lockFile->write($lockData); |
|
| 312 | + } |
|
| 313 | 313 | } |
@@ -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) |
@@ -302,7 +302,7 @@ discard block |
||
| 302 | 302 | } |
| 303 | 303 | private function updateComposerLock(Composer $composer, IOInterface $io) |
| 304 | 304 | { |
| 305 | - $lock = \substr(Factory::getComposerFile(), 0, -4) . 'lock'; |
|
| 305 | + $lock = \substr(Factory::getComposerFile(), 0, -4).'lock'; |
|
| 306 | 306 | $composerJson = \file_get_contents(Factory::getComposerFile()); |
| 307 | 307 | $lockFile = new JsonFile($lock, null, $io); |
| 308 | 308 | $locker = ClassDiscovery::safeClassExists(RepositorySet::class) ? new Locker($io, $lockFile, $composer->getInstallationManager(), $composerJson) : new Locker($io, $lockFile, $composer->getRepositoryManager(), $composer->getInstallationManager(), $composerJson); |
@@ -10,6 +10,5 @@ |
||
| 10 | 10 | * |
| 11 | 11 | * @deprecated since since version 1.0, and will be removed in 2.0. Use {@link \Http\Discovery\Exception\NotFoundException} instead. |
| 12 | 12 | */ |
| 13 | -final class NotFoundException extends RealNotFoundException |
|
| 14 | -{ |
|
| 13 | +final class NotFoundException extends RealNotFoundException { |
|
| 15 | 14 | } |
@@ -21,14 +21,14 @@ |
||
| 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 | - parent::__construct($requestFactory, $responseFactory, $serverRequestFactory, $streamFactory, $uploadedFileFactory, $uriFactory); |
|
| 28 | - $this->client = $client ?? Psr18ClientDiscovery::find(); |
|
| 29 | - } |
|
| 30 | - public function sendRequest(RequestInterface $request) : ResponseInterface |
|
| 31 | - { |
|
| 32 | - return $this->client->sendRequest($request); |
|
| 33 | - } |
|
| 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 | + parent::__construct($requestFactory, $responseFactory, $serverRequestFactory, $streamFactory, $uploadedFileFactory, $uriFactory); |
|
| 28 | + $this->client = $client ?? Psr18ClientDiscovery::find(); |
|
| 29 | + } |
|
| 30 | + public function sendRequest(RequestInterface $request) : ResponseInterface |
|
| 31 | + { |
|
| 32 | + return $this->client->sendRequest($request); |
|
| 33 | + } |
|
| 34 | 34 | } |
@@ -19,8 +19,7 @@ |
||
| 19 | 19 | * |
| 20 | 20 | * @author Nicolas Grekas <[email protected]> |
| 21 | 21 | */ |
| 22 | -class Psr18Client extends Psr17Factory implements ClientInterface |
|
| 23 | -{ |
|
| 22 | +class Psr18Client extends Psr17Factory implements ClientInterface { |
|
| 24 | 23 | private $client; |
| 25 | 24 | 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 | 25 | { |
@@ -12,11 +12,11 @@ |
||
| 12 | 12 | */ |
| 13 | 13 | final class MockClientStrategy implements DiscoveryStrategy |
| 14 | 14 | { |
| 15 | - public static function getCandidates($type) |
|
| 16 | - { |
|
| 17 | - if (\is_a(HttpClient::class, $type, \true) || \is_a(HttpAsyncClient::class, $type, \true)) { |
|
| 18 | - return [['class' => Mock::class, 'condition' => Mock::class]]; |
|
| 19 | - } |
|
| 20 | - return []; |
|
| 21 | - } |
|
| 15 | + public static function getCandidates($type) |
|
| 16 | + { |
|
| 17 | + if (\is_a(HttpClient::class, $type, \true) || \is_a(HttpAsyncClient::class, $type, \true)) { |
|
| 18 | + return [['class' => Mock::class, 'condition' => Mock::class]]; |
|
| 19 | + } |
|
| 20 | + return []; |
|
| 21 | + } |
|
| 22 | 22 | } |
@@ -10,8 +10,7 @@ |
||
| 10 | 10 | * |
| 11 | 11 | * @author Sam Rapaport <[email protected]> |
| 12 | 12 | */ |
| 13 | -final class MockClientStrategy implements DiscoveryStrategy |
|
| 14 | -{ |
|
| 13 | +final class MockClientStrategy implements DiscoveryStrategy { |
|
| 15 | 14 | public static function getCandidates($type) |
| 16 | 15 | { |
| 17 | 16 | if (\is_a(HttpClient::class, $type, \true) || \is_a(HttpAsyncClient::class, $type, \true)) { |
@@ -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 | } |
@@ -11,8 +11,7 @@ |
||
| 11 | 11 | * |
| 12 | 12 | * @author Márk Sági-Kazár <[email protected]> |
| 13 | 13 | */ |
| 14 | -class NetworkException extends TransferException implements PsrNetworkException |
|
| 15 | -{ |
|
| 14 | +class NetworkException extends TransferException implements PsrNetworkException { |
|
| 16 | 15 | use RequestAwareTrait; |
| 17 | 16 | /** |
| 18 | 17 | * @param string $message |
@@ -5,19 +5,19 @@ |
||
| 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 | - /** |
|
| 17 | - * {@inheritdoc} |
|
| 18 | - */ |
|
| 19 | - public function getRequest() : RequestInterface |
|
| 20 | - { |
|
| 21 | - return $this->request; |
|
| 22 | - } |
|
| 8 | + /** |
|
| 9 | + * @var RequestInterface |
|
| 10 | + */ |
|
| 11 | + private $request; |
|
| 12 | + private function setRequest(RequestInterface $request) |
|
| 13 | + { |
|
| 14 | + $this->request = $request; |
|
| 15 | + } |
|
| 16 | + /** |
|
| 17 | + * {@inheritdoc} |
|
| 18 | + */ |
|
| 19 | + public function getRequest() : RequestInterface |
|
| 20 | + { |
|
| 21 | + return $this->request; |
|
| 22 | + } |
|
| 23 | 23 | } |
@@ -3,8 +3,7 @@ |
||
| 3 | 3 | namespace OCA\FullTextSearch_Elasticsearch\Vendor\Http\Client\Exception; |
| 4 | 4 | |
| 5 | 5 | use OCA\FullTextSearch_Elasticsearch\Vendor\Psr\Http\Message\RequestInterface; |
| 6 | -trait RequestAwareTrait |
|
| 7 | -{ |
|
| 6 | +trait RequestAwareTrait { |
|
| 8 | 7 | /** |
| 9 | 8 | * @var RequestInterface |
| 10 | 9 | */ |
@@ -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 | } |
@@ -12,8 +12,7 @@ |
||
| 12 | 12 | * |
| 13 | 13 | * @author Márk Sági-Kazár <[email protected]> |
| 14 | 14 | */ |
| 15 | -class RequestException extends TransferException implements PsrRequestException |
|
| 16 | -{ |
|
| 15 | +class RequestException extends TransferException implements PsrRequestException { |
|
| 17 | 16 | use RequestAwareTrait; |
| 18 | 17 | /** |
| 19 | 18 | * @param string $message |
@@ -7,42 +7,42 @@ |
||
| 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 | - /** |
|
| 19 | - * {@inheritdoc} |
|
| 20 | - */ |
|
| 21 | - public function then(callable $onFulfilled = null, callable $onRejected = null) |
|
| 22 | - { |
|
| 23 | - if (null === $onFulfilled) { |
|
| 24 | - return $this; |
|
| 25 | - } |
|
| 26 | - try { |
|
| 27 | - return new self($onFulfilled($this->response)); |
|
| 28 | - } catch (Exception $e) { |
|
| 29 | - return new HttpRejectedPromise($e); |
|
| 30 | - } |
|
| 31 | - } |
|
| 32 | - /** |
|
| 33 | - * {@inheritdoc} |
|
| 34 | - */ |
|
| 35 | - public function getState() |
|
| 36 | - { |
|
| 37 | - return Promise::FULFILLED; |
|
| 38 | - } |
|
| 39 | - /** |
|
| 40 | - * {@inheritdoc} |
|
| 41 | - */ |
|
| 42 | - public function wait($unwrap = \true) |
|
| 43 | - { |
|
| 44 | - if ($unwrap) { |
|
| 45 | - return $this->response; |
|
| 46 | - } |
|
| 47 | - } |
|
| 10 | + /** |
|
| 11 | + * @var ResponseInterface |
|
| 12 | + */ |
|
| 13 | + private $response; |
|
| 14 | + public function __construct(ResponseInterface $response) |
|
| 15 | + { |
|
| 16 | + $this->response = $response; |
|
| 17 | + } |
|
| 18 | + /** |
|
| 19 | + * {@inheritdoc} |
|
| 20 | + */ |
|
| 21 | + public function then(callable $onFulfilled = null, callable $onRejected = null) |
|
| 22 | + { |
|
| 23 | + if (null === $onFulfilled) { |
|
| 24 | + return $this; |
|
| 25 | + } |
|
| 26 | + try { |
|
| 27 | + return new self($onFulfilled($this->response)); |
|
| 28 | + } catch (Exception $e) { |
|
| 29 | + return new HttpRejectedPromise($e); |
|
| 30 | + } |
|
| 31 | + } |
|
| 32 | + /** |
|
| 33 | + * {@inheritdoc} |
|
| 34 | + */ |
|
| 35 | + public function getState() |
|
| 36 | + { |
|
| 37 | + return Promise::FULFILLED; |
|
| 38 | + } |
|
| 39 | + /** |
|
| 40 | + * {@inheritdoc} |
|
| 41 | + */ |
|
| 42 | + public function wait($unwrap = \true) |
|
| 43 | + { |
|
| 44 | + if ($unwrap) { |
|
| 45 | + return $this->response; |
|
| 46 | + } |
|
| 47 | + } |
|
| 48 | 48 | } |
@@ -5,8 +5,7 @@ |
||
| 5 | 5 | use OCA\FullTextSearch_Elasticsearch\Vendor\Http\Client\Exception; |
| 6 | 6 | use OCA\FullTextSearch_Elasticsearch\Vendor\Http\Promise\Promise; |
| 7 | 7 | use OCA\FullTextSearch_Elasticsearch\Vendor\Psr\Http\Message\ResponseInterface; |
| 8 | -final class HttpFulfilledPromise implements Promise |
|
| 9 | -{ |
|
| 8 | +final class HttpFulfilledPromise implements Promise { |
|
| 10 | 9 | /** |
| 11 | 10 | * @var ResponseInterface |
| 12 | 11 | */ |
@@ -11,6 +11,5 @@ |
||
| 11 | 11 | * |
| 12 | 12 | * @deprecated since version 2.4, use Psr\Http\Client\ClientInterface instead; see https://www.php-fig.org/psr/psr-18/ |
| 13 | 13 | */ |
| 14 | -interface HttpClient extends ClientInterface |
|
| 15 | -{ |
|
| 14 | +interface HttpClient extends ClientInterface { |
|
| 16 | 15 | } |