Initial Drupal 11 with DDEV setup

This commit is contained in:
gluebox
2025-10-08 11:39:17 -04:00
commit 89ef74b305
25344 changed files with 2599172 additions and 0 deletions

View File

@ -0,0 +1,49 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bridge\PsrHttpMessage\ArgumentValueResolver;
use Psr\Http\Message\MessageInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ServerRequestInterface;
use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Controller\ValueResolverInterface;
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
/**
* Injects the RequestInterface, MessageInterface or ServerRequestInterface when requested.
*
* @author Iltar van der Berg <kjarli@gmail.com>
* @author Alexander M. Turek <me@derrabus.de>
*/
final class PsrServerRequestResolver implements ValueResolverInterface
{
private const SUPPORTED_TYPES = [
ServerRequestInterface::class => true,
RequestInterface::class => true,
MessageInterface::class => true,
];
public function __construct(
private readonly HttpMessageFactoryInterface $httpMessageFactory,
) {
}
public function resolve(Request $request, ArgumentMetadata $argument): \Traversable
{
if (!isset(self::SUPPORTED_TYPES[$argument->getType()])) {
return;
}
yield $this->httpMessageFactory->createRequest($request);
}
}

View File

@ -0,0 +1,109 @@
CHANGELOG
=========
6.4
---
* Import the bridge into the Symfony monorepo and synchronize releases
* Remove `ArgumentValueResolverInterface` from `PsrServerRequestResolver`
* Support `php-http/discovery` for auto-detecting PSR-17 factories
2.3.1
-----
* Don't rely on `Request::getPayload()` to populate the parsed body
2.3.0
-----
* Leverage `Request::getPayload()` to populate the parsed body of PSR-7 requests
* Implement `ValueResolverInterface` introduced with Symfony 6.2
2.2.0
-----
* Drop support for Symfony 4
* Bump minimum version of PHP to 7.2
* Support version 2 of the psr/http-message contracts
2.1.3
-----
* Ignore invalid HTTP headers when creating PSR7 objects
* Fix for wrong type passed to `moveTo()`
2.1.2
-----
* Allow Symfony 6
2.1.0
-----
* Added a `PsrResponseListener` to automatically convert PSR-7 responses returned by controllers
* Added a `PsrServerRequestResolver` that allows injecting PSR-7 request objects into controllers
2.0.2
-----
* Fix populating server params from URI in HttpFoundationFactory
* Create cookies as raw in HttpFoundationFactory
* Fix BinaryFileResponse with Content-Range PsrHttpFactory
2.0.1
-----
* Don't normalize query string in PsrHttpFactory
* Fix conversion for HTTPS requests
* Fix populating default port and headers in HttpFoundationFactory
2.0.0
-----
* Remove DiactorosFactory
1.3.0
-----
* Added support for streamed requests
* Added support for Symfony 5.0+
* Fixed bridging UploadedFile objects
* Bumped minimum version of Symfony to 4.4
1.2.0
-----
* Added new documentation links
* Bumped minimum version of PHP to 7.1
* Added support for streamed responses
1.1.2
-----
* Fixed createResponse
1.1.1
-----
* Deprecated DiactorosFactory, use PsrHttpFactory instead
* Removed triggering of deprecation
1.1.0
-----
* Added support for creating PSR-7 messages using PSR-17 factories
1.0.2
-----
* Fixed request target in PSR7 Request (mtibben)
1.0.1
-----
* Added support for Symfony 4 (dunglas)
1.0.0
-----
* Initial release

View File

