Skip to content

Commit d53d061

Browse files
Merge pull request #18541 from MauricioFauth/psr7-psr17
Refactor HTTP factories
2 parents 63e1777 + 239447f commit d53d061

15 files changed

Lines changed: 776 additions & 417 deletions

.github/workflows/tests.yml

Lines changed: 0 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -186,69 +186,3 @@ jobs:
186186
with:
187187
project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
188188
coverage-reports: build/logs/clover.xml
189-
190-
test-php-psr7-implementations:
191-
name: Test on PHP ${{ matrix.php-version }} (+ psr7-${{ matrix.psr-7-library }})
192-
runs-on: ubuntu-latest
193-
strategy:
194-
fail-fast: false
195-
matrix:
196-
php-version: ['8.1']
197-
php-extensions: ['mbstring, iconv, mysqli, zip, bz2']
198-
psr-7-library: ['guzzlehttp/psr7', 'nyholm/psr7', 'laminas/laminas-diactoros']
199-
steps:
200-
- name: Checkout code
201-
uses: actions/checkout@v3
202-
with:
203-
# Fetch some commits for Scrutinizer coverage upload
204-
fetch-depth: 15
205-
206-
- name: Install gettext
207-
run: sudo apt-get install -y gettext
208-
209-
- name: Generate mo files
210-
run: ./scripts/generate-mo --quiet
211-
212-
- name: Set up PHP ${{ matrix.php-version }}
213-
uses: shivammathur/setup-php@v2
214-
with:
215-
php-version: ${{ matrix.php-version }}
216-
extensions: ${{ matrix.php-extensions }}
217-
coverage: pcov
218-
219-
- name: Install Composer dependencies
220-
uses: ramsey/composer-install@v2
221-
with:
222-
dependency-versions: highest
223-
224-
- name: Remove default PSR-7 implementation
225-
run: composer remove slim/psr7
226-
227-
- name: Add PSR-7 implementation
228-
run: composer require ${{ matrix.psr-7-library }}
229-
230-
- name: Run PHP tests
231-
run: composer run phpunit -- --testsuite unit
232-
233-
- name: Send coverage
234-
uses: codecov/codecov-action@v3
235-
with:
236-
flags: ${{ matrix.psr-7-library }}-psr-7
237-
name: php-7.2-psr-7
238-
239-
- name: Send coverage to Scrutinizer
240-
uses: sudo-bot/action-scrutinizer@latest
241-
# Do not run this step on forked versions of the main repository (example: contributor forks)
242-
if: github.repository == 'phpmyadmin/phpmyadmin'
243-
with:
244-
cli-args: "--format=php-clover build/logs/clover.xml --revision=${{ github.event.pull_request.head.sha || github.sha }}"
245-
246-
- name: Send coverage to Codacy
247-
uses: codacy/codacy-coverage-reporter-action@v1
248-
# Do not run this step on forked versions of the main repository (example: contributor forks)
249-
if: github.repository == 'phpmyadmin/phpmyadmin'
250-
# Upload can fail on forks or if the secret is missing
251-
continue-on-error: true
252-
with:
253-
project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
254-
coverage-reports: build/logs/clover.xml

