Skip to content

Commit 7afc1d1

Browse files
Add support for UploadedFileFactoryInterface and UriFactoryInterface (#5)
This PR adds support for two missing factories defined by PSR-17: * [UploadedFileFactoryInterface](https://www.php-fig.org/psr/psr-17/#25-uploadedfilefactoryinterface) * [UriFactoryInterface](https://www.php-fig.org/psr/psr-17/#26-urifactoryinterface) --------- Co-authored-by: Evan Sims <hello@evansims.com>
1 parent 0cbed4d commit 7afc1d1

File tree

5 files changed

+397
-1
lines changed

5 files changed

+397
-1
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"require": {
2020
"php": "^8.0",
2121
"psr/http-factory": "^1.0",
22-
"psr-discovery/discovery": "^1.0"
22+
"psr-discovery/discovery": "^1.1"
2323
},
2424
"require-dev": {
2525
"friendsofphp/php-cs-fixer": "^3.14",
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PsrDiscovery\Contracts\Implementations\Psr17;
6+
7+
use Psr\Http\Message\UploadedFileFactoryInterface;
8+
9+
interface UploadedFileFactoriesContract extends FactoriesContract
10+
{
11+
/**
12+
* Discover and instantiate a matching implementation.
13+
*/
14+
public static function discover(): ?UploadedFileFactoryInterface;
15+
16+
/**
17+
* Return a singleton instance of a matching implementation.
18+
*/
19+
public static function singleton(): ?UploadedFileFactoryInterface;
20+
21+
/**
22+
* Use a specific implementation instance.
23+
*
24+
* @param ?UploadedFileFactoryInterface $instance
25+
*/
26+
public static function use(?UploadedFileFactoryInterface $instance): void;
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PsrDiscovery\Contracts\Implementations\Psr17;
6+
7+
use Psr\Http\Message\UriFactoryInterface;
8+
9+
interface UriFactoriesContract extends FactoriesContract
10+
{
11+
/**
12+
* Discover and instantiate a matching implementation.
13+
*/
14+
public static function discover(): ?UriFactoryInterface;
15+
16+
/**
17+
* Return a singleton instance of a matching implementation.
18+
*/
19+
public static function singleton(): ?UriFactoryInterface;
20+
21+
/**
22+
* Use a specific implementation instance.
23+
*
24+
* @param ?UriFactoryInterface $instance
25+
*/
26+
public static function use(?UriFactoryInterface $instance): void;
27+
}
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PsrDiscovery\Implementations\Psr17;
6+
7+
use Psr\Http\Message\UploadedFileFactoryInterface;
8+
use PsrDiscovery\Collections\CandidatesCollection;
9+
use PsrDiscovery\Contracts\Implementations\Psr17\UploadedFileFactoriesContract;
10+
use PsrDiscovery\Discover;
11+
use PsrDiscovery\Entities\CandidateEntity;
12+
use PsrDiscovery\Implementations\Implementation;
13+
14+
final class UploadedFileFactories extends Implementation implements UploadedFileFactoriesContract
15+
{
16+
private static ?CandidatesCollection $candidates = null;
17+
18+
private static ?CandidatesCollection $extendedCandidates = null;
19+
20+
private static ?UploadedFileFactoryInterface $singleton = null;
21+
22+
private static ?UploadedFileFactoryInterface $using = null;
23+
24+
public static function add(CandidateEntity $candidate): void
25+
{
26+
self::$candidates ??= CandidatesCollection::create();
27+
parent::add($candidate);
28+
self::use(null);
29+
}
30+
31+
/**
32+
* @psalm-suppress MixedInferredReturnType,MixedReturnStatement
33+
*/
34+
public static function allCandidates(): CandidatesCollection
35+
{
36+
if (self::$extendedCandidates instanceof CandidatesCollection) {
37+
return self::$extendedCandidates;
38+
}
39+
40+
self::$extendedCandidates = CandidatesCollection::create();
41+
self::$extendedCandidates->set(self::candidates());
42+
43+
return self::$extendedCandidates;
44+
}
45+
46+
/**
47+
* @psalm-suppress MixedInferredReturnType,MixedReturnStatement
48+
*/
49+
public static function candidates(): CandidatesCollection
50+
{
51+
if (self::$candidates instanceof CandidatesCollection) {
52+
return self::$candidates;
53+
}
54+
55+
self::$candidates = CandidatesCollection::create();
56+
57+
self::$candidates->add(CandidateEntity::create(
58+
package: 'guzzlehttp/psr7',
59+
version: '^2.0',
60+
builder: static fn (string $class = '\GuzzleHttp\Psr7\HttpFactory'): object => new $class(),
61+
));
62+
63+
self::$candidates->add(CandidateEntity::create(
64+
package: 'nyholm/psr7',
65+
version: '^0.2.2',
66+
builder: static fn (string $class = '\Nyholm\Psr7\Factory\UploadedFileFactory'): object => new $class(),
67+
));
68+
69+
self::$candidates->add(CandidateEntity::create(
70+
package: 'nyholm/psr7',
71+
version: '^1.0',
72+
builder: static fn (string $class = '\Nyholm\Psr7\Factory\Psr17Factory'): object => new $class(),
73+
));
74+
75+
self::$candidates->add(CandidateEntity::create(
76+
package: 'http-interop/http-factory-guzzle',
77+
version: '^0.2 | ^1.0',
78+
builder: static fn (string $class = '\Http\Factory\Guzzle\UploadedFileFactory'): object => new $class(),
79+
));
80+
81+
self::$candidates->add(CandidateEntity::create(
82+
package: 'zendframework/zend-diactoros',
83+
version: '^2.0',
84+
builder: static fn (string $class = '\Zend\Diactoros\UploadedFileFactory'): object => new $class(),
85+
));
86+
87+
self::$candidates->add(CandidateEntity::create(
88+
package: 'laminas/laminas-diactoros',
89+
version: '^2.0',
90+
builder: static fn (string $class = '\Laminas\Diactoros\UploadedFileFactory'): object => new $class(),
91+
));
92+
93+
self::$candidates->add(CandidateEntity::create(
94+
package: 'slim/psr7',
95+
version: '^1.0',
96+
builder: static fn (string $class = '\Slim\Psr7\Factory\UploadedFileFactory'): object => new $class(),
97+
));
98+
99+
self::$candidates->add(CandidateEntity::create(
100+
package: 'typo3/core',
101+
version: '^10.1 | ^11.0 | ^12.0',
102+
builder: static fn (string $class = '\TYPO3\CMS\Core\Http\StreamFactory'): object => new $class(),
103+
));
104+
105+
self::$candidates->add(CandidateEntity::create(
106+
package: 'nimbly/capsule',
107+
version: '^2.0',
108+
builder: static fn (string $class = '\Nimbly\Capsule\Factory\UploadedFileFactory'): object => new $class(),
109+
));
110+
111+
self::$candidates->add(CandidateEntity::create(
112+
package: 'tuupola/http-factory',
113+
version: '^1.0.2',
114+
builder: static fn (string $class = '\Tuupola\Http\Factory\UploadedFileFactory'): object => new $class(),
115+
));
116+
117+
self::$candidates->add(CandidateEntity::create(
118+
package: 'httpsoft/http-message',
119+
version: '^1.0.4',
120+
builder: static fn (string $class = '\HttpSoft\Message\UploadedFileFactory'): object => new $class(),
121+
));
122+
123+
return self::$candidates;
124+
}
125+
126+
/**
127+
* @psalm-suppress MoreSpecificReturnType,LessSpecificReturnStatement
128+
*/
129+
public static function discover(): ?UploadedFileFactoryInterface
130+
{
131+
if (self::$using instanceof UploadedFileFactoryInterface) {
132+
return self::$using;
133+
}
134+
135+
return Discover::httpUploadedFileFactory();
136+
}
137+
138+
public static function discoveries(): array
139+
{
140+
return Discover::httpUploadedFileFactories();
141+
}
142+
143+
public static function prefer(string $package): void
144+
{
145+
self::$candidates ??= CandidatesCollection::create();
146+
parent::prefer($package);
147+
self::use(null);
148+
}
149+
150+
public static function set(CandidatesCollection $candidates): void
151+
{
152+
self::$candidates ??= CandidatesCollection::create();
153+
parent::set($candidates);
154+
self::use(null);
155+
}
156+
157+
public static function singleton(): ?UploadedFileFactoryInterface
158+
{
159+
if (self::$using instanceof UploadedFileFactoryInterface) {
160+
return self::$using;
161+
}
162+
163+
return self::$singleton ??= self::discover();
164+
}
165+
166+
public static function use(?UploadedFileFactoryInterface $instance): void
167+
{
168+
self::$singleton = $instance;
169+
self::$using = $instance;
170+
}
171+
}

0 commit comments

Comments
 (0)