Completed
Push — master ( 186982...2975e7 )
by Rafael
05:12
created

MutationAnnotationParser::supports()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
/*******************************************************************************
3
 *  This file is part of the GraphQL Bundle package.
4
 *
5
 *  (c) YnloUltratech <[email protected]>
6
 *
7
 *  For the full copyright and license information, please view the LICENSE
8
 *  file that was distributed with this source code.
9
 ******************************************************************************/
10
11
namespace Ynlo\GraphQLBundle\Definition\Loader\Annotation;
12
13
use Doctrine\Common\Annotations\Reader;
14
use Ynlo\GraphQLBundle\Annotation;
15
use Ynlo\GraphQLBundle\Definition\MutationDefinition;
16
use Ynlo\GraphQLBundle\Definition\Registry\Endpoint;
17
use Ynlo\GraphQLBundle\Util\ClassUtils;
18
use Ynlo\GraphQLBundle\Util\TypeUtil;
19
20
/**
21
 * Parse mutation annotation to fetch definitions
22
 */
23
class MutationAnnotationParser extends QueryAnnotationParser
24
{
25
    /**
26
     * @var Reader
27
     */
28
    protected $reader;
29
30
    /**
31
     * MutationAnnotationParser constructor.
32
     *
33
     * @param Reader $reader
34
     */
35 29
    public function __construct(Reader $reader)
36
    {
37 29
        $this->reader = $reader;
38 29
    }
39
40
    /**
41
     * {@inheritdoc}
42
     */
43 25
    public function supports($annotation): bool
44
    {
45 25
        return $annotation instanceof Annotation\Mutation;
46
    }
47
48
    /**
49
     * {@inheritdoc}
50
     *
51
     * @param Annotation\Mutation $annotation
52
     */
53 10
    public function parse($annotation, \ReflectionClass $refClass, Endpoint $endpoint)
54
    {
55
        /** @var Annotation\Mutation $annotation */
56
57 10
        if (!preg_match('/\\Mutation\\\\/', $refClass->getName())) {
58
            $error = sprintf(
59
                'Annotation "@Mutation" in the class "%s" is not valid, 
60
            mutations can only be applied to classes inside "...Bundle\Mutation\..."',
61
                $refClass->getName()
62
            );
63
            throw new \RuntimeException($error);
64
        }
65
66 10
        if (!$annotation->resolver && !$refClass->hasMethod('__invoke')) {
67
            $error = sprintf(
68
                'The class "%s" should have a method "__invoke" to process the mutation.',
69
                $refClass->getName()
70
            );
71
            throw new \RuntimeException($error);
72
        }
73
74 10
        $mutation = new MutationDefinition();
75
76 10
        if ($annotation->name) {
77 10
            $mutation->setName($annotation->name);
78
        } else {
79
            $mutation->setName(lcfirst(ClassUtils::getDefaultName($refClass->getName())));
80
        }
81
82 10
        $endpoint->addMutation($mutation);
83
84 10
        if (!$annotation->payload) {
85
            if (class_exists($refClass->getName().'Payload')) {
86
                $annotation->payload = $refClass->getName().'Payload';
87
                if (!$endpoint->hasTypeForClass($annotation->payload)) {
88
                    $error = sprintf(
89
                        'The payload "%s" exist but does not exist a valid GraphQL type, is missing ObjectType annotation?',
90
                        $annotation->payload
91
                    );
92
                    throw new \RuntimeException($error);
93
                }
94
            }
95
        }
96
97 10
        $mutation->setType(TypeUtil::normalize($annotation->payload));
98 10
        $mutation->setList(TypeUtil::isTypeList($annotation->payload));
99 10
        $mutation->setNonNullList(TypeUtil::isTypeNonNullList($annotation->payload));
100 10
        $mutation->setNonNull(TypeUtil::isTypeNonNull($annotation->payload));
101
102 10
        if (!$mutation->getType()) {
103
            $error = sprintf(
104
                'The mutation "%s" does not have a valid payload,
105
                 create a file called %sPayload or specify a payload.',
106
                $mutation->getName(),
107
                $refClass->getName()
108
            );
109
            throw new \RuntimeException($error);
110
        }
111
112 10
        $argAnnotations = $this->reader->getClassAnnotations($refClass);
113 10
        foreach ($argAnnotations as $argAnnotation) {
114
            if ($argAnnotation instanceof Annotation\Argument) {
115
                $this->resolveArgument($mutation, $argAnnotation);
116
            }
117
        }
118
119 10
        if ($annotation->node) {
120 10
            $mutation->setNode($annotation->node);
121
        } else {
122
            if ($node = ClassUtils::getNodeFromClass($refClass->getName())) {
123
                $mutation->setNode($node);
124
            }
125
        }
126
127 10
        $mutation->setResolver($annotation->resolver ?? $refClass->getName());
128 10
        $mutation->setDeprecationReason($annotation->deprecationReason);
129 10
        $mutation->setDescription($annotation->description);
130
131
        //enable form auto-loaded by default
132 10
        if (!isset($annotation->options['form'])) {
133
            $annotation->options['form'] = true;
134
        }
135
136 10
        foreach ($annotation->options as $option => $value) {
137 10
            $mutation->setMeta($option, $value);
138
        }
139 10
    }
140
}
141