@ -0,0 +1,56 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bridge\PsrHttpMessage\EventListener;
use Psr\Http\Message\ResponseInterface;
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;
use Symfony\Bridge\PsrHttpMessage\HttpFoundationFactoryInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\KernelEvents;
/**
* Converts PSR-7 Response to HttpFoundation Response using the bridge.
*
* @author Kévin Dunglas <dunglas@gmail.com>
* @author Alexander M. Turek <me@derrabus.de>
*/
final class PsrResponseListener implements EventSubscriberInterface
{
private readonly HttpFoundationFactoryInterface $httpFoundationFactory;
public function __construct(?HttpFoundationFactoryInterface $httpFoundationFactory = null)
{
$this->httpFoundationFactory = $httpFoundationFactory ?? new HttpFoundationFactory();
}
/**
* Do the conversion if applicable and update the response of the event.
*/
public function onKernelView(ViewEvent $event): void
{
$controllerResult = $event->getControllerResult();
if (!$controllerResult instanceof ResponseInterface) {
return;
}
$event->setResponse($this->httpFoundationFactory->createResponse($controllerResult));
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::VIEW => 'onKernelView',
];
}
}

View File

@ -0,0 +1,156 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bridge\PsrHttpMessage\Factory;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UploadedFileInterface;
use Symfony\Bridge\PsrHttpMessage\HttpFoundationFactoryInterface;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;
/**
* @author Kévin Dunglas <dunglas@gmail.com>
*/
class HttpFoundationFactory implements HttpFoundationFactoryInterface
{
/**
* @param int $responseBufferMaxLength The maximum output buffering size for each iteration when sending the response
*/
public function __construct(
private readonly int $responseBufferMaxLength = 16372,
) {
}
public function createRequest(ServerRequestInterface $psrRequest, bool $streamed = false): Request
{
$server = [];
$uri = $psrRequest->getUri();
$server['SERVER_NAME'] = $uri->getHost();
$server['SERVER_PORT'] = $uri->getPort() ?: ('https' === $uri->getScheme() ? 443 : 80);
$server['REQUEST_URI'] = $uri->getPath();
$server['QUERY_STRING'] = $uri->getQuery();
if ('' !== $server['QUERY_STRING']) {
$server['REQUEST_URI'] .= '?'.$server['QUERY_STRING'];
}
if ('https' === $uri->getScheme()) {
$server['HTTPS'] = 'on';
}
$server['REQUEST_METHOD'] = $psrRequest->getMethod();
$server = array_replace($psrRequest->getServerParams(), $server);
$parsedBody = $psrRequest->getParsedBody();
$parsedBody = \is_array($parsedBody) ? $parsedBody : [];
$request = new Request(
$psrRequest->getQueryParams(),
$parsedBody,
$psrRequest->getAttributes(),
$psrRequest->getCookieParams(),
$this->getFiles($psrRequest->getUploadedFiles()),
$server,
$streamed ? $psrRequest->getBody()->detach() : $psrRequest->getBody()->__toString()
);
$request->headers->add($psrRequest->getHeaders());
return $request;
}
/**
* Converts to the input array to $_FILES structure.
*/
private function getFiles(array $uploadedFiles): array
{
$files = [];
foreach ($uploadedFiles as $key => $value) {
if ($value instanceof UploadedFileInterface) {
$files[$key] = $this->createUploadedFile($value);
} else {
$files[$key] = $this->getFiles($value);
}
}
return $files;
}
/**
* Creates Symfony UploadedFile instance from PSR-7 ones.
*/
private function createUploadedFile(UploadedFileInterface $psrUploadedFile): UploadedFile
{
return new UploadedFile($psrUploadedFile, function () { return $this->getTemporaryPath(); });
}
/**
* Gets a temporary file path.
*/
protected function getTemporaryPath(): string
{
return tempnam(sys_get_temp_dir(), 'symfony');
}
public function createResponse(ResponseInterface $psrResponse, bool $streamed = false): Response
{
$cookies = $psrResponse->getHeader('Set-Cookie');
$psrResponse = $psrResponse->withoutHeader('Set-Cookie');
if ($streamed) {
$response = new StreamedResponse(
$this->createStreamedResponseCallback($psrResponse->getBody()),
$psrResponse->getStatusCode(),
$psrResponse->getHeaders()
);
} else {
$response = new Response(
$psrResponse->getBody()->__toString(),
$psrResponse->getStatusCode(),
$psrResponse->getHeaders()
);
}
$response->setProtocolVersion($psrResponse->getProtocolVersion());
foreach ($cookies as $cookie) {
$response->headers->setCookie(Cookie::fromString($cookie));
}
return $response;
}
private function createStreamedResponseCallback(StreamInterface $body): callable
{
return function () use ($body) {
if ($body->isSeekable()) {
$body->rewind();
}
if (!$body->isReadable()) {
echo $body;
return;
}
while (!$body->eof()) {
echo $body->read($this->responseBufferMaxLength);
}
};
}
}

