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 Symfony\Component\Form\FormFactory; |
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
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* Parse mutation annotation to fetch definitions |
21
|
|
|
*/ |
22
|
|
|
class MutationAnnotationParser extends QueryAnnotationParser |
23
|
|
|
{ |
24
|
|
|
use AnnotationReaderAwareTrait; |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* @var FormFactory |
28
|
|
|
*/ |
29
|
|
|
protected $formFactory; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* @var Endpoint |
33
|
|
|
*/ |
34
|
|
|
protected $endpoint; |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* @param FormFactory $formFactory |
38
|
|
|
*/ |
39
|
1 |
|
public function __construct(FormFactory $formFactory) |
40
|
|
|
{ |
41
|
1 |
|
$this->formFactory = $formFactory; |
42
|
1 |
|
} |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* {@inheritdoc} |
46
|
|
|
*/ |
47
|
1 |
|
public function supports($annotation): bool |
48
|
|
|
{ |
49
|
1 |
|
return $annotation instanceof Annotation\Mutation; |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* {@inheritdoc} |
54
|
|
|
*/ |
55
|
1 |
|
public function parse($annotation, \ReflectionClass $refClass, Endpoint $endpoint) |
56
|
|
|
{ |
57
|
|
|
/** @var Annotation\Mutation $annotation */ |
58
|
|
|
|
59
|
1 |
|
if (!preg_match('/Bundle\\\\Mutation\\\\/', $refClass->getName())) { |
60
|
|
|
$error = sprintf( |
61
|
|
|
'Annotation "@Mutation" in the class "%s" is not valid, |
62
|
|
|
mutations can only be applied to classes inside "...Bundle\Mutation\..."', |
63
|
|
|
$refClass->getName() |
64
|
|
|
); |
65
|
|
|
throw new \Exception($error); |
66
|
|
|
} |
67
|
|
|
|
68
|
1 |
|
if (!$refClass->hasMethod('__invoke') && !$annotation->resolver) { |
69
|
|
|
$error = sprintf( |
70
|
|
|
'The class "%s" should have a method "__invoke" to process the mutation.', |
71
|
|
|
$refClass->getName() |
72
|
|
|
); |
73
|
|
|
throw new \Exception($error); |
74
|
|
|
} |
75
|
|
|
|
76
|
1 |
|
$mutation = new MutationDefinition(); |
77
|
|
|
|
78
|
1 |
View Code Duplication |
if ($annotation->name) { |
|
|
|
|
79
|
1 |
|
$mutation->setName($annotation->name); |
80
|
|
|
} else { |
81
|
1 |
|
$mutation->setName(lcfirst(ClassUtils::getDefaultName($refClass->getName()))); |
82
|
|
|
} |
83
|
|
|
|
84
|
1 |
|
$endpoint->addMutation($mutation); |
85
|
|
|
|
86
|
1 |
|
if (!$annotation->payload) { |
87
|
1 |
|
if (class_exists($refClass->getName().'Payload')) { |
88
|
1 |
|
$annotation->payload = $refClass->getName().'Payload'; |
89
|
1 |
|
if (!$endpoint->hasTypeForClass($annotation->payload)) { |
90
|
|
|
$error = sprintf( |
91
|
|
|
'The payload "%s" exist but does not exist a valid GraphQL type, is missing ObjectType annotation?', |
92
|
|
|
$annotation->payload |
93
|
|
|
); |
94
|
|
|
throw new \Exception($error); |
95
|
|
|
} |
96
|
|
|
} |
97
|
|
|
} |
98
|
|
|
|
99
|
1 |
|
$mutation->setType($annotation->payload); |
100
|
|
|
|
101
|
1 |
|
if (!$mutation->getType()) { |
102
|
|
|
$error = sprintf( |
103
|
|
|
'The mutation "%s" does not have a valid payload, |
104
|
|
|
create a file called %sPayload or specify a payload.', |
105
|
|
|
$mutation->getName(), |
106
|
|
|
$refClass->getName() |
107
|
|
|
); |
108
|
|
|
throw new \Exception($error); |
109
|
|
|
} |
110
|
|
|
|
111
|
1 |
|
$argAnnotations = $this->reader->getClassAnnotations($refClass); |
112
|
1 |
|
foreach ($argAnnotations as $argAnnotation) { |
113
|
1 |
|
if ($argAnnotation instanceof Annotation\Argument) { |
114
|
1 |
|
$this->resolveArgument($mutation, $argAnnotation); |
115
|
|
|
} |
116
|
|
|
} |
117
|
|
|
|
118
|
1 |
|
if ($annotation->node) { |
119
|
1 |
|
$mutation->setNode($annotation->node); |
120
|
|
|
} else { |
121
|
|
|
//try resolve a related node using naming convention |
122
|
|
|
//the related node name is always the last folder containing the mutation inside ...Bundle\Mutation |
123
|
1 |
|
preg_match('/Bundle\\\\Mutation([\\\\\w]+)?\\\\(\w+)\\\\\w+$/', $refClass->getName(), $matches); |
124
|
1 |
|
if (isset($matches[2]) && $endpoint->hasType($matches[2])) { |
125
|
1 |
|
$mutation->setNode($matches[2]); |
126
|
|
|
} |
127
|
|
|
} |
128
|
|
|
|
129
|
1 |
|
$mutation->setResolver($annotation->resolver ?? $refClass->getName()); |
130
|
1 |
|
$mutation->setDeprecationReason($annotation->deprecationReason); |
131
|
1 |
|
$mutation->setDescription($annotation->description); |
132
|
|
|
|
133
|
|
|
//enable form auto-loaded by default |
134
|
1 |
|
if (!isset($annotation->options['form'])) { |
135
|
1 |
|
$annotation->options['form'] = true; |
136
|
|
|
} |
137
|
|
|
|
138
|
1 |
|
foreach ($annotation->options as $option => $value) { |
139
|
1 |
|
$mutation->setMeta($option, $value); |
140
|
|
|
} |
141
|
1 |
|
} |
142
|
|
|
} |
143
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.