Passed
Pull Request — 2.1 (#1729)
by Antoine
04:12 queued 01:10
created

EntrypointAction::parseRequest()   D

Complexity

Conditions 9
Paths 30

Size

Total Lines 35
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 35
rs 4.909
c 0
b 0
f 0
cc 9
eloc 18
nc 30
nop 1
1
<?php
2
3
/*
4
 * This file is part of the API Platform project.
5
 *
6
 * (c) Kévin Dunglas <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace ApiPlatform\Core\GraphQl\Action;
15
16
use ApiPlatform\Core\GraphQl\ExecutorInterface;
17
use ApiPlatform\Core\GraphQl\Type\SchemaBuilderInterface;
18
use GraphQL\Error\Error;
19
use GraphQL\Executor\ExecutionResult;
20
use Symfony\Component\HttpFoundation\JsonResponse;
21
use Symfony\Component\HttpFoundation\Request;
22
use Symfony\Component\HttpFoundation\Response;
23
24
/**
25
 * GraphQL API entrypoint.
26
 *
27
 * @author Alan Poulain <[email protected]>
28
 */
29
final class EntrypointAction
30
{
31
    private $schemaBuilder;
32
    private $executor;
33
    private $twig;
34
    private $debug;
35
    private $title;
36
    private $graphiqlEnabled;
37
38
    public function __construct(SchemaBuilderInterface $schemaBuilder, ExecutorInterface $executor, \Twig_Environment $twig, bool $debug = false, bool $graphiqlEnabled = false, string $title = '')
39
    {
40
        $this->schemaBuilder = $schemaBuilder;
41
        $this->executor = $executor;
42
        $this->twig = $twig;
43
        $this->debug = $debug;
44
        $this->graphiqlEnabled = $graphiqlEnabled;
45
        $this->title = $title;
46
    }
47
48
    public function __invoke(Request $request): Response
49
    {
50
        if ($this->graphiqlEnabled && $request->isMethod('GET') && 'html' === $request->getRequestFormat()) {
51
            return new Response($this->twig->render('@ApiPlatform/Graphiql/index.html.twig', ['title' => $this->title]));
52
        }
53
54
        list($query, $operation, $variables) = $this->parseRequest($request);
55
56
        if (null === $query) {
57
            return new JsonResponse(new ExecutionResult(null, [new Error('GraphQL query is not valid')]), Response::HTTP_BAD_REQUEST);
58
        }
59
60
        if (null === $variables) {
61
            return new JsonResponse(new ExecutionResult(null, [new Error('GraphQL variables are not valid JSON')]), Response::HTTP_BAD_REQUEST);
62
        }
63
64
        try {
65
            $executionResult = $this->executor->executeQuery($this->schemaBuilder->getSchema(), $query, null, null, $variables, $operation);
66
        } catch (\Exception $e) {
67
            $executionResult = new ExecutionResult(null, [$e]);
68
        }
69
70
        return new JsonResponse($executionResult->toArray($this->debug), $executionResult->errors ? Response::HTTP_BAD_REQUEST : Response::HTTP_OK);
71
    }
72
73
    private function parseRequest(Request $request): array
74
    {
75
        $query = $request->query->get('query');
76
        $operation = $request->query->get('operation');
77
        if ($variables = $request->query->get('variables', [])) {
78
            $variables = \json_decode($variables, true);
79
        }
80
81
        if (!$request->isMethod('POST')) {
82
            return [$query, $operation, $variables];
83
        }
84
85
        if ('json' === $request->getContentType()) {
86
            $input = \json_decode($request->getContent(), true);
87
88
            if (isset($input['query'])) {
89
                $query = $input['query'];
90
            }
91
92
            if (isset($input['variables'])) {
93
                $variables = \is_array($input['variables']) ? $input['variables'] : \json_decode($input['variables'], true);
94
            }
95
96
            if (isset($input['operation'])) {
97
                $operation = $input['operation'];
98
            }
99
100
            return [$query, $operation, $variables];
101
        }
102
103
        if ('application/graphql' === $request->headers->get('CONTENT_TYPE')) {
104
            $query = $request->getContent();
105
        }
106
107
        return [$query, $operation, $variables];
108
    }
109
}
110