View File

@ -0,0 +1,201 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bridge\PsrHttpMessage\Factory;
use Http\Discovery\Psr17Factory as DiscoveryPsr17Factory;
use Nyholm\Psr7\Factory\Psr17Factory as NyholmPsr17Factory;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestFactoryInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamFactoryInterface;
use Psr\Http\Message\UploadedFileFactoryInterface;
use Psr\Http\Message\UploadedFileInterface;
use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;
/**
* Builds Psr\HttpMessage instances using a PSR-17 implementation.
*
* @author Antonio J. García Lagar <aj@garcialagar.es>
* @author Aurélien Pillevesse <aurelienpillevesse@hotmail.fr>
*/
class PsrHttpFactory implements HttpMessageFactoryInterface
{
private readonly ServerRequestFactoryInterface $serverRequestFactory;
private readonly StreamFactoryInterface $streamFactory;
private readonly UploadedFileFactoryInterface $uploadedFileFactory;
private readonly ResponseFactoryInterface $responseFactory;
public function __construct(
?ServerRequestFactoryInterface $serverRequestFactory = null,
?StreamFactoryInterface $streamFactory = null,
?UploadedFileFactoryInterface $uploadedFileFactory = null,
?ResponseFactoryInterface $responseFactory = null,
) {
if (null === $serverRequestFactory || null === $streamFactory || null === $uploadedFileFactory || null === $responseFactory) {
$psr17Factory = match (true) {
class_exists(DiscoveryPsr17Factory::class) => new DiscoveryPsr17Factory(),
class_exists(NyholmPsr17Factory::class) => new NyholmPsr17Factory(),
default => throw new \LogicException(\sprintf('You cannot use the "%s" as no PSR-17 factories have been provided. Try running "composer require php-http/discovery psr/http-factory-implementation:*".', self::class)),
};
$serverRequestFactory ??= $psr17Factory;
$streamFactory ??= $psr17Factory;
$uploadedFileFactory ??= $psr17Factory;
$responseFactory ??= $psr17Factory;
}
$this->serverRequestFactory = $serverRequestFactory;
$this->streamFactory = $streamFactory;
$this->uploadedFileFactory = $uploadedFileFactory;
$this->responseFactory = $responseFactory;
}
public function createRequest(Request $symfonyRequest): ServerRequestInterface
{
$uri = $symfonyRequest->server->get('QUERY_STRING', '');
$uri = $symfonyRequest->getSchemeAndHttpHost().$symfonyRequest->getBaseUrl().$symfonyRequest->getPathInfo().('' !== $uri ? '?'.$uri : '');
$request = $this->serverRequestFactory->createServerRequest(
$symfonyRequest->getMethod(),
$uri,
$symfonyRequest->server->all()
);
foreach ($symfonyRequest->headers->all() as $name => $value) {
try {
$request = $request->withHeader($name, $value);
} catch (\InvalidArgumentException $e) {
// ignore invalid header
}
}
$body = $this->streamFactory->createStreamFromResource($symfonyRequest->getContent(true));
$format = $symfonyRequest->getContentTypeFormat();
if ('json' === $format) {
$parsedBody = json_decode($symfonyRequest->getContent(), true, 512, \JSON_BIGINT_AS_STRING);
if (!\is_array($parsedBody)) {
$parsedBody = null;
}
} else {
$parsedBody = $symfonyRequest->request->all();
}
$request = $request
->withBody($body)
->withUploadedFiles($this->getFiles($symfonyRequest->files->all()))
->withCookieParams($symfonyRequest->cookies->all())
->withQueryParams($symfonyRequest->query->all())
->withParsedBody($parsedBody)
;
foreach ($symfonyRequest->attributes->all() as $key => $value) {
$request = $request->withAttribute($key, $value);
}
return $request;
}
/**
* Converts Symfony uploaded files array to the PSR one.
*/
private function getFiles(array $uploadedFiles): array
{
$files = [];
foreach ($uploadedFiles as $key => $value) {
if (null === $value) {
$files[$key] = $this->uploadedFileFactory->createUploadedFile($this->streamFactory->createStream(), 0, \UPLOAD_ERR_NO_FILE);
continue;
}
if ($value instanceof UploadedFile) {
$files[$key] = $this->createUploadedFile($value);
} else {
$files[$key] = $this->getFiles($value);
}
}
return $files;
}
/**
* Creates a PSR-7 UploadedFile instance from a Symfony one.
*/
private function createUploadedFile(UploadedFile $symfonyUploadedFile): UploadedFileInterface
{
return $this->uploadedFileFactory->createUploadedFile(
$this->streamFactory->createStreamFromFile(
$symfonyUploadedFile->getRealPath()
),
(int) $symfonyUploadedFile->getSize(),
$symfonyUploadedFile->getError(),
$symfonyUploadedFile->getClientOriginalName(),
$symfonyUploadedFile->getClientMimeType()
);
}
public function createResponse(Response $symfonyResponse): ResponseInterface
{
$response = $this->responseFactory->createResponse($symfonyResponse->getStatusCode(), Response::$statusTexts[$symfonyResponse->getStatusCode()] ?? '');
if ($symfonyResponse instanceof BinaryFileResponse && !$symfonyResponse->headers->has('Content-Range')) {
$stream = $this->streamFactory->createStreamFromFile(
$symfonyResponse->getFile()->getPathname()
);
} else {
$stream = $this->streamFactory->createStreamFromFile('php://temp', 'wb+');
if ($symfonyResponse instanceof StreamedResponse || $symfonyResponse instanceof BinaryFileResponse) {
ob_start(function ($buffer) use ($stream) {
$stream->write($buffer);
return '';
}, 1);
$symfonyResponse->sendContent();
ob_end_clean();
} else {
$stream->write($symfonyResponse->getContent());
}
}
$response = $response->withBody($stream);
$headers = $symfonyResponse->headers->all();
$cookies = $symfonyResponse->headers->getCookies();
if ($cookies) {
$headers['Set-Cookie'] = [];
foreach ($cookies as $cookie) {
$headers['Set-Cookie'][] = $cookie->__toString();
}
}
foreach ($headers as $name => $value) {
try {
$response = $response->withHeader($name, $value);
} catch (\InvalidArgumentException $e) {
// ignore invalid header
}
}
$protocolVersion = $symfonyResponse->getProtocolVersion();
return $response->withProtocolVersion($protocolVersion);
}
}

