Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
echo "::set-output name=dir::$(composer config cache-files-dir)"
- name: composer-cache
uses: actions/cache@v4.0.2
uses: actions/cache@v5.0.1
with:
path: ${{ steps.composercache.outputs.dir }}
key: composer-${{ hashFiles('**/composer.json') }}-${{ matrix.install-args }}
Expand All @@ -53,7 +53,7 @@ jobs:
vendor/bin/simple-phpunit --no-coverage
- name: phpstan-cache
uses: actions/cache@v4.0.2
uses: actions/cache@v5.0.1
with:
key: phpstan-${{ matrix.php-version }}-${{ matrix.install-args }}-${{ github.ref }}-${{ github.sha }}
path: .phpstan-cache
Expand Down
2 changes: 1 addition & 1 deletion Controller/GraphQL/InvalidUserPasswordException.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

class InvalidUserPasswordException extends GraphQLException
{
public static function create(Exception $previous = null): self
public static function create(?Exception $previous = null): self
{
return new self('The provided user / password is incorrect.', 401, $previous, 'Security');
}
Expand Down
39 changes: 19 additions & 20 deletions Controller/GraphQLiteController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@
use Laminas\Diactoros\ServerRequestFactory;
use Laminas\Diactoros\StreamFactory;
use Laminas\Diactoros\UploadedFileFactory;
use LogicException;
use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
use TheCodingMachine\GraphQLite\Bundle\UploadMiddlewareUtils\DummyResponseWithRequest;
use TheCodingMachine\GraphQLite\Bundle\UploadMiddlewareUtils\RequestExtractorMiddleware;
use TheCodingMachine\GraphQLite\Http\HttpCodeDecider;
use TheCodingMachine\GraphQLite\Http\HttpCodeDeciderInterface;
use function array_map;
use GraphQL\Executor\ExecutionResult;
use GraphQL\Server\ServerConfig;
use GraphQL\Server\StandardServer;
use GraphQL\Upload\UploadMiddleware;
use function class_exists;
use function json_decode;
use Psr\Http\Message\ServerRequestInterface;
use RuntimeException;
use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface;
Expand All @@ -28,25 +28,20 @@
use Symfony\Component\Routing\RouteCollection;
use TheCodingMachine\GraphQLite\Bundle\Context\SymfonyGraphQLContext;

use function array_map;
use function class_exists;
use function get_class;
use function json_decode;

/**
* Listens to every single request and forward Graphql requests to Graphql Webonix standardServer.
* Listens to every single request and forwards GraphQL requests to Webonyx's {@see \GraphQL\Server\StandardServer}.
*/
class GraphQLiteController
{
/**
* @var HttpMessageFactoryInterface
*/
private $httpMessageFactory;
/** @var int */
private $debug;
/**
* @var ServerConfig
*/
private $serverConfig;
/**
* @var HttpCodeDeciderInterface
*/
private $httpCodeDecider;
private HttpMessageFactoryInterface $httpMessageFactory;
private int $debug;
private ServerConfig $serverConfig;
private HttpCodeDeciderInterface $httpCodeDecider;

public function __construct(ServerConfig $serverConfig, ?HttpMessageFactoryInterface $httpMessageFactory = null, ?int $debug = null, ?HttpCodeDeciderInterface $httpCodeDecider = null)
{
Expand Down Expand Up @@ -90,10 +85,14 @@ public function handleRequest(Request $request): Response
$psr7Request = $psr7Request->withParsedBody($parsedBody);
}

// Let's parse the request and adapt it for file uploads.
// Let's parse the request and adapt it for file uploads by extracting it from the middleware.
if (class_exists(UploadMiddleware::class)) {
$uploadMiddleware = new UploadMiddleware();
$psr7Request = $uploadMiddleware->processRequest($psr7Request);
$dummyResponseWithRequest = $uploadMiddleware->process($psr7Request, new RequestExtractorMiddleware());
if (! $dummyResponseWithRequest instanceof DummyResponseWithRequest) {
throw new LogicException(DummyResponseWithRequest::class . ' expect, got ' . get_class($dummyResponseWithRequest));
}
$psr7Request = $dummyResponseWithRequest->getRequest();
}

return $this->handlePsr7Request($psr7Request, $request);
Expand Down
27 changes: 27 additions & 0 deletions UploadMiddlewareUtils/DummyResponseWithRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace TheCodingMachine\GraphQLite\Bundle\UploadMiddlewareUtils;

use Laminas\Diactoros\Response;
use Psr\Http\Message\ServerRequestInterface;

/**
* Class used to allow extraction of request from PSR-15 middleware
*
* @internal
*/
class DummyResponseWithRequest extends Response
{
private ServerRequestInterface $request;

public function __construct(ServerRequestInterface $request)
{
parent::__construct();
$this->request = $request;
}

public function getRequest(): ServerRequestInterface
{
return $this->request;
}
}
21 changes: 21 additions & 0 deletions UploadMiddlewareUtils/RequestExtractorMiddleware.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace TheCodingMachine\GraphQLite\Bundle\UploadMiddlewareUtils;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;

/**
* Middleware to extract the request from the middleware chain
*
* @internal
*/
class RequestExtractorMiddleware implements RequestHandlerInterface
{
public function handle(ServerRequestInterface $request): ResponseInterface
{
return new DummyResponseWithRequest($request);
}

}
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"phpstan": "phpstan analyse GraphQLiteBundle.php DependencyInjection/ Controller/ Resources/ Security/ -c phpstan.neon --level=7 --no-progress"
},
"suggest": {
"ecodev/graphql-upload": "If you want to support file upload inside GraphQL input types (v7/v8)",
"symfony/security-bundle": "To use @Logged or @Right annotations"
},
"autoload" : {
Expand Down
Loading