composer.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,15 @@
5757
"ext-sodium": "*",
5858
"ext-xml": "*",
5959
"composer/ca-bundle": "^1.2",
60+
"fig/http-message-util": "^1.1",
6061
"google/recaptcha": "^1.3",
6162
"nikic/fast-route": "^1.3",
6263
"phpmyadmin/motranslator": "^5.0",
6364
"phpmyadmin/shapefile": "^3.0.1",
6465
"phpmyadmin/sql-parser": "^6.0.x-dev",
6566
"phpmyadmin/twig-i18n-extension": "^4.0.1",
6667
"psr/http-factory": "^1.0",
67-
"psr/http-message": "^1.0",
68+
"psr/http-message": "^1.1",
6869
"slim/psr7": "^1.6.1",
6970
"symfony/config": "^6.2",
7071
"symfony/dependency-injection": "^6.2",
@@ -97,6 +98,10 @@
9798
"require-dev": {
9899
"bacon/bacon-qr-code": "^2.0",
99100
"code-lts/u2f-php-server": "^1.2",
101+
"guzzlehttp/psr7": "^2.5",
102+
"httpsoft/http-message": "^1.1",
103+
"laminas/laminas-diactoros": "^3.0",
104+
"nyholm/psr7": "^1.8",
100105
"php-webdriver/webdriver": "^1.14",
101106
"phpmyadmin/coding-standard": "^4.0",
102107
"phpstan/extension-installer": "^1.3",

libraries/classes/Application.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,7 @@ private function connectToDatabaseServer(
593593
public static function getRequest(): ServerRequest
594594
{
595595
if (self::$request === null) {
596-
self::$request = ServerRequestFactory::createFromGlobals();
596+
self::$request = ServerRequestFactory::create()->fromGlobals();
597597
}
598598

599599
return self::$request;

libraries/classes/Http/Factory/ResponseFactory.php

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,52 +4,47 @@
44

55
namespace PhpMyAdmin\Http\Factory;
66

7+
use Fig\Http\Message\StatusCodeInterface;
78
use GuzzleHttp\Psr7\HttpFactory;
9+
use HttpSoft\Message\ResponseFactory as HttpSoftResponseFactory;
810
use Laminas\Diactoros\ResponseFactory as LaminasResponseFactory;
911
use Nyholm\Psr7\Factory\Psr17Factory;
1012
use PhpMyAdmin\Http\Response;
1113
use Psr\Http\Message\ResponseFactoryInterface;
14+
use RuntimeException;
1215
use Slim\Psr7\Factory\ResponseFactory as SlimResponseFactory;
1316

1417
use function class_exists;
1518

16-
class ResponseFactory
19+
final class ResponseFactory implements ResponseFactoryInterface
1720
{
18-
private ResponseFactoryInterface $responseFactory;
19-
20-
public function __construct(ResponseFactoryInterface|null $responseFactory = null)
21+
/** @psalm-var list<class-string<ResponseFactoryInterface>> */
22+
private static array $providers = [
23+
SlimResponseFactory::class,
24+
LaminasResponseFactory::class,
25+
Psr17Factory::class,
26+
HttpFactory::class,
27+
HttpSoftResponseFactory::class,
28+
];
29+
30+
public function __construct(private ResponseFactoryInterface $responseFactory)
2131
{
22-
$this->responseFactory = $responseFactory ?? $this->createResponseFactory();
2332
}
2433

25-
/**
26-
* Create a new response.
27-
*
28-
* @param int $code HTTP status code; defaults to 200
29-
* @param string $reasonPhrase Reason phrase to associate with status code
30-
* in generated response; if none is provided implementations MAY use
31-
* the defaults as suggested in the HTTP specification.
32-
*/
33-
public function createResponse(int $code = 200, string $reasonPhrase = ''): Response
34+
public function createResponse(int $code = StatusCodeInterface::STATUS_OK, string $reasonPhrase = ''): Response
3435
{
3536
return new Response($this->responseFactory->createResponse($code, $reasonPhrase));
3637
}
3738

38-
private function createResponseFactory(): ResponseFactoryInterface
39+
/** @throws RuntimeException When no {@see ResponseFactoryInterface} implementation is found. */
40+
public static function create(): self
3941
{
40-
if (class_exists(Psr17Factory::class)) {
41-
/** @var ResponseFactoryInterface $factory */
42-
$factory = new Psr17Factory();
43-
} elseif (class_exists(HttpFactory::class)) {
44-
/** @var ResponseFactoryInterface $factory */
45-
$factory = new HttpFactory();
46-
} elseif (class_exists(LaminasResponseFactory::class)) {
47-
/** @var ResponseFactoryInterface $factory */
48-
$factory = new LaminasResponseFactory();
49-
} else {
50-
$factory = new SlimResponseFactory();
42+
foreach (self::$providers as $provider) {
43+
if (class_exists($provider)) {
44+
return new self(new $provider());
45+
}
5146
}
5247

53-
return $factory;
48+
throw new RuntimeException('No HTTP response factories found.');
5449
}
5550
}

0 commit comments

Comments
 (0)