View File

@ -0,0 +1,69 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bridge\PsrHttpMessage\Factory;
use Psr\Http\Message\UploadedFileInterface;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile as BaseUploadedFile;
/**
* @author Nicolas Grekas <p@tchwork.com>
*/
class UploadedFile extends BaseUploadedFile
{
private bool $test = false;
public function __construct(
private readonly UploadedFileInterface $psrUploadedFile,
callable $getTemporaryPath,
) {
$error = $psrUploadedFile->getError();
$path = '';
if (\UPLOAD_ERR_NO_FILE !== $error) {
$path = $psrUploadedFile->getStream()->getMetadata('uri') ?? '';
if ($this->test = !\is_string($path) || !is_uploaded_file($path)) {
$path = $getTemporaryPath();
$psrUploadedFile->moveTo($path);
}
}
parent::__construct(
$path,
(string) $psrUploadedFile->getClientFilename(),
$psrUploadedFile->getClientMediaType(),
$psrUploadedFile->getError(),
$this->test
);
}
public function move(string $directory, ?string $name = null): File
{
if (!$this->isValid() || $this->test) {
return parent::move($directory, $name);
}
$target = $this->getTargetFile($directory, $name);
try {
$this->psrUploadedFile->moveTo((string) $target);
} catch (\RuntimeException $e) {
throw new FileException(\sprintf('Could not move the file "%s" to "%s" (%s).', $this->getPathname(), $target, $e->getMessage()), 0, $e);
}
@chmod($target, 0666 & ~umask());
return $target;
}
}

