Completed
Pull Request — master (#359)
by Maxence
41s
created
lib/Vendor/Psr/Http/Message/ResponseFactoryInterface.php 2 patches
Indentation   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -4,15 +4,15 @@
 block discarded – undo
4 4
 
5 5
 interface ResponseFactoryInterface
6 6
 {
7
-    /**
8
-     * Create a new response.
9
-     *
10
-     * @param int $code HTTP status code; defaults to 200
11
-     * @param string $reasonPhrase Reason phrase to associate with status code
12
-     *     in generated response; if none is provided implementations MAY use
13
-     *     the defaults as suggested in the HTTP specification.
14
-     *
15
-     * @return ResponseInterface
16
-     */
17
-    public function createResponse(int $code = 200, string $reasonPhrase = ''): ResponseInterface;
7
+	/**
8
+	 * Create a new response.
9
+	 *
10
+	 * @param int $code HTTP status code; defaults to 200
11
+	 * @param string $reasonPhrase Reason phrase to associate with status code
12
+	 *     in generated response; if none is provided implementations MAY use
13
+	 *     the defaults as suggested in the HTTP specification.
14
+	 *
15
+	 * @return ResponseInterface
16
+	 */
17
+	public function createResponse(int $code = 200, string $reasonPhrase = ''): ResponseInterface;
18 18
 }
Please login to merge, or discard this patch.
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -2,8 +2,7 @@
 block discarded – undo
2 2
 
3 3
 namespace OCA\FullTextSearch_Elasticsearch\Vendor\Psr\Http\Message;
4 4
 
5
-interface ResponseFactoryInterface
6
-{
5
+interface ResponseFactoryInterface {
7 6
     /**
8 7
      * Create a new response.
9 8
      *
Please login to merge, or discard this patch.
lib/Vendor/Psr/Http/Message/StreamInterface.php 2 patches
Indentation   +144 added lines, -144 removed lines patch added patch discarded remove patch
@@ -11,148 +11,148 @@
 block discarded – undo
11 11
  */
12 12
 interface StreamInterface
13 13
 {
14
-    /**
15
-     * Reads all data from the stream into a string, from the beginning to end.
16
-     *
17
-     * This method MUST attempt to seek to the beginning of the stream before
18
-     * reading data and read the stream until the end is reached.
19
-     *
20
-     * Warning: This could attempt to load a large amount of data into memory.
21
-     *
22
-     * This method MUST NOT raise an exception in order to conform with PHP's
23
-     * string casting operations.
24
-     *
25
-     * @see http://php.net/manual/en/language.oop5.magic.php#object.tostring
26
-     * @return string
27
-     */
28
-    public function __toString(): string;
29
-
30
-    /**
31
-     * Closes the stream and any underlying resources.
32
-     *
33
-     * @return void
34
-     */
35
-    public function close(): void;
36
-
37
-    /**
38
-     * Separates any underlying resources from the stream.
39
-     *
40
-     * After the stream has been detached, the stream is in an unusable state.
41
-     *
42
-     * @return resource|null Underlying PHP stream, if any
43
-     */
44
-    public function detach();
45
-
46
-    /**
47
-     * Get the size of the stream if known.
48
-     *
49
-     * @return int|null Returns the size in bytes if known, or null if unknown.
50
-     */
51
-    public function getSize(): ?int;
52
-
53
-    /**
54
-     * Returns the current position of the file read/write pointer
55
-     *
56
-     * @return int Position of the file pointer
57
-     * @throws \RuntimeException on error.
58
-     */
59
-    public function tell(): int;
60
-
61
-    /**
62
-     * Returns true if the stream is at the end of the stream.
63
-     *
64
-     * @return bool
65
-     */
66
-    public function eof(): bool;
67
-
68
-    /**
69
-     * Returns whether or not the stream is seekable.
70
-     *
71
-     * @return bool
72
-     */
73
-    public function isSeekable(): bool;
74
-
75
-    /**
76
-     * Seek to a position in the stream.
77
-     *
78
-     * @link http://www.php.net/manual/en/function.fseek.php
79
-     * @param int $offset Stream offset
80
-     * @param int $whence Specifies how the cursor position will be calculated
81
-     *     based on the seek offset. Valid values are identical to the built-in
82
-     *     PHP $whence values for `fseek()`.  SEEK_SET: Set position equal to
83
-     *     offset bytes SEEK_CUR: Set position to current location plus offset
84
-     *     SEEK_END: Set position to end-of-stream plus offset.
85
-     * @throws \RuntimeException on failure.
86
-     */
87
-    public function seek(int $offset, int $whence = SEEK_SET): void;
88
-
89
-    /**
90
-     * Seek to the beginning of the stream.
91
-     *
92
-     * If the stream is not seekable, this method will raise an exception;
93
-     * otherwise, it will perform a seek(0).
94
-     *
95
-     * @see seek()
96
-     * @link http://www.php.net/manual/en/function.fseek.php
97
-     * @throws \RuntimeException on failure.
98
-     */
99
-    public function rewind(): void;
100
-
101
-    /**
102
-     * Returns whether or not the stream is writable.
103
-     *
104
-     * @return bool
105
-     */
106
-    public function isWritable(): bool;
107
-
108
-    /**
109
-     * Write data to the stream.
110
-     *
111
-     * @param string $string The string that is to be written.
112
-     * @return int Returns the number of bytes written to the stream.
113
-     * @throws \RuntimeException on failure.
114
-     */
115
-    public function write(string $string): int;
116
-
117
-    /**
118
-     * Returns whether or not the stream is readable.
119
-     *
120
-     * @return bool
121
-     */
122
-    public function isReadable(): bool;
123
-
124
-    /**
125
-     * Read data from the stream.
126
-     *
127
-     * @param int $length Read up to $length bytes from the object and return
128
-     *     them. Fewer than $length bytes may be returned if underlying stream
129
-     *     call returns fewer bytes.
130
-     * @return string Returns the data read from the stream, or an empty string
131
-     *     if no bytes are available.
132
-     * @throws \RuntimeException if an error occurs.
133
-     */
134
-    public function read(int $length): string;
135
-
136
-    /**
137
-     * Returns the remaining contents in a string
138
-     *
139
-     * @return string
140
-     * @throws \RuntimeException if unable to read or an error occurs while
141
-     *     reading.
142
-     */
143
-    public function getContents(): string;
144
-
145
-    /**
146
-     * Get stream metadata as an associative array or retrieve a specific key.
147
-     *
148
-     * The keys returned are identical to the keys returned from PHP's
149
-     * stream_get_meta_data() function.
150
-     *
151
-     * @link http://php.net/manual/en/function.stream-get-meta-data.php
152
-     * @param string|null $key Specific metadata to retrieve.
153
-     * @return array|mixed|null Returns an associative array if no key is
154
-     *     provided. Returns a specific key value if a key is provided and the
155
-     *     value is found, or null if the key is not found.
156
-     */
157
-    public function getMetadata(?string $key = null);
14
+	/**
15
+	 * Reads all data from the stream into a string, from the beginning to end.
16
+	 *
17
+	 * This method MUST attempt to seek to the beginning of the stream before
18
+	 * reading data and read the stream until the end is reached.
19
+	 *
20
+	 * Warning: This could attempt to load a large amount of data into memory.
21
+	 *
22
+	 * This method MUST NOT raise an exception in order to conform with PHP's
23
+	 * string casting operations.
24
+	 *
25
+	 * @see http://php.net/manual/en/language.oop5.magic.php#object.tostring
26
+	 * @return string
27
+	 */
28
+	public function __toString(): string;
29
+
30
+	/**
31
+	 * Closes the stream and any underlying resources.
32
+	 *
33
+	 * @return void
34
+	 */
35
+	public function close(): void;
36
+
37
+	/**
38
+	 * Separates any underlying resources from the stream.
39
+	 *
40
+	 * After the stream has been detached, the stream is in an unusable state.
41
+	 *
42
+	 * @return resource|null Underlying PHP stream, if any
43
+	 */
44
+	public function detach();
45
+
46
+	/**
47
+	 * Get the size of the stream if known.
48
+	 *
49
+	 * @return int|null Returns the size in bytes if known, or null if unknown.
50
+	 */
51
+	public function getSize(): ?int;
52
+
53
+	/**
54
+	 * Returns the current position of the file read/write pointer
55
+	 *
56
+	 * @return int Position of the file pointer
57
+	 * @throws \RuntimeException on error.
58
+	 */
59
+	public function tell(): int;
60
+
61
+	/**
62
+	 * Returns true if the stream is at the end of the stream.
63
+	 *
64
+	 * @return bool
65
+	 */
66
+	public function eof(): bool;
67
+
68
+	/**
69
+	 * Returns whether or not the stream is seekable.
70
+	 *
71
+	 * @return bool
72
+	 */
73
+	public function isSeekable(): bool;
74
+
75
+	/**
76
+	 * Seek to a position in the stream.
77
+	 *
78
+	 * @link http://www.php.net/manual/en/function.fseek.php
79
+	 * @param int $offset Stream offset
80
+	 * @param int $whence Specifies how the cursor position will be calculated
81
+	 *     based on the seek offset. Valid values are identical to the built-in
82
+	 *     PHP $whence values for `fseek()`.  SEEK_SET: Set position equal to
83
+	 *     offset bytes SEEK_CUR: Set position to current location plus offset
84
+	 *     SEEK_END: Set position to end-of-stream plus offset.
85
+	 * @throws \RuntimeException on failure.
86
+	 */
87
+	public function seek(int $offset, int $whence = SEEK_SET): void;
88
+
89
+	/**
90
+	 * Seek to the beginning of the stream.
91
+	 *
92
+	 * If the stream is not seekable, this method will raise an exception;
93
+	 * otherwise, it will perform a seek(0).
94
+	 *
95
+	 * @see seek()
96
+	 * @link http://www.php.net/manual/en/function.fseek.php
97
+	 * @throws \RuntimeException on failure.
98
+	 */
99
+	public function rewind(): void;
100
+
101
+	/**
102
+	 * Returns whether or not the stream is writable.
103
+	 *
104
+	 * @return bool
105
+	 */
106
+	public function isWritable(): bool;
107
+
108
+	/**
109
+	 * Write data to the stream.
110
+	 *
111
+	 * @param string $string The string that is to be written.
112
+	 * @return int Returns the number of bytes written to the stream.
113
+	 * @throws \RuntimeException on failure.
114
+	 */
115
+	public function write(string $string): int;
116
+
117
+	/**
118
+	 * Returns whether or not the stream is readable.
119
+	 *
120
+	 * @return bool
121
+	 */
122
+	public function isReadable(): bool;
123
+
124
+	/**
125
+	 * Read data from the stream.
126
+	 *
127
+	 * @param int $length Read up to $length bytes from the object and return
128
+	 *     them. Fewer than $length bytes may be returned if underlying stream
129
+	 *     call returns fewer bytes.
130
+	 * @return string Returns the data read from the stream, or an empty string
131
+	 *     if no bytes are available.
132
+	 * @throws \RuntimeException if an error occurs.
133
+	 */
134
+	public function read(int $length): string;
135
+
136
+	/**
137
+	 * Returns the remaining contents in a string
138
+	 *
139
+	 * @return string
140
+	 * @throws \RuntimeException if unable to read or an error occurs while
141
+	 *     reading.
142
+	 */
143
+	public function getContents(): string;
144
+
145
+	/**
146
+	 * Get stream metadata as an associative array or retrieve a specific key.
147
+	 *
148
+	 * The keys returned are identical to the keys returned from PHP's
149
+	 * stream_get_meta_data() function.
150
+	 *
151
+	 * @link http://php.net/manual/en/function.stream-get-meta-data.php
152
+	 * @param string|null $key Specific metadata to retrieve.
153
+	 * @return array|mixed|null Returns an associative array if no key is
154
+	 *     provided. Returns a specific key value if a key is provided and the
155
+	 *     value is found, or null if the key is not found.
156
+	 */
157
+	public function getMetadata(?string $key = null);
158 158
 }
Please login to merge, or discard this patch.
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -9,8 +9,7 @@
 block discarded – undo
9 9
  * a wrapper around the most common operations, including serialization of
10 10
  * the entire stream to a string.
11 11
  */
12
-interface StreamInterface
13
-{
12
+interface StreamInterface {
14 13
     /**
15 14
      * Reads all data from the stream into a string, from the beginning to end.
16 15
      *
Please login to merge, or discard this patch.
lib/Vendor/Psr/Http/Message/RequestFactoryInterface.php 2 patches
Indentation   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -4,15 +4,15 @@
 block discarded – undo
4 4
 
5 5
 interface RequestFactoryInterface
6 6
 {
7
-    /**
8
-     * Create a new request.
9
-     *
10
-     * @param string $method The HTTP method associated with the request.
11
-     * @param UriInterface|string $uri The URI associated with the request. If
12
-     *     the value is a string, the factory MUST create a UriInterface
13
-     *     instance based on it.
14
-     *
15
-     * @return RequestInterface
16
-     */
17
-    public function createRequest(string $method, $uri): RequestInterface;
7
+	/**
8
+	 * Create a new request.
9
+	 *
10
+	 * @param string $method The HTTP method associated with the request.
11
+	 * @param UriInterface|string $uri The URI associated with the request. If
12
+	 *     the value is a string, the factory MUST create a UriInterface
13
+	 *     instance based on it.
14
+	 *
15
+	 * @return RequestInterface
16
+	 */
17
+	public function createRequest(string $method, $uri): RequestInterface;
18 18
 }
Please login to merge, or discard this patch.
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -2,8 +2,7 @@
 block discarded – undo
2 2
 
3 3
 namespace OCA\FullTextSearch_Elasticsearch\Vendor\Psr\Http\Message;
4 4
 
5
-interface RequestFactoryInterface
6
-{
5
+interface RequestFactoryInterface {
7 6
     /**
8 7
      * Create a new request.
9 8
      *
Please login to merge, or discard this patch.
lib/Vendor/Psr/Http/Client/RequestExceptionInterface.php 2 patches
Indentation   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -13,12 +13,12 @@
 block discarded – undo
13 13
  */
14 14
 interface RequestExceptionInterface extends ClientExceptionInterface
15 15
 {
16
-    /**
17
-     * Returns the request.
18
-     *
19
-     * The request object MAY be a different object from the one passed to ClientInterface::sendRequest()
20
-     *
21
-     * @return RequestInterface
22
-     */
23
-    public function getRequest(): RequestInterface;
16
+	/**
17
+	 * Returns the request.
18
+	 *
19
+	 * The request object MAY be a different object from the one passed to ClientInterface::sendRequest()
20
+	 *
21
+	 * @return RequestInterface
22
+	 */
23
+	public function getRequest(): RequestInterface;
24 24
 }
Please login to merge, or discard this patch.
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -11,8 +11,7 @@
 block discarded – undo
11 11
  *      - Request is invalid (e.g. method is missing)
12 12
  *      - Runtime request errors (e.g. the body stream is not seekable)
13 13
  */
14
-interface RequestExceptionInterface extends ClientExceptionInterface
15
-{
14
+interface RequestExceptionInterface extends ClientExceptionInterface {
16 15
     /**
17 16
      * Returns the request.
18 17
      *
Please login to merge, or discard this patch.
lib/Vendor/Psr/Http/Client/ClientInterface.php 2 patches
Indentation   +10 added lines, -10 removed lines patch added patch discarded remove patch
@@ -7,14 +7,14 @@
 block discarded – undo
7 7
 
8 8
 interface ClientInterface
9 9
 {
10
-    /**
11
-     * Sends a PSR-7 request and returns a PSR-7 response.
12
-     *
13
-     * @param RequestInterface $request
14
-     *
15
-     * @return ResponseInterface
16
-     *
17
-     * @throws \OCA\FullTextSearch_Elasticsearch\Vendor\Psr\Http\Client\ClientExceptionInterface If an error happens while processing the request.
18
-     */
19
-    public function sendRequest(RequestInterface $request): ResponseInterface;
10
+	/**
11
+	 * Sends a PSR-7 request and returns a PSR-7 response.
12
+	 *
13
+	 * @param RequestInterface $request
14
+	 *
15
+	 * @return ResponseInterface
16
+	 *
17
+	 * @throws \OCA\FullTextSearch_Elasticsearch\Vendor\Psr\Http\Client\ClientExceptionInterface If an error happens while processing the request.
18
+	 */
19
+	public function sendRequest(RequestInterface $request): ResponseInterface;
20 20
 }
Please login to merge, or discard this patch.
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -5,8 +5,7 @@
 block discarded – undo
5 5
 use OCA\FullTextSearch_Elasticsearch\Vendor\Psr\Http\Message\RequestInterface;
6 6
 use OCA\FullTextSearch_Elasticsearch\Vendor\Psr\Http\Message\ResponseInterface;
7 7
 
8
-interface ClientInterface
9
-{
8
+interface ClientInterface {
10 9
     /**
11 10
      * Sends a PSR-7 request and returns a PSR-7 response.
12 11
      *
Please login to merge, or discard this patch.
lib/Vendor/Psr/Http/Client/NetworkExceptionInterface.php 2 patches
Indentation   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -13,12 +13,12 @@
 block discarded – undo
13 13
  */
14 14
 interface NetworkExceptionInterface extends ClientExceptionInterface
15 15
 {
16
-    /**
17
-     * Returns the request.
18
-     *
19
-     * The request object MAY be a different object from the one passed to ClientInterface::sendRequest()
20
-     *
21
-     * @return RequestInterface
22
-     */
23
-    public function getRequest(): RequestInterface;
16
+	/**
17
+	 * Returns the request.
18
+	 *
19
+	 * The request object MAY be a different object from the one passed to ClientInterface::sendRequest()
20
+	 *
21
+	 * @return RequestInterface
22
+	 */
23
+	public function getRequest(): RequestInterface;
24 24
 }
Please login to merge, or discard this patch.
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -11,8 +11,7 @@
 block discarded – undo
11 11
  *
12 12
  * Example: the target host name can not be resolved or the connection failed.
13 13
  */
14
-interface NetworkExceptionInterface extends ClientExceptionInterface
15
-{
14
+interface NetworkExceptionInterface extends ClientExceptionInterface {
16 15
     /**
17 16
      * Returns the request.
18 17
      *
Please login to merge, or discard this patch.
lib/Vendor/Http/Discovery/UriFactoryDiscovery.php 2 patches
Indentation   +16 added lines, -16 removed lines patch added patch discarded remove patch
@@ -14,21 +14,21 @@
 block discarded – undo
14 14
  */
15 15
 final class UriFactoryDiscovery extends ClassDiscovery
16 16
 {
17
-    /**
18
-     * Finds a URI Factory.
19
-     *
20
-     * @return UriFactory
21
-     *
22
-     * @throws Exception\NotFoundException
23
-     */
24
-    public static function find()
25
-    {
26
-        try {
27
-            $uriFactory = static::findOneByType(UriFactory::class);
28
-        } catch (DiscoveryFailedException $e) {
29
-            throw new NotFoundException('No uri factories found. To use Guzzle, Diactoros or Slim Framework factories install php-http/message and the chosen message implementation.', 0, $e);
30
-        }
17
+	/**
18
+	 * Finds a URI Factory.
19
+	 *
20
+	 * @return UriFactory
21
+	 *
22
+	 * @throws Exception\NotFoundException
23
+	 */
24
+	public static function find()
25
+	{
26
+		try {
27
+			$uriFactory = static::findOneByType(UriFactory::class);
28
+		} catch (DiscoveryFailedException $e) {
29
+			throw new NotFoundException('No uri factories found. To use Guzzle, Diactoros or Slim Framework factories install php-http/message and the chosen message implementation.', 0, $e);
30
+		}
31 31
 
32
-        return static::instantiateClass($uriFactory);
33
-    }
32
+		return static::instantiateClass($uriFactory);
33
+	}
34 34
 }
Please login to merge, or discard this patch.
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -12,8 +12,7 @@
 block discarded – undo
12 12
  *
13 13
  * @deprecated This will be removed in 2.0. Consider using Psr17FactoryDiscovery.
14 14
  */
15
-final class UriFactoryDiscovery extends ClassDiscovery
16
-{
15
+final class UriFactoryDiscovery extends ClassDiscovery {
17 16
     /**
18 17
      * Finds a URI Factory.
19 18
      *
Please login to merge, or discard this patch.
lib/Vendor/Http/Discovery/HttpAsyncClientDiscovery.php 2 patches
Indentation   +16 added lines, -16 removed lines patch added patch discarded remove patch
@@ -12,21 +12,21 @@
 block discarded – undo
12 12
  */
13 13
 final class HttpAsyncClientDiscovery extends ClassDiscovery
14 14
 {
15
-    /**
16
-     * Finds an HTTP Async Client.
17
-     *
18
-     * @return HttpAsyncClient
19
-     *
20
-     * @throws Exception\NotFoundException
21
-     */
22
-    public static function find()
23
-    {
24
-        try {
25
-            $asyncClient = static::findOneByType(HttpAsyncClient::class);
26
-        } catch (DiscoveryFailedException $e) {
27
-            throw new NotFoundException('No HTTPlug async clients found. Make sure to install a package providing "php-http/async-client-implementation". Example: "php-http/guzzle6-adapter".', 0, $e);
28
-        }
15
+	/**
16
+	 * Finds an HTTP Async Client.
17
+	 *
18
+	 * @return HttpAsyncClient
19
+	 *
20
+	 * @throws Exception\NotFoundException
21
+	 */
22
+	public static function find()
23
+	{
24
+		try {
25
+			$asyncClient = static::findOneByType(HttpAsyncClient::class);
26
+		} catch (DiscoveryFailedException $e) {
27
+			throw new NotFoundException('No HTTPlug async clients found. Make sure to install a package providing "php-http/async-client-implementation". Example: "php-http/guzzle6-adapter".', 0, $e);
28
+		}
29 29
 
30
-        return static::instantiateClass($asyncClient);
31
-    }
30
+		return static::instantiateClass($asyncClient);
31
+	}
32 32
 }
Please login to merge, or discard this patch.
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -10,8 +10,7 @@
 block discarded – undo
10 10
  *
11 11
  * @author Joel Wurtz <[email protected]>
12 12
  */
13
-final class HttpAsyncClientDiscovery extends ClassDiscovery
14
-{
13
+final class HttpAsyncClientDiscovery extends ClassDiscovery {
15 14
     /**
16 15
      * Finds an HTTP Async Client.
17 16
      *
Please login to merge, or discard this patch.
lib/Vendor/Http/Discovery/Composer/Plugin.php 2 patches
Indentation   +408 added lines, -408 removed lines patch added patch discarded remove patch
@@ -38,370 +38,370 @@  discard block
 block discarded – undo
38 38
  */
39 39
 class Plugin implements PluginInterface, EventSubscriberInterface
40 40
 {
41
-    /**
42
-     * Describes, for every supported virtual implementation, which packages
43
-     * provide said implementation and which extra dependencies each package
44
-     * requires to provide the implementation.
45
-     */
46
-    private const PROVIDE_RULES = [
47
-        'php-http/async-client-implementation' => [
48
-            'symfony/http-client:>=6.3' => ['guzzlehttp/promises', 'psr/http-factory-implementation', 'php-http/httplug'],
49
-            'symfony/http-client' => ['guzzlehttp/promises', 'php-http/message-factory', 'psr/http-factory-implementation', 'php-http/httplug'],
50
-            'php-http/guzzle7-adapter' => [],
51
-            'php-http/guzzle6-adapter' => [],
52
-            'php-http/curl-client' => [],
53
-            'php-http/react-adapter' => [],
54
-        ],
55
-        'php-http/client-implementation' => [
56
-            'symfony/http-client:>=6.3' => ['psr/http-factory-implementation', 'php-http/httplug'],
57
-            'symfony/http-client' => ['php-http/message-factory', 'psr/http-factory-implementation', 'php-http/httplug'],
58
-            'php-http/guzzle7-adapter' => [],
59
-            'php-http/guzzle6-adapter' => [],
60
-            'php-http/cakephp-adapter' => [],
61
-            'php-http/curl-client' => [],
62
-            'php-http/react-adapter' => [],
63
-            'php-http/buzz-adapter' => [],
64
-            'php-http/artax-adapter' => [],
65
-            'kriswallsmith/buzz:^1' => [],
66
-        ],
67
-        'psr/http-client-implementation' => [
68
-            'symfony/http-client' => ['psr/http-factory-implementation', 'psr/http-client'],
69
-            'guzzlehttp/guzzle' => [],
70
-            'kriswallsmith/buzz:^1' => [],
71
-        ],
72
-        'psr/http-message-implementation' => [
73
-            'php-http/discovery' => ['psr/http-factory-implementation'],
74
-        ],
75
-        'psr/http-factory-implementation' => [
76
-            'nyholm/psr7' => [],
77
-            'guzzlehttp/psr7:>=2' => [],
78
-            'slim/psr7' => [],
79
-            'laminas/laminas-diactoros' => [],
80
-            'phalcon/cphalcon:^4' => [],
81
-            'http-interop/http-factory-guzzle' => [],
82
-            'http-interop/http-factory-diactoros' => [],
83
-            'http-interop/http-factory-slim' => [],
84
-            'httpsoft/http-message' => [],
85
-        ],
86
-    ];
87
-
88
-    /**
89
-     * Describes which package should be preferred on the left side
90
-     * depending on which one is already installed on the right side.
91
-     */
92
-    private const STICKYNESS_RULES = [
93
-        'symfony/http-client' => 'symfony/framework-bundle',
94
-        'php-http/guzzle7-adapter' => 'guzzlehttp/guzzle:^7',
95
-        'php-http/guzzle6-adapter' => 'guzzlehttp/guzzle:^6',
96
-        'php-http/guzzle5-adapter' => 'guzzlehttp/guzzle:^5',
97
-        'php-http/cakephp-adapter' => 'cakephp/cakephp',
98
-        'php-http/react-adapter' => 'react/event-loop',
99
-        'php-http/buzz-adapter' => 'kriswallsmith/buzz:^0.15.1',
100
-        'php-http/artax-adapter' => 'amphp/artax:^3',
101
-        'http-interop/http-factory-guzzle' => 'guzzlehttp/psr7:^1',
102
-        'http-interop/http-factory-slim' => 'slim/slim:^3',
103
-    ];
104
-
105
-    private const INTERFACE_MAP = [
106
-        'php-http/async-client-implementation' => [
107
-            'Http\Client\HttpAsyncClient',
108
-        ],
109
-        'php-http/client-implementation' => [
110
-            'Http\Client\HttpClient',
111
-        ],
112
-        'psr/http-client-implementation' => [
113
-            'Psr\Http\Client\ClientInterface',
114
-        ],
115
-        'psr/http-factory-implementation' => [
116
-            'Psr\Http\Message\RequestFactoryInterface',
117
-            'Psr\Http\Message\ResponseFactoryInterface',
118
-            'Psr\Http\Message\ServerRequestFactoryInterface',
119
-            'Psr\Http\Message\StreamFactoryInterface',
120
-            'Psr\Http\Message\UploadedFileFactoryInterface',
121
-            'Psr\Http\Message\UriFactoryInterface',
122
-        ],
123
-    ];
124
-
125
-    public static function getSubscribedEvents(): array
126
-    {
127
-        return [
128
-            ScriptEvents::PRE_AUTOLOAD_DUMP => 'preAutoloadDump',
129
-            ScriptEvents::POST_UPDATE_CMD => 'postUpdate',
130
-        ];
131
-    }
132
-
133
-    public function activate(Composer $composer, IOInterface $io): void
134
-    {
135
-    }
136
-
137
-    public function deactivate(Composer $composer, IOInterface $io)
138
-    {
139
-    }
140
-
141
-    public function uninstall(Composer $composer, IOInterface $io)
142
-    {
143
-    }
144
-
145
-    public function postUpdate(Event $event)
146
-    {
147
-        $composer = $event->getComposer();
148
-        $repo = $composer->getRepositoryManager()->getLocalRepository();
149
-        $requires = [
150
-            $composer->getPackage()->getRequires(),
151
-            $composer->getPackage()->getDevRequires(),
152
-        ];
153
-        $pinnedAbstractions = [];
154
-        $pinned = $composer->getPackage()->getExtra()['discovery'] ?? [];
155
-        foreach (self::INTERFACE_MAP as $abstraction => $interfaces) {
156
-            foreach (isset($pinned[$abstraction]) ? [] : $interfaces as $interface) {
157
-                if (!isset($pinned[$interface])) {
158
-                    continue 2;
159
-                }
160
-            }
161
-            $pinnedAbstractions[$abstraction] = true;
162
-        }
163
-
164
-        $missingRequires = $this->getMissingRequires($repo, $requires, 'project' === $composer->getPackage()->getType(), $pinnedAbstractions);
165
-        $missingRequires = [
166
-            'require' => array_fill_keys(array_merge([], ...array_values($missingRequires[0])), '*'),
167
-            'require-dev' => array_fill_keys(array_merge([], ...array_values($missingRequires[1])), '*'),
168
-            'remove' => array_fill_keys(array_merge([], ...array_values($missingRequires[2])), '*'),
169
-        ];
170
-
171
-        if (!$missingRequires = array_filter($missingRequires)) {
172
-            return;
173
-        }
174
-
175
-        $composerJsonContents = file_get_contents(Factory::getComposerFile());
176
-        $this->updateComposerJson($missingRequires, $composer->getConfig()->get('sort-packages'));
177
-
178
-        $installer = null;
179
-        // Find the composer installer, hack borrowed from symfony/flex
180
-        foreach (debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT) as $trace) {
181
-            if (isset($trace['object']) && $trace['object'] instanceof Installer) {
182
-                $installer = $trace['object'];
183
-                break;
184
-            }
185
-        }
186
-
187
-        if (!$installer) {
188
-            return;
189
-        }
190
-
191
-        $event->stopPropagation();
192
-
193
-        $dispatcher = $composer->getEventDispatcher();
194
-        $disableScripts = !method_exists($dispatcher, 'setRunScripts') || !((array) $dispatcher)["\0*\0runScripts"];
195
-        $composer = Factory::create($event->getIO(), null, false, $disableScripts);
196
-
197
-        /** @var Installer $installer */
198
-        $installer = clone $installer;
199
-        if (method_exists($installer, 'setAudit')) {
200
-            $trace['object']->setAudit(false);
201
-        }
202
-        // we need a clone of the installer to preserve its configuration state but with our own service objects
203
-        $installer->__construct(
204
-            $event->getIO(),
205
-            $composer->getConfig(),
206
-            $composer->getPackage(),
207
-            $composer->getDownloadManager(),
208
-            $composer->getRepositoryManager(),
209
-            $composer->getLocker(),
210
-            $composer->getInstallationManager(),
211
-            $composer->getEventDispatcher(),
212
-            $composer->getAutoloadGenerator()
213
-        );
214
-        if (method_exists($installer, 'setPlatformRequirementFilter')) {
215
-            $installer->setPlatformRequirementFilter(((array) $trace['object'])["\0*\0platformRequirementFilter"]);
216
-        }
217
-
218
-        if (0 !== $installer->run()) {
219
-            file_put_contents(Factory::getComposerFile(), $composerJsonContents);
220
-
221
-            return;
222
-        }
223
-
224
-        $versionSelector = new VersionSelector(ClassDiscovery::safeClassExists(RepositorySet::class) ? new RepositorySet() : new Pool());
225
-        $updateComposerJson = false;
226
-
227
-        foreach ($composer->getRepositoryManager()->getLocalRepository()->getPackages() as $package) {
228
-            foreach (['require', 'require-dev'] as $key) {
229
-                if (!isset($missingRequires[$key][$package->getName()])) {
230
-                    continue;
231
-                }
232
-                $updateComposerJson = true;
233
-                $missingRequires[$key][$package->getName()] = $versionSelector->findRecommendedRequireVersion($package);
234
-            }
235
-        }
236
-
237
-        if ($updateComposerJson) {
238
-            $this->updateComposerJson($missingRequires, $composer->getConfig()->get('sort-packages'));
239
-            $this->updateComposerLock($composer, $event->getIO());
240
-        }
241
-    }
242
-
243
-    public function getMissingRequires(InstalledRepositoryInterface $repo, array $requires, bool $isProject, array $pinnedAbstractions): array
244
-    {
245
-        $allPackages = [];
246
-        $devPackages = method_exists($repo, 'getDevPackageNames') ? array_fill_keys($repo->getDevPackageNames(), true) : [];
247
-
248
-        // One must require "php-http/discovery"
249
-        // to opt-in for auto-installation of virtual package implementations
250
-        if (!isset($requires[0]['php-http/discovery'])) {
251
-            $requires = [[], []];
252
-        }
253
-
254
-        foreach ($repo->getPackages() as $package) {
255
-            $allPackages[$package->getName()] = true;
256
-
257
-            if (1 < \count($names = $package->getNames(false))) {
258
-                $allPackages += array_fill_keys($names, false);
259
-
260
-                if (isset($devPackages[$package->getName()])) {
261
-                    $devPackages += $names;
262
-                }
263
-            }
264
-
265
-            if (isset($package->getRequires()['php-http/discovery'])) {
266
-                $requires[(int) isset($devPackages[$package->getName()])] += $package->getRequires();
267
-            }
268
-        }
269
-
270
-        $missingRequires = [[], [], []];
271
-        $versionParser = new VersionParser();
272
-
273
-        if (ClassDiscovery::safeClassExists(\Phalcon\Http\Message\RequestFactory::class, false)) {
274
-            $missingRequires[0]['psr/http-factory-implementation'] = [];
275
-            $missingRequires[1]['psr/http-factory-implementation'] = [];
276
-        }
277
-
278
-        foreach ($requires as $dev => $rules) {
279
-            $abstractions = [];
280
-            $rules = array_intersect_key(self::PROVIDE_RULES, $rules);
281
-
282
-            while ($rules) {
283
-                $abstraction = key($rules);
284
-
285
-                if (isset($pinnedAbstractions[$abstraction])) {
286
-                    unset($rules[$abstraction]);
287
-                    continue;
288
-                }
289
-
290
-                $abstractions[] = $abstraction;
291
-
292
-                foreach (array_shift($rules) as $candidate => $deps) {
293
-                    [$candidate, $version] = explode(':', $candidate, 2) + [1 => null];
294
-
295
-                    if (!isset($allPackages[$candidate])) {
296
-                        continue;
297
-                    }
298
-                    if (null !== $version && !$repo->findPackage($candidate, $versionParser->parseConstraints($version))) {
299
-                        continue;
300
-                    }
301
-                    if ($isProject && !$dev && isset($devPackages[$candidate])) {
302
-                        $missingRequires[0][$abstraction] = [$candidate];
303
-                        $missingRequires[2][$abstraction] = [$candidate];
304
-                    } else {
305
-                        $missingRequires[$dev][$abstraction] = [];
306
-                    }
307
-
308
-                    foreach ($deps as $dep) {
309
-                        if (isset(self::PROVIDE_RULES[$dep])) {
310
-                            $rules[$dep] = self::PROVIDE_RULES[$dep];
311
-                        } elseif (!isset($allPackages[$dep])) {
312
-                            $missingRequires[$dev][$abstraction][] = $dep;
313
-                        } elseif ($isProject && !$dev && isset($devPackages[$dep])) {
314
-                            $missingRequires[0][$abstraction][] = $dep;
315
-                            $missingRequires[2][$abstraction][] = $dep;
316
-                        }
317
-                    }
318
-                    break;
319
-                }
320
-            }
321
-
322
-            while ($abstractions) {
323
-                $abstraction = array_shift($abstractions);
324
-
325
-                if (isset($missingRequires[$dev][$abstraction])) {
326
-                    continue;
327
-                }
328
-                $candidates = self::PROVIDE_RULES[$abstraction];
329
-
330
-                foreach ($candidates as $candidate => $deps) {
331
-                    [$candidate, $version] = explode(':', $candidate, 2) + [1 => null];
332
-
333
-                    if (null !== $version && !$repo->findPackage($candidate, $versionParser->parseConstraints($version))) {
334
-                        continue;
335
-                    }
336
-                    if (isset($allPackages[$candidate]) && (!$isProject || $dev || !isset($devPackages[$candidate]))) {
337
-                        continue 2;
338
-                    }
339
-                }
340
-
341
-                foreach (array_intersect_key(self::STICKYNESS_RULES, $candidates) as $candidate => $stickyRule) {
342
-                    [$stickyName, $stickyVersion] = explode(':', $stickyRule, 2) + [1 => null];
343
-                    if (!isset($allPackages[$stickyName]) || ($isProject && !$dev && isset($devPackages[$stickyName]))) {
344
-                        continue;
345
-                    }
346
-                    if (null !== $stickyVersion && !$repo->findPackage($stickyName, $versionParser->parseConstraints($stickyVersion))) {
347
-                        continue;
348
-                    }
349
-
350
-                    $candidates = [$candidate => $candidates[$candidate]];
351
-                    break;
352
-                }
353
-
354
-                $dep = key($candidates);
355
-                [$dep] = explode(':', $dep, 2);
356
-                $missingRequires[$dev][$abstraction] = [$dep];
357
-
358
-                if ($isProject && !$dev && isset($devPackages[$dep])) {
359
-                    $missingRequires[2][$abstraction][] = $dep;
360
-                }
361
-            }
362
-        }
363
-
364
-        $missingRequires[1] = array_diff_key($missingRequires[1], $missingRequires[0]);
365
-
366
-        return $missingRequires;
367
-    }
368
-
369
-    public function preAutoloadDump(Event $event)
370
-    {
371
-        $filesystem = new Filesystem();
372
-        // Double realpath() on purpose, see https://bugs.php.net/72738
373
-        $vendorDir = $filesystem->normalizePath(realpath(realpath($event->getComposer()->getConfig()->get('vendor-dir'))));
374
-        $filesystem->ensureDirectoryExists($vendorDir.'/composer');
375
-        $pinned = $event->getComposer()->getPackage()->getExtra()['discovery'] ?? [];
376
-        $candidates = [];
377
-
378
-        $allInterfaces = array_merge(...array_values(self::INTERFACE_MAP));
379
-        foreach ($pinned as $abstraction => $class) {
380
-            if (isset(self::INTERFACE_MAP[$abstraction])) {
381
-                $interfaces = self::INTERFACE_MAP[$abstraction];
382
-            } elseif (false !== $k = array_search($abstraction, $allInterfaces, true)) {
383
-                $interfaces = [$allInterfaces[$k]];
384
-            } else {
385
-                throw new \UnexpectedValueException(sprintf('Invalid "extra.discovery" pinned in composer.json: "%s" is not one of ["%s"].', $abstraction, implode('", "', array_keys(self::INTERFACE_MAP))));
386
-            }
387
-
388
-            foreach ($interfaces as $interface) {
389
-                $candidates[] = sprintf("case %s: return [['class' => %s]];\n", var_export($interface, true), var_export($class, true));
390
-            }
391
-        }
392
-
393
-        $file = $vendorDir.'/composer/GeneratedDiscoveryStrategy.php';
394
-
395
-        if (!$candidates) {
396
-            if (file_exists($file)) {
397
-                unlink($file);
398
-            }
399
-
400
-            return;
401
-        }
402
-
403
-        $candidates = implode('            ', $candidates);
404
-        $code = <<<EOPHP
41
+	/**
42
+	 * Describes, for every supported virtual implementation, which packages
43
+	 * provide said implementation and which extra dependencies each package
44
+	 * requires to provide the implementation.
45
+	 */
46
+	private const PROVIDE_RULES = [
47
+		'php-http/async-client-implementation' => [
48
+			'symfony/http-client:>=6.3' => ['guzzlehttp/promises', 'psr/http-factory-implementation', 'php-http/httplug'],
49
+			'symfony/http-client' => ['guzzlehttp/promises', 'php-http/message-factory', 'psr/http-factory-implementation', 'php-http/httplug'],
50
+			'php-http/guzzle7-adapter' => [],
51
+			'php-http/guzzle6-adapter' => [],
52
+			'php-http/curl-client' => [],
53
+			'php-http/react-adapter' => [],
54
+		],
55
+		'php-http/client-implementation' => [
56
+			'symfony/http-client:>=6.3' => ['psr/http-factory-implementation', 'php-http/httplug'],
57
+			'symfony/http-client' => ['php-http/message-factory', 'psr/http-factory-implementation', 'php-http/httplug'],
58
+			'php-http/guzzle7-adapter' => [],
59
+			'php-http/guzzle6-adapter' => [],
60
+			'php-http/cakephp-adapter' => [],
61
+			'php-http/curl-client' => [],
62
+			'php-http/react-adapter' => [],
63
+			'php-http/buzz-adapter' => [],
64
+			'php-http/artax-adapter' => [],
65
+			'kriswallsmith/buzz:^1' => [],
66
+		],
67
+		'psr/http-client-implementation' => [
68
+			'symfony/http-client' => ['psr/http-factory-implementation', 'psr/http-client'],
69
+			'guzzlehttp/guzzle' => [],
70
+			'kriswallsmith/buzz:^1' => [],
71
+		],
72
+		'psr/http-message-implementation' => [
73
+			'php-http/discovery' => ['psr/http-factory-implementation'],
74
+		],
75
+		'psr/http-factory-implementation' => [
76
+			'nyholm/psr7' => [],
77
+			'guzzlehttp/psr7:>=2' => [],
78
+			'slim/psr7' => [],
79
+			'laminas/laminas-diactoros' => [],
80
+			'phalcon/cphalcon:^4' => [],
81
+			'http-interop/http-factory-guzzle' => [],
82
+			'http-interop/http-factory-diactoros' => [],
83
+			'http-interop/http-factory-slim' => [],
84
+			'httpsoft/http-message' => [],
85
+		],
86
+	];
87
+
88
+	/**
89
+	 * Describes which package should be preferred on the left side
90
+	 * depending on which one is already installed on the right side.
91
+	 */
92
+	private const STICKYNESS_RULES = [
93
+		'symfony/http-client' => 'symfony/framework-bundle',
94
+		'php-http/guzzle7-adapter' => 'guzzlehttp/guzzle:^7',
95
+		'php-http/guzzle6-adapter' => 'guzzlehttp/guzzle:^6',
96
+		'php-http/guzzle5-adapter' => 'guzzlehttp/guzzle:^5',
97
+		'php-http/cakephp-adapter' => 'cakephp/cakephp',
98
+		'php-http/react-adapter' => 'react/event-loop',
99
+		'php-http/buzz-adapter' => 'kriswallsmith/buzz:^0.15.1',
100
+		'php-http/artax-adapter' => 'amphp/artax:^3',
101
+		'http-interop/http-factory-guzzle' => 'guzzlehttp/psr7:^1',
102
+		'http-interop/http-factory-slim' => 'slim/slim:^3',
103
+	];
104
+
105
+	private const INTERFACE_MAP = [
106
+		'php-http/async-client-implementation' => [
107
+			'Http\Client\HttpAsyncClient',
108
+		],
109
+		'php-http/client-implementation' => [
110
+			'Http\Client\HttpClient',
111
+		],
112
+		'psr/http-client-implementation' => [
113
+			'Psr\Http\Client\ClientInterface',
114
+		],
115
+		'psr/http-factory-implementation' => [
116
+			'Psr\Http\Message\RequestFactoryInterface',
117
+			'Psr\Http\Message\ResponseFactoryInterface',
118
+			'Psr\Http\Message\ServerRequestFactoryInterface',
119
+			'Psr\Http\Message\StreamFactoryInterface',
120
+			'Psr\Http\Message\UploadedFileFactoryInterface',
121
+			'Psr\Http\Message\UriFactoryInterface',
122
+		],
123
+	];
124
+
125
+	public static function getSubscribedEvents(): array
126
+	{
127
+		return [
128
+			ScriptEvents::PRE_AUTOLOAD_DUMP => 'preAutoloadDump',
129
+			ScriptEvents::POST_UPDATE_CMD => 'postUpdate',
130
+		];
131
+	}
132
+
133
+	public function activate(Composer $composer, IOInterface $io): void
134
+	{
135
+	}
136
+
137
+	public function deactivate(Composer $composer, IOInterface $io)
138
+	{
139
+	}
140
+
141
+	public function uninstall(Composer $composer, IOInterface $io)
142
+	{
143
+	}
144
+
145
+	public function postUpdate(Event $event)
146
+	{
147
+		$composer = $event->getComposer();
148
+		$repo = $composer->getRepositoryManager()->getLocalRepository();
149
+		$requires = [
150
+			$composer->getPackage()->getRequires(),
151
+			$composer->getPackage()->getDevRequires(),
152
+		];
153
+		$pinnedAbstractions = [];
154
+		$pinned = $composer->getPackage()->getExtra()['discovery'] ?? [];
155
+		foreach (self::INTERFACE_MAP as $abstraction => $interfaces) {
156
+			foreach (isset($pinned[$abstraction]) ? [] : $interfaces as $interface) {
157
+				if (!isset($pinned[$interface])) {
158
+					continue 2;
159
+				}
160
+			}
161
+			$pinnedAbstractions[$abstraction] = true;
162
+		}
163
+
164
+		$missingRequires = $this->getMissingRequires($repo, $requires, 'project' === $composer->getPackage()->getType(), $pinnedAbstractions);
165
+		$missingRequires = [
166
+			'require' => array_fill_keys(array_merge([], ...array_values($missingRequires[0])), '*'),
167
+			'require-dev' => array_fill_keys(array_merge([], ...array_values($missingRequires[1])), '*'),
168
+			'remove' => array_fill_keys(array_merge([], ...array_values($missingRequires[2])), '*'),
169
+		];
170
+
171
+		if (!$missingRequires = array_filter($missingRequires)) {
172
+			return;
173
+		}
174
+
175
+		$composerJsonContents = file_get_contents(Factory::getComposerFile());
176
+		$this->updateComposerJson($missingRequires, $composer->getConfig()->get('sort-packages'));
177
+
178
+		$installer = null;
179
+		// Find the composer installer, hack borrowed from symfony/flex
180
+		foreach (debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT) as $trace) {
181
+			if (isset($trace['object']) && $trace['object'] instanceof Installer) {
182
+				$installer = $trace['object'];
183
+				break;
184
+			}
185
+		}
186
+
187
+		if (!$installer) {
188
+			return;
189
+		}
190
+
191
+		$event->stopPropagation();
192
+
193
+		$dispatcher = $composer->getEventDispatcher();
194
+		$disableScripts = !method_exists($dispatcher, 'setRunScripts') || !((array) $dispatcher)["\0*\0runScripts"];
195
+		$composer = Factory::create($event->getIO(), null, false, $disableScripts);
196
+
197
+		/** @var Installer $installer */
198
+		$installer = clone $installer;
199
+		if (method_exists($installer, 'setAudit')) {
200
+			$trace['object']->setAudit(false);
201
+		}
202
+		// we need a clone of the installer to preserve its configuration state but with our own service objects
203
+		$installer->__construct(
204
+			$event->getIO(),
205
+			$composer->getConfig(),
206
+			$composer->getPackage(),
207
+			$composer->getDownloadManager(),
208
+			$composer->getRepositoryManager(),
209
+			$composer->getLocker(),
210
+			$composer->getInstallationManager(),
211
+			$composer->getEventDispatcher(),
212
+			$composer->getAutoloadGenerator()
213
+		);
214
+		if (method_exists($installer, 'setPlatformRequirementFilter')) {
215
+			$installer->setPlatformRequirementFilter(((array) $trace['object'])["\0*\0platformRequirementFilter"]);
216
+		}
217
+
218
+		if (0 !== $installer->run()) {
219
+			file_put_contents(Factory::getComposerFile(), $composerJsonContents);
220
+
221
+			return;
222
+		}
223
+
224
+		$versionSelector = new VersionSelector(ClassDiscovery::safeClassExists(RepositorySet::class) ? new RepositorySet() : new Pool());
225
+		$updateComposerJson = false;
226
+
227
+		foreach ($composer->getRepositoryManager()->getLocalRepository()->getPackages() as $package) {
228
+			foreach (['require', 'require-dev'] as $key) {
229
+				if (!isset($missingRequires[$key][$package->getName()])) {
230
+					continue;
231
+				}
232
+				$updateComposerJson = true;
233
+				$missingRequires[$key][$package->getName()] = $versionSelector->findRecommendedRequireVersion($package);
234
+			}
235
+		}
236
+
237
+		if ($updateComposerJson) {
238
+			$this->updateComposerJson($missingRequires, $composer->getConfig()->get('sort-packages'));
239
+			$this->updateComposerLock($composer, $event->getIO());
240
+		}
241
+	}
242
+
243
+	public function getMissingRequires(InstalledRepositoryInterface $repo, array $requires, bool $isProject, array $pinnedAbstractions): array
244
+	{
245
+		$allPackages = [];
246
+		$devPackages = method_exists($repo, 'getDevPackageNames') ? array_fill_keys($repo->getDevPackageNames(), true) : [];
247
+
248
+		// One must require "php-http/discovery"
249
+		// to opt-in for auto-installation of virtual package implementations
250
+		if (!isset($requires[0]['php-http/discovery'])) {
251
+			$requires = [[], []];
252
+		}
253
+
254
+		foreach ($repo->getPackages() as $package) {
255
+			$allPackages[$package->getName()] = true;
256
+
257
+			if (1 < \count($names = $package->getNames(false))) {
258
+				$allPackages += array_fill_keys($names, false);
259
+
260
+				if (isset($devPackages[$package->getName()])) {
261
+					$devPackages += $names;
262
+				}
263
+			}
264
+
265
+			if (isset($package->getRequires()['php-http/discovery'])) {
266
+				$requires[(int) isset($devPackages[$package->getName()])] += $package->getRequires();
267
+			}
268
+		}
269
+
270
+		$missingRequires = [[], [], []];
271
+		$versionParser = new VersionParser();
272
+
273
+		if (ClassDiscovery::safeClassExists(\Phalcon\Http\Message\RequestFactory::class, false)) {
274
+			$missingRequires[0]['psr/http-factory-implementation'] = [];
275
+			$missingRequires[1]['psr/http-factory-implementation'] = [];
276
+		}
277
+
278
+		foreach ($requires as $dev => $rules) {
279
+			$abstractions = [];
280
+			$rules = array_intersect_key(self::PROVIDE_RULES, $rules);
281
+
282
+			while ($rules) {
283
+				$abstraction = key($rules);
284
+
285
+				if (isset($pinnedAbstractions[$abstraction])) {
286
+					unset($rules[$abstraction]);
287
+					continue;
288
+				}
289
+
290
+				$abstractions[] = $abstraction;
291
+
292
+				foreach (array_shift($rules) as $candidate => $deps) {
293
+					[$candidate, $version] = explode(':', $candidate, 2) + [1 => null];
294
+
295
+					if (!isset($allPackages[$candidate])) {
296
+						continue;
297
+					}
298
+					if (null !== $version && !$repo->findPackage($candidate, $versionParser->parseConstraints($version))) {
299
+						continue;
300
+					}
301
+					if ($isProject && !$dev && isset($devPackages[$candidate])) {
302
+						$missingRequires[0][$abstraction] = [$candidate];
303
+						$missingRequires[2][$abstraction] = [$candidate];
304
+					} else {
305
+						$missingRequires[$dev][$abstraction] = [];
306
+					}
307
+
308
+					foreach ($deps as $dep) {
309
+						if (isset(self::PROVIDE_RULES[$dep])) {
310
+							$rules[$dep] = self::PROVIDE_RULES[$dep];
311
+						} elseif (!isset($allPackages[$dep])) {
312
+							$missingRequires[$dev][$abstraction][] = $dep;
313
+						} elseif ($isProject && !$dev && isset($devPackages[$dep])) {
314
+							$missingRequires[0][$abstraction][] = $dep;
315
+							$missingRequires[2][$abstraction][] = $dep;
316
+						}
317
+					}
318
+					break;
319
+				}
320
+			}
321
+
322
+			while ($abstractions) {
323
+				$abstraction = array_shift($abstractions);
324
+
325
+				if (isset($missingRequires[$dev][$abstraction])) {
326
+					continue;
327
+				}
328
+				$candidates = self::PROVIDE_RULES[$abstraction];
329
+
330
+				foreach ($candidates as $candidate => $deps) {
331
+					[$candidate, $version] = explode(':', $candidate, 2) + [1 => null];
332
+
333
+					if (null !== $version && !$repo->findPackage($candidate, $versionParser->parseConstraints($version))) {
334
+						continue;
335
+					}
336
+					if (isset($allPackages[$candidate]) && (!$isProject || $dev || !isset($devPackages[$candidate]))) {
337
+						continue 2;
338
+					}
339
+				}
340
+
341
+				foreach (array_intersect_key(self::STICKYNESS_RULES, $candidates) as $candidate => $stickyRule) {
342
+					[$stickyName, $stickyVersion] = explode(':', $stickyRule, 2) + [1 => null];
343
+					if (!isset($allPackages[$stickyName]) || ($isProject && !$dev && isset($devPackages[$stickyName]))) {
344
+						continue;
345
+					}
346
+					if (null !== $stickyVersion && !$repo->findPackage($stickyName, $versionParser->parseConstraints($stickyVersion))) {
347
+						continue;
348
+					}
349
+
350
+					$candidates = [$candidate => $candidates[$candidate]];
351
+					break;
352
+				}
353
+
354
+				$dep = key($candidates);
355
+				[$dep] = explode(':', $dep, 2);
356
+				$missingRequires[$dev][$abstraction] = [$dep];
357
+
358
+				if ($isProject && !$dev && isset($devPackages[$dep])) {
359
+					$missingRequires[2][$abstraction][] = $dep;
360
+				}
361
+			}
362
+		}
363
+
364
+		$missingRequires[1] = array_diff_key($missingRequires[1], $missingRequires[0]);
365
+
366
+		return $missingRequires;
367
+	}
368
+
369
+	public function preAutoloadDump(Event $event)
370
+	{
371
+		$filesystem = new Filesystem();
372
+		// Double realpath() on purpose, see https://bugs.php.net/72738
373
+		$vendorDir = $filesystem->normalizePath(realpath(realpath($event->getComposer()->getConfig()->get('vendor-dir'))));
374
+		$filesystem->ensureDirectoryExists($vendorDir.'/composer');
375
+		$pinned = $event->getComposer()->getPackage()->getExtra()['discovery'] ?? [];
376
+		$candidates = [];
377
+
378
+		$allInterfaces = array_merge(...array_values(self::INTERFACE_MAP));
379
+		foreach ($pinned as $abstraction => $class) {
380
+			if (isset(self::INTERFACE_MAP[$abstraction])) {
381
+				$interfaces = self::INTERFACE_MAP[$abstraction];
382
+			} elseif (false !== $k = array_search($abstraction, $allInterfaces, true)) {
383
+				$interfaces = [$allInterfaces[$k]];
384
+			} else {
385
+				throw new \UnexpectedValueException(sprintf('Invalid "extra.discovery" pinned in composer.json: "%s" is not one of ["%s"].', $abstraction, implode('", "', array_keys(self::INTERFACE_MAP))));
386
+			}
387
+
388
+			foreach ($interfaces as $interface) {
389
+				$candidates[] = sprintf("case %s: return [['class' => %s]];\n", var_export($interface, true), var_export($class, true));
390
+			}
391
+		}
392
+
393
+		$file = $vendorDir.'/composer/GeneratedDiscoveryStrategy.php';
394
+
395
+		if (!$candidates) {
396
+			if (file_exists($file)) {
397
+				unlink($file);
398
+			}
399
+
400
+			return;
401
+		}
402
+
403
+		$candidates = implode('            ', $candidates);
404
+		$code = <<<EOPHP
405 405
 <?php
406 406
 
407 407
 namespace OCA\FullTextSearch_Elasticsearch\Vendor\Http\Discovery\Strategy;
@@ -418,48 +418,48 @@  discard block
 block discarded – undo
418 418
 }
419 419
 
420 420
 EOPHP
421
-        ;
422
-
423
-        if (!file_exists($file) || $code !== file_get_contents($file)) {
424
-            file_put_contents($file, $code);
425
-        }
426
-
427
-        $rootPackage = $event->getComposer()->getPackage();
428
-        $autoload = $rootPackage->getAutoload();
429
-        $autoload['classmap'][] = $vendorDir.'/composer/GeneratedDiscoveryStrategy.php';
430
-        $rootPackage->setAutoload($autoload);
431
-    }
432
-
433
-    private function updateComposerJson(array $missingRequires, bool $sortPackages)
434
-    {
435
-        $file = Factory::getComposerFile();
436
-        $contents = file_get_contents($file);
437
-
438
-        $manipulator = new JsonManipulator($contents);
439
-
440
-        foreach ($missingRequires as $key => $packages) {
441
-            foreach ($packages as $package => $constraint) {
442
-                if ('remove' === $key) {
443
-                    $manipulator->removeSubNode('require-dev', $package);
444
-                } else {
445
-                    $manipulator->addLink($key, $package, $constraint, $sortPackages);
446
-                }
447
-            }
448
-        }
449
-
450
-        file_put_contents($file, $manipulator->getContents());
451
-    }
452
-
453
-    private function updateComposerLock(Composer $composer, IOInterface $io)
454
-    {
455
-        $lock = substr(Factory::getComposerFile(), 0, -4).'lock';
456
-        $composerJson = file_get_contents(Factory::getComposerFile());
457
-        $lockFile = new JsonFile($lock, null, $io);
458
-        $locker = ClassDiscovery::safeClassExists(RepositorySet::class)
459
-            ? new Locker($io, $lockFile, $composer->getInstallationManager(), $composerJson)
460
-            : new Locker($io, $lockFile, $composer->getRepositoryManager(), $composer->getInstallationManager(), $composerJson);
461
-        $lockData = $locker->getLockData();
462
-        $lockData['content-hash'] = Locker::getContentHash($composerJson);
463
-        $lockFile->write($lockData);
464
-    }
421
+		;
422
+
423
+		if (!file_exists($file) || $code !== file_get_contents($file)) {
424
+			file_put_contents($file, $code);
425
+		}
426
+
427
+		$rootPackage = $event->getComposer()->getPackage();
428
+		$autoload = $rootPackage->getAutoload();
429
+		$autoload['classmap'][] = $vendorDir.'/composer/GeneratedDiscoveryStrategy.php';
430
+		$rootPackage->setAutoload($autoload);
431
+	}
432
+
433
+	private function updateComposerJson(array $missingRequires, bool $sortPackages)
434
+	{
435
+		$file = Factory::getComposerFile();
436
+		$contents = file_get_contents($file);
437
+
438
+		$manipulator = new JsonManipulator($contents);
439
+
440
+		foreach ($missingRequires as $key => $packages) {
441
+			foreach ($packages as $package => $constraint) {
442
+				if ('remove' === $key) {
443
+					$manipulator->removeSubNode('require-dev', $package);
444
+				} else {
445
+					$manipulator->addLink($key, $package, $constraint, $sortPackages);
446
+				}
447
+			}
448
+		}
449
+
450
+		file_put_contents($file, $manipulator->getContents());
451
+	}
452
+
453
+	private function updateComposerLock(Composer $composer, IOInterface $io)
454
+	{
455
+		$lock = substr(Factory::getComposerFile(), 0, -4).'lock';
456
+		$composerJson = file_get_contents(Factory::getComposerFile());
457
+		$lockFile = new JsonFile($lock, null, $io);
458
+		$locker = ClassDiscovery::safeClassExists(RepositorySet::class)
459
+			? new Locker($io, $lockFile, $composer->getInstallationManager(), $composerJson)
460
+			: new Locker($io, $lockFile, $composer->getRepositoryManager(), $composer->getInstallationManager(), $composerJson);
461
+		$lockData = $locker->getLockData();
462
+		$lockData['content-hash'] = Locker::getContentHash($composerJson);
463
+		$lockFile->write($lockData);
464
+	}
465 465
 }
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -191,7 +191,7 @@  discard block
 block discarded – undo
191 191
         $event->stopPropagation();
192 192
 
193 193
         $dispatcher = $composer->getEventDispatcher();
194
-        $disableScripts = !method_exists($dispatcher, 'setRunScripts') || !((array) $dispatcher)["\0*\0runScripts"];
194
+        $disableScripts = !method_exists($dispatcher, 'setRunScripts') || !((array)$dispatcher)["\0*\0runScripts"];
195 195
         $composer = Factory::create($event->getIO(), null, false, $disableScripts);
196 196
 
197 197
         /** @var Installer $installer */
@@ -212,7 +212,7 @@  discard block
 block discarded – undo
212 212
             $composer->getAutoloadGenerator()
213 213
         );
214 214
         if (method_exists($installer, 'setPlatformRequirementFilter')) {
215
-            $installer->setPlatformRequirementFilter(((array) $trace['object'])["\0*\0platformRequirementFilter"]);
215
+            $installer->setPlatformRequirementFilter(((array)$trace['object'])["\0*\0platformRequirementFilter"]);
216 216
         }
217 217
 
218 218
         if (0 !== $installer->run()) {
@@ -263,7 +263,7 @@  discard block
 block discarded – undo
263 263
             }
264 264
 
265 265
             if (isset($package->getRequires()['php-http/discovery'])) {
266
-                $requires[(int) isset($devPackages[$package->getName()])] += $package->getRequires();
266
+                $requires[(int)isset($devPackages[$package->getName()])] += $package->getRequires();
267 267
             }
268 268
         }
269 269
 
Please login to merge, or discard this patch.