13
13
14
14
use Symfony \Bundle \MakerBundle \ConsoleStyle ;
15
15
use Symfony \Bundle \MakerBundle \DependencyBuilder ;
16
+ use Symfony \Bundle \MakerBundle \Exception \RuntimeCommandException ;
16
17
use Symfony \Bundle \MakerBundle \FileManager ;
17
18
use Symfony \Bundle \MakerBundle \Generator ;
18
19
use Symfony \Bundle \MakerBundle \InputAwareMakerInterface ;
51
52
52
53
/**
53
54
* @author Maelan LE BORGNE <[email protected] >
55
+ *
56
+ * @internal
54
57
*/
55
58
final class MakeWebhook extends AbstractMaker implements InputAwareMakerInterface
56
59
{
60
+ /** @see https://regex101.com/r/S3BWkx/1 */
61
+ public const WEBHOOK_NAME_PATTERN = '/^[a-zA-Z_.\-\x80-\xff][a-zA-Z0-9_.\-\x80-\xff]*$/u ' ;
57
62
private const WEBHOOK_CONFIG_PATH = 'config/packages/webhook.yaml ' ;
58
63
private YamlSourceManipulator $ ysm ;
64
+ private ?string $ name ;
59
65
60
66
public function __construct (
61
67
private FileManager $ fileManager ,
@@ -83,7 +89,7 @@ public function configureCommand(Command $command, InputConfiguration $inputConf
83
89
$ inputConfig ->setArgumentAsNonInteractive ('name ' );
84
90
}
85
91
86
- public function configureDependencies (DependencyBuilder $ dependencies , ?InputInterface $ input = null )
92
+ public function configureDependencies (DependencyBuilder $ dependencies , ?InputInterface $ input = null ): void
87
93
{
88
94
$ dependencies ->addClassDependency (
89
95
AbstractRequestParser::class,
@@ -101,9 +107,9 @@ public function configureDependencies(DependencyBuilder $dependencies, ?InputInt
101
107
102
108
public function interact (InputInterface $ input , ConsoleStyle $ io , Command $ command ): void
103
109
{
104
- if ($ input ->getArgument ('name ' )) {
105
- if (!$ this ->verifyWebhookName ($ input -> getArgument ( ' name ' ) )) {
106
- throw new \ InvalidArgumentException ('A webhook name can only have alphanumeric characters, underscores, dots, and dashes. ' );
110
+ if ($ this -> name = $ input ->getArgument ('name ' )) {
111
+ if (!$ this ->verifyWebhookName ($ this -> name )) {
112
+ throw new RuntimeCommandException ('A webhook name can only have alphanumeric characters, underscores, dots, and dashes. ' );
107
113
}
108
114
109
115
return ;
@@ -112,58 +118,56 @@ public function interact(InputInterface $input, ConsoleStyle $io, Command $comma
112
118
$ argument = $ command ->getDefinition ()->getArgument ('name ' );
113
119
$ question = new Question ($ argument ->getDescription ());
114
120
$ question ->setValidator (Validator::notBlank (...));
115
- $ webhookName = $ io ->askQuestion ($ question );
116
121
117
- while (!$ this ->verifyWebhookName ($ webhookName )) {
122
+ $ this ->name = $ io ->askQuestion ($ question );
123
+ while (!$ this ->verifyWebhookName ($ this ->name )) {
118
124
$ io ->error ('A webhook name can only have alphanumeric characters, underscores, dots, and dashes. ' );
119
- $ webhookName = $ io ->askQuestion ($ question );
125
+ $ this -> name = $ io ->askQuestion ($ question );
120
126
}
121
-
122
- $ input ->setArgument ('name ' , $ webhookName );
123
- }
124
-
125
- private function verifyWebhookName (string $ entityName ): bool
126
- {
127
- return preg_match ('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_.\-\x7f-\xff]*$/ ' , $ entityName );
128
127
}
129
128
130
129
public function generate (InputInterface $ input , ConsoleStyle $ io , Generator $ generator ): void
131
130
{
132
- $ webhookName = $ input ->getArgument ('name ' );
133
131
$ requestParserDetails = $ this ->generator ->createClassNameDetails (
134
- Str::asClassName ($ webhookName .'RequestParser ' ),
132
+ Str::asClassName ($ this -> name .'RequestParser ' ),
135
133
'Webhook \\'
136
134
);
137
135
$ remoteEventHandlerDetails = $ this ->generator ->createClassNameDetails (
138
- Str::asClassName ($ webhookName .'WebhookHandler ' ),
136
+ Str::asClassName ($ this -> name .'WebhookHandler ' ),
139
137
'RemoteEvent \\'
140
138
);
141
139
142
- $ this ->addToYamlConfig ($ webhookName , $ requestParserDetails );
140
+ $ this ->addToYamlConfig ($ this -> name , $ requestParserDetails );
143
141
144
142
$ this ->generateRequestParser ($ io , $ requestParserDetails );
145
143
146
144
$ this ->generator ->generateClass (
147
145
$ remoteEventHandlerDetails ->getFullName (),
148
146
'webhook/WebhookHandler.tpl.php ' ,
149
147
[
150
- 'webhook_name ' => $ webhookName ,
148
+ 'webhook_name ' => $ this -> name ,
151
149
]
152
150
);
153
151
154
152
$ this ->generator ->writeChanges ();
155
153
$ this ->fileManager ->dumpFile (self ::WEBHOOK_CONFIG_PATH , $ this ->ysm ->getContents ());
156
154
}
157
155
156
+ private function verifyWebhookName (string $ entityName ): bool
157
+ {
158
+ return preg_match (self ::WEBHOOK_NAME_PATTERN , $ entityName );
159
+ }
160
+
158
161
private function addToYamlConfig (string $ webhookName , ClassNameDetails $ requestParserDetails ): void
159
162
{
160
- if (!$ this ->fileManager ->fileExists (self ::WEBHOOK_CONFIG_PATH )) {
161
- $ yamlConfig = Yaml::dump (['framework ' => ['webhook ' => ['routing ' => []]]], 4 , 2 );
162
- } else {
163
+ $ yamlConfig = Yaml::dump (['framework ' => ['webhook ' => ['routing ' => []]]], 4 , 2 );
164
+ if ($ this ->fileManager ->fileExists (self ::WEBHOOK_CONFIG_PATH )) {
163
165
$ yamlConfig = $ this ->fileManager ->getFileContents (self ::WEBHOOK_CONFIG_PATH );
164
166
}
167
+
165
168
$ this ->ysm = new YamlSourceManipulator ($ yamlConfig );
166
169
$ arrayConfig = $ this ->ysm ->getData ();
170
+
167
171
if (\array_key_exists ($ webhookName , $ arrayConfig ['framework ' ]['webhook ' ]['routing ' ] ?? [])) {
168
172
throw new \InvalidArgumentException ('A webhook with this name already exists ' );
169
173
}
@@ -180,7 +184,7 @@ private function addToYamlConfig(string $webhookName, ClassNameDetails $requestP
180
184
/**
181
185
* @throws \Exception
182
186
*/
183
- public function generateRequestParser (ConsoleStyle $ io , ClassNameDetails $ requestParserDetails ): void
187
+ private function generateRequestParser (ConsoleStyle $ io , ClassNameDetails $ requestParserDetails ): void
184
188
{
185
189
$ useStatements = new UseStatementGenerator ([
186
190
JsonException::class,
@@ -191,6 +195,7 @@ public function generateRequestParser(ConsoleStyle $io, ClassNameDetails $reques
191
195
RejectWebhookException::class,
192
196
RequestMatcherInterface::class,
193
197
]);
198
+
194
199
$ requestMatchers = [];
195
200
while (true ) {
196
201
$ newRequestMatcher = $ this ->askForNextRequestMatcher ($ io , $ requestMatchers , $ requestParserDetails ->getFullName (), empty ($ requestMatchers ));
@@ -199,12 +204,14 @@ public function generateRequestParser(ConsoleStyle $io, ClassNameDetails $reques
199
204
}
200
205
$ requestMatchers [] = $ newRequestMatcher ;
201
206
}
202
- $ useChainRequestsMatcher = false ;
207
+
203
208
// Use a ChainRequestMatcher if multiple matchers have been added OR if none (will be printed with an empty array)
209
+ $ useChainRequestsMatcher = false ;
204
210
if (1 !== \count ($ requestMatchers )) {
205
211
$ useChainRequestsMatcher = true ;
206
212
$ useStatements ->addUseStatement (ChainRequestMatcher::class);
207
213
}
214
+
208
215
$ requestMatcherArguments = [];
209
216
foreach ($ requestMatchers as $ requestMatcherClass ) {
210
217
$ useStatements ->addUseStatement ($ requestMatcherClass );
@@ -245,6 +252,7 @@ private function askForNextRequestMatcher(ConsoleStyle $io, array $addedMatchers
245
252
$ choices = array_diff ($ availableMatchers , $ addedMatchers );
246
253
$ question = new ChoiceQuestion ($ questionText , array_values (['<skip> ' ] + $ choices ), 0 );
247
254
$ matcherName = $ io ->askQuestion ($ question );
255
+
248
256
if ('<skip> ' === $ matcherName ) {
249
257
return null ;
250
258
}
0 commit comments