View File

@ -0,0 +1,35 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bridge\PsrHttpMessage;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
/**
* Creates Symfony Request and Response instances from PSR-7 ones.
*
* @author Kévin Dunglas <dunglas@gmail.com>
*/
interface HttpFoundationFactoryInterface
{
/**
* Creates a Symfony Request instance from a PSR-7 one.
*/
public function createRequest(ServerRequestInterface $psrRequest, bool $streamed = false): Request;
/**
* Creates a Symfony Response instance from a PSR-7 one.
*/
public function createResponse(ResponseInterface $psrResponse, bool $streamed = false): Response;
}

View File

@ -0,0 +1,35 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bridge\PsrHttpMessage;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
/**
* Creates PSR HTTP Request and Response instances from Symfony ones.
*
* @author Kévin Dunglas <dunglas@gmail.com>
*/
interface HttpMessageFactoryInterface
{
/**
* Creates a PSR-7 Request instance from a Symfony one.
*/
public function createRequest(Request $symfonyRequest): ServerRequestInterface;
/**
* Creates a PSR-7 Response instance from a Symfony one.
*/
public function createResponse(Response $symfonyResponse): ResponseInterface;
}

View File

@ -0,0 +1,19 @@
Copyright (c) 2004-present Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,13 @@
PSR-7 Bridge
============
Provides integration for PSR7.
Resources
---------
* [Documentation](https://symfony.com/doc/current/components/psr7.html)
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
* [Report issues](https://github.com/symfony/symfony/issues) and
[send Pull Requests](https://github.com/symfony/symfony/pulls)
in the [main Symfony repository](https://github.com/symfony/symfony)

View File

@ -0,0 +1,49 @@
{
"name": "symfony/psr-http-message-bridge",
"type": "symfony-bridge",
"description": "PSR HTTP message bridge",
"keywords": ["http", "psr-7", "psr-17", "http-message"],
"homepage": "https://symfony.com",
"license": "MIT",
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"require": {
"php": ">=8.2",
"psr/http-message": "^1.0|^2.0",
"symfony/http-foundation": "^6.4|^7.0"
},
"require-dev": {
"symfony/browser-kit": "^6.4|^7.0",
"symfony/config": "^6.4|^7.0",
"symfony/event-dispatcher": "^6.4|^7.0",
"symfony/framework-bundle": "^6.4|^7.0",
"symfony/http-kernel": "^6.4|^7.0",
"nyholm/psr7": "^1.1",
"php-http/discovery": "^1.15",
"psr/log": "^1.1.4|^2|^3"
},
"conflict": {
"php-http/discovery": "<1.15",
"symfony/http-kernel": "<6.4"
},
"config": {
"allow-plugins": {
"php-http/discovery": false
}
},
"autoload": {
"psr-4": { "Symfony\\Bridge\\PsrHttpMessage\\": "" },
"exclude-from-classmap": [
"/Tests/"
]
},
"minimum-stability": "dev"
}