1
|
|
|
<?php |
2
|
|
|
declare(strict_types=1); |
3
|
|
|
|
4
|
|
|
namespace WyriHaximus\ApiClient\Tools; |
5
|
|
|
|
6
|
|
|
use Aura\Cli\Context; |
7
|
|
|
use Aura\Cli\Stdio; |
8
|
|
|
use Doctrine\Common\Inflector\Inflector; |
9
|
|
|
use Exception; |
10
|
|
|
use PhpParser\Builder\Method; |
11
|
|
|
use PhpParser\Builder\Property; |
12
|
|
|
use PhpParser\BuilderFactory; |
13
|
|
|
use PhpParser\PrettyPrinter; |
14
|
|
|
use PhpParser\Node; |
15
|
|
|
use Symfony\Component\Yaml\Yaml; |
16
|
|
|
use Symfony\CS\Config\Config; |
17
|
|
|
use Symfony\CS\ConfigAwareInterface; |
18
|
|
|
use Symfony\CS\ConfigInterface; |
19
|
|
|
use Symfony\CS\FileCacheManager; |
20
|
|
|
use Symfony\CS\Fixer; |
21
|
|
|
use Symfony\CS\FixerInterface; |
22
|
|
|
use WyriHaximus\ApiClient\Annotations\Collection; |
23
|
|
|
use WyriHaximus\ApiClient\Annotations\Nested; |
24
|
|
|
use WyriHaximus\ApiClient\Annotations\Rename; |
25
|
|
|
use WyriHaximus\ApiClient\Resource\ResourceInterface; |
26
|
|
|
|
27
|
|
|
class ResourceGenerator |
28
|
|
|
{ |
29
|
|
|
/** |
30
|
|
|
* @var Context |
31
|
|
|
*/ |
32
|
|
|
protected $context; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* @var Stdio |
36
|
|
|
*/ |
37
|
|
|
protected $stdio; |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* @var array |
41
|
|
|
*/ |
42
|
|
|
protected $definitions = []; |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* @var string |
46
|
|
|
*/ |
47
|
|
|
protected $path; |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* @var Fixer |
51
|
|
|
*/ |
52
|
|
|
protected $fixer; |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* @var array |
56
|
|
|
*/ |
57
|
|
|
protected $fixers; |
58
|
|
|
|
59
|
2 |
|
public function __construct(Context $context, Stdio $stdio) |
60
|
|
|
{ |
61
|
2 |
|
$this->context = $context; |
62
|
2 |
|
$this->stdio = $stdio; |
63
|
|
|
|
64
|
2 |
|
$this->setUpArguments(); |
65
|
2 |
|
$this->setUpFixers(); |
66
|
2 |
|
} |
67
|
|
|
|
68
|
2 |
|
protected function setUpArguments() |
69
|
|
|
{ |
70
|
2 |
|
$getOpt = $this->context->getopt([]); |
71
|
2 |
|
$i = 0; |
72
|
|
|
do { |
73
|
2 |
|
$i++; |
74
|
2 |
|
$opt = $getOpt->get($i); |
75
|
2 |
|
if ($opt === null) { |
76
|
2 |
|
break; |
77
|
|
|
} |
78
|
2 |
|
$this->definitions[] = $opt; |
79
|
2 |
|
} while (true); |
80
|
2 |
|
$this->path = array_pop($this->definitions); |
81
|
2 |
|
} |
82
|
|
|
|
83
|
2 |
|
protected function setUpFixers() |
84
|
|
|
{ |
85
|
2 |
|
$this->fixer = new Fixer(); |
86
|
2 |
|
$this->fixer->registerCustomFixers([ |
87
|
2 |
|
new Fixer\Symfony\ExtraEmptyLinesFixer(), |
88
|
2 |
|
new Fixer\Symfony\SingleBlankLineBeforeNamespaceFixer(), |
89
|
2 |
|
new Fixer\PSR0\Psr0Fixer(), |
90
|
2 |
|
new Fixer\PSR1\EncodingFixer(), |
91
|
2 |
|
new Fixer\PSR1\ShortTagFixer(), |
92
|
2 |
|
new Fixer\PSR2\BracesFixer(), |
93
|
2 |
|
new Fixer\PSR2\ElseifFixer(), |
94
|
2 |
|
new Fixer\PSR2\EofEndingFixer(), |
95
|
2 |
|
new Fixer\PSR2\FunctionCallSpaceFixer(), |
96
|
2 |
|
new Fixer\PSR2\FunctionDeclarationFixer(), |
97
|
2 |
|
new Fixer\PSR2\IndentationFixer(), |
98
|
2 |
|
new Fixer\PSR2\LineAfterNamespaceFixer(), |
99
|
2 |
|
new Fixer\PSR2\LinefeedFixer(), |
100
|
2 |
|
new Fixer\PSR2\LowercaseConstantsFixer(), |
101
|
2 |
|
new Fixer\PSR2\LowercaseKeywordsFixer(), |
102
|
2 |
|
new Fixer\PSR2\MethodArgumentSpaceFixer(), |
103
|
2 |
|
new Fixer\PSR2\MultipleUseFixer(), |
104
|
2 |
|
new Fixer\PSR2\ParenthesisFixer(), |
105
|
2 |
|
new Fixer\PSR2\PhpClosingTagFixer(), |
106
|
2 |
|
new Fixer\PSR2\SingleLineAfterImportsFixer(), |
107
|
2 |
|
new Fixer\PSR2\TrailingSpacesFixer(), |
108
|
2 |
|
new Fixer\PSR2\VisibilityFixer(), |
109
|
2 |
|
new Fixer\Contrib\NewlineAfterOpenTagFixer(), |
110
|
2 |
|
new EmptyLineAboveDocblocksFixer(), |
111
|
|
|
]); |
112
|
2 |
|
$config = Config::create()-> |
113
|
2 |
|
fixers($this->fixer->getFixers()) |
114
|
|
|
; |
115
|
2 |
|
$this->fixer->addConfig($config); |
116
|
2 |
|
$this->fixers = $this->prepareFixers($config); |
117
|
2 |
|
} |
118
|
|
|
|
119
|
1 |
|
public function run() |
120
|
|
|
{ |
121
|
1 |
|
$this->checkValidity(); |
122
|
|
|
|
123
|
1 |
|
foreach ($this->definitions as $definition) { |
124
|
1 |
|
$this->stdio->outln('-----'); |
125
|
1 |
|
$this->stdio->outln('- Definition: ' . $definition); |
126
|
1 |
|
$this->stdio->outln('-----'); |
127
|
1 |
|
$this->generateFromDefinition($definition); |
128
|
1 |
|
$this->stdio->outln('-----'); |
129
|
|
|
} |
130
|
1 |
|
} |
131
|
|
|
|
132
|
1 |
|
public function checkValidity() |
133
|
|
|
{ |
134
|
1 |
|
if (count($this->definitions) < 1) { |
135
|
|
|
throw new \InvalidArgumentException('Not enough arguments'); |
136
|
|
|
} |
137
|
|
|
|
138
|
1 |
|
if ($this->path === null) { |
139
|
|
|
throw new \InvalidArgumentException('No path set'); |
140
|
|
|
} |
141
|
|
|
|
142
|
1 |
|
if (!file_exists($this->path)) { |
143
|
|
|
throw new \InvalidArgumentException('Path "' . $this->path . '" doesn\'t exist'); |
144
|
|
|
} |
145
|
|
|
|
146
|
1 |
|
if (!is_dir($this->path)) { |
147
|
|
|
throw new \InvalidArgumentException('Path "' . $this->path . '" isn\'t a directory'); |
148
|
|
|
} |
149
|
|
|
|
150
|
1 |
|
foreach ($this->definitions as $definition) { |
151
|
1 |
|
if (!file_exists($definition)) { |
152
|
1 |
|
throw new \InvalidArgumentException('Definition "' . $definition . '" doesn\'t exist'); |
153
|
|
|
} |
154
|
|
|
} |
155
|
1 |
|
} |
156
|
|
|
|
157
|
1 |
|
public function generateFromDefinition(string $definition) |
158
|
|
|
{ |
159
|
1 |
|
$yaml = $this->readYaml($definition); |
160
|
|
|
|
161
|
1 |
|
$namespacePadding = explode('\\', $yaml['class']); |
162
|
1 |
|
$namespace = explode('\\', $yaml['namespace']); |
163
|
|
|
|
164
|
1 |
|
$yaml['class'] = array_pop($namespacePadding); |
165
|
1 |
|
$yaml['namespace'] = implode('\\', array_merge($namespace, $namespacePadding)); |
166
|
|
|
|
167
|
1 |
|
$namespacePathPadding = implode(DIRECTORY_SEPARATOR, $namespacePadding); |
168
|
1 |
|
$baseClass = implode( |
169
|
1 |
|
'\\', |
170
|
|
|
array_merge( |
171
|
|
|
$namespace, |
172
|
|
|
$namespacePadding, |
173
|
|
|
[ |
174
|
1 |
|
$yaml['class'] |
175
|
|
|
] |
176
|
|
|
) |
177
|
|
|
); |
178
|
|
|
|
179
|
|
|
|
180
|
1 |
|
if (isset($yaml['rename'])) { |
181
|
1 |
|
foreach ($yaml['rename'] as $key => $resource) { |
182
|
1 |
|
$yaml['properties'][$resource] = $yaml['properties'][$key]; |
183
|
1 |
|
unset($yaml['properties'][$key]); |
184
|
|
|
} |
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
|
188
|
1 |
|
$this->stdio->out('Interface: generating'); |
189
|
1 |
|
$this->save( |
190
|
1 |
|
$this->path . |
191
|
1 |
|
DIRECTORY_SEPARATOR . |
192
|
1 |
|
$namespacePathPadding . |
193
|
1 |
|
DIRECTORY_SEPARATOR, |
194
|
1 |
|
$yaml['class'] . |
195
|
1 |
|
'Interface.php', |
196
|
1 |
|
$this->createInterface($yaml) |
197
|
|
|
); |
198
|
|
|
|
199
|
1 |
|
$this->stdio->out('Base class: generating'); |
200
|
1 |
|
$this->save( |
201
|
1 |
|
$this->path . |
202
|
1 |
|
DIRECTORY_SEPARATOR . |
203
|
1 |
|
$namespacePathPadding . |
204
|
1 |
|
DIRECTORY_SEPARATOR, |
205
|
1 |
|
$yaml['class'] . |
206
|
1 |
|
'.php', |
207
|
1 |
|
$this->createBaseClass($yaml) |
208
|
|
|
); |
209
|
|
|
|
210
|
1 |
|
$this->stdio->out('Async class: generating'); |
211
|
1 |
|
$this->save( |
212
|
1 |
|
$this->path . |
213
|
1 |
|
DIRECTORY_SEPARATOR . |
214
|
1 |
|
'Async' . |
215
|
1 |
|
DIRECTORY_SEPARATOR . |
216
|
1 |
|
$namespacePathPadding . |
217
|
1 |
|
DIRECTORY_SEPARATOR, |
218
|
1 |
|
$yaml['class'] . |
219
|
1 |
|
'.php', |
220
|
1 |
|
$this->createExtendingClass( |
221
|
|
|
implode( |
222
|
1 |
|
'\\', |
223
|
|
|
array_merge( |
224
|
|
|
$namespace, |
225
|
|
|
[ |
226
|
1 |
|
'Async', |
227
|
|
|
], |
228
|
|
|
$namespacePadding |
229
|
|
|
) |
230
|
|
|
), |
231
|
1 |
|
$yaml['class'], |
232
|
|
|
$baseClass |
233
|
|
|
) |
234
|
|
|
); |
235
|
|
|
|
236
|
1 |
|
$this->stdio->out('Sync class: generating'); |
237
|
1 |
|
$this->save( |
238
|
1 |
|
$this->path . |
239
|
1 |
|
DIRECTORY_SEPARATOR . |
240
|
1 |
|
'Sync' . |
241
|
1 |
|
DIRECTORY_SEPARATOR . |
242
|
1 |
|
$namespacePathPadding . |
243
|
1 |
|
DIRECTORY_SEPARATOR, |
244
|
1 |
|
$yaml['class'] . |
245
|
1 |
|
'.php', |
246
|
1 |
|
$this->createExtendingClass( |
247
|
|
|
implode( |
248
|
1 |
|
'\\', |
249
|
|
|
array_merge( |
250
|
|
|
$namespace, |
251
|
|
|
[ |
252
|
1 |
|
'Sync', |
253
|
|
|
], |
254
|
|
|
$namespacePadding |
255
|
|
|
) |
256
|
|
|
), |
257
|
1 |
|
$yaml['class'], |
258
|
|
|
$baseClass |
259
|
|
|
) |
260
|
|
|
); |
261
|
1 |
|
} |
262
|
|
|
|
263
|
1 |
|
protected function readYaml(string $filename): array |
264
|
|
|
{ |
265
|
1 |
|
return Yaml::parse(file_get_contents($filename)); |
266
|
|
|
} |
267
|
|
|
|
268
|
1 |
|
protected function createBaseClass(array $yaml): string |
269
|
|
|
{ |
270
|
1 |
|
$factory = new BuilderFactory; |
271
|
|
|
|
272
|
1 |
|
$class = $factory->class($yaml['class']) |
273
|
1 |
|
->implement($yaml['class'] . 'Interface') |
274
|
1 |
|
->makeAbstract(); |
275
|
|
|
|
276
|
1 |
|
$docBlock = []; |
277
|
|
|
|
278
|
1 |
View Code Duplication |
if (isset($yaml['collection'])) { |
|
|
|
|
279
|
1 |
|
$nestedResources = []; |
280
|
1 |
|
foreach ($yaml['collection'] as $key => $resource) { |
281
|
1 |
|
$nestedResources[] = $key . '="' . $resource . '"'; |
282
|
|
|
} |
283
|
1 |
|
$docBlock[] = '@Collection(' . implode(', ', $nestedResources) . ')'; |
284
|
|
|
} |
285
|
|
|
|
286
|
1 |
View Code Duplication |
if (isset($yaml['nested'])) { |
|
|
|
|
287
|
1 |
|
$nestedResources = []; |
288
|
1 |
|
foreach ($yaml['nested'] as $key => $resource) { |
289
|
1 |
|
$nestedResources[] = $key . '="' . $resource . '"'; |
290
|
|
|
} |
291
|
1 |
|
$docBlock[] = '@Nested(' . implode(', ', $nestedResources) . ')'; |
292
|
|
|
} |
293
|
|
|
|
294
|
1 |
View Code Duplication |
if (isset($yaml['rename'])) { |
|
|
|
|
295
|
1 |
|
$nestedResources = []; |
296
|
1 |
|
foreach ($yaml['rename'] as $key => $resource) { |
297
|
1 |
|
$nestedResources[] = $resource . '="' . $key . '"'; |
298
|
|
|
} |
299
|
1 |
|
$docBlock[] = '@Rename(' . implode(', ', $nestedResources) . ')'; |
300
|
|
|
} |
301
|
|
|
|
302
|
1 |
|
if (count($docBlock) > 0) { |
303
|
1 |
|
$class->setDocComment("/**\r\n * " . implode("\r\n * ", $docBlock) . "\r\n */"); |
304
|
|
|
} |
305
|
|
|
|
306
|
1 |
|
$class->addStmt( |
307
|
1 |
|
new Node\Stmt\TraitUse([ |
308
|
1 |
|
new Node\Name('TransportAwareTrait') |
309
|
|
|
]) |
310
|
|
|
); |
311
|
|
|
|
312
|
1 |
|
foreach ($yaml['properties'] as $name => $details) { |
313
|
1 |
|
$type = $details; |
314
|
1 |
|
if (is_array($details)) { |
315
|
1 |
|
$type = $details['type']; |
316
|
|
|
} |
317
|
1 |
|
$class->addStmt($this->createProperty($factory, $type, $name, $details)); |
318
|
1 |
|
$class->addStmt($this->createMethod($factory, $type, $name, $details)); |
319
|
|
|
} |
320
|
|
|
|
321
|
1 |
|
$stmt = $factory->namespace($yaml['namespace']); |
322
|
1 |
|
if (isset($yaml['collection'])) { |
323
|
1 |
|
$stmt = $stmt->addStmt( |
324
|
1 |
|
$factory->use(Collection::class) |
325
|
|
|
); |
326
|
|
|
} |
327
|
1 |
|
if (isset($yaml['nested'])) { |
328
|
1 |
|
$stmt = $stmt->addStmt( |
329
|
1 |
|
$factory->use(Nested::class) |
330
|
|
|
); |
331
|
|
|
} |
332
|
1 |
|
if (isset($yaml['rename'])) { |
333
|
1 |
|
$stmt = $stmt->addStmt( |
334
|
1 |
|
$factory->use(Rename::class) |
335
|
|
|
); |
336
|
|
|
} |
337
|
|
|
$stmt |
338
|
1 |
|
->addStmt($factory->use('WyriHaximus\ApiClient\Resource\TransportAwareTrait')) |
339
|
1 |
|
->addStmt($class) |
340
|
|
|
; |
341
|
|
|
|
342
|
1 |
|
$node = $stmt->getNode(); |
343
|
|
|
|
344
|
1 |
|
$prettyPrinter = new PrettyPrinter\Standard(); |
345
|
1 |
|
return $prettyPrinter->prettyPrintFile([ |
346
|
1 |
|
$node |
347
|
1 |
|
]) . PHP_EOL; |
348
|
|
|
} |
349
|
|
|
|
350
|
1 |
|
protected function createInterface(array $yaml): string |
351
|
|
|
{ |
352
|
1 |
|
$factory = new BuilderFactory; |
353
|
|
|
|
354
|
1 |
|
$class = $factory->interface($yaml['class'] . 'Interface') |
355
|
1 |
|
->extend('ResourceInterface'); |
356
|
|
|
|
357
|
1 |
|
foreach ($yaml['properties'] as $name => $details) { |
358
|
1 |
|
$type = $details; |
359
|
1 |
|
if (is_array($details)) { |
360
|
1 |
|
$type = $details['type']; |
361
|
|
|
} |
362
|
1 |
|
$class->addStmt($this->createMethod($factory, $type, $name, $details)); |
363
|
|
|
} |
364
|
|
|
|
365
|
1 |
|
$node = $factory->namespace($yaml['namespace']) |
366
|
1 |
|
->addStmt($factory->use(ResourceInterface::class)) |
367
|
1 |
|
->addStmt($class) |
368
|
1 |
|
->getNode() |
369
|
|
|
; |
370
|
|
|
|
371
|
1 |
|
$prettyPrinter = new PrettyPrinter\Standard(); |
372
|
1 |
|
return $prettyPrinter->prettyPrintFile([ |
373
|
1 |
|
$node |
374
|
1 |
|
]) . PHP_EOL; |
375
|
|
|
} |
376
|
|
|
|
377
|
1 |
|
protected function createProperty(BuilderFactory $factory, string $type, string $name, $details): Property |
378
|
|
|
{ |
379
|
1 |
|
$property = $factory->property($name) |
380
|
1 |
|
->makeProtected() |
381
|
1 |
|
->setDocComment('/** |
382
|
1 |
|
* @var ' . $type . ' |
383
|
1 |
|
*/'); |
384
|
1 |
|
if (isset($details['default'])) { |
385
|
1 |
|
$property->setDefault($details['default']); |
386
|
|
|
} |
387
|
|
|
|
388
|
1 |
|
return $property; |
389
|
|
|
} |
390
|
|
|
|
391
|
1 |
|
protected function createMethod(BuilderFactory $factory, string $type, string $name, $details): Method |
|
|
|
|
392
|
|
|
{ |
393
|
1 |
|
return $factory->method(Inflector::camelize($name)) |
394
|
1 |
|
->makePublic() |
395
|
1 |
|
->setReturnType($type) |
396
|
1 |
|
->setDocComment('/** |
397
|
1 |
|
* @return ' . $type . ' |
398
|
1 |
|
*/') |
399
|
1 |
|
->addStmt( |
400
|
1 |
|
new Node\Stmt\Return_( |
401
|
1 |
|
new Node\Expr\PropertyFetch( |
402
|
1 |
|
new Node\Expr\Variable('this'), |
403
|
|
|
$name |
404
|
|
|
) |
405
|
|
|
) |
406
|
|
|
); |
407
|
|
|
} |
408
|
|
|
|
409
|
1 |
|
protected function createExtendingClass(string $namespace, string $className, string $baseClass): string |
410
|
|
|
{ |
411
|
1 |
|
$factory = new BuilderFactory; |
412
|
|
|
|
413
|
1 |
|
$class = $factory->class($className) |
414
|
1 |
|
->extend('Base' . $className); |
415
|
|
|
|
416
|
1 |
|
$class->addStmt($factory->method('refresh') |
417
|
1 |
|
->makePublic() |
418
|
1 |
|
->setReturnType($className) |
419
|
1 |
|
->addStmt( |
420
|
1 |
|
new Node\Stmt\Return_( |
421
|
1 |
|
new Node\Expr\MethodCall( |
422
|
1 |
|
new Node\Expr\Variable('this'), |
423
|
1 |
|
'wait', |
424
|
|
|
[ |
|
|
|
|
425
|
1 |
|
new Node\Expr\MethodCall( |
426
|
1 |
|
new Node\Expr\Variable('this'), |
427
|
1 |
|
'callAsync', |
428
|
|
|
[ |
|
|
|
|
429
|
1 |
|
new Node\Scalar\String_('refresh'), |
430
|
|
|
] |
431
|
|
|
), |
432
|
|
|
] |
433
|
|
|
) |
434
|
|
|
) |
435
|
|
|
)); |
436
|
|
|
|
437
|
1 |
|
$node = $factory->namespace($namespace) |
438
|
1 |
|
->addStmt($factory->use($baseClass)->as('Base' . $className)) |
439
|
1 |
|
->addStmt($class) |
440
|
|
|
|
441
|
1 |
|
->getNode() |
442
|
|
|
; |
443
|
|
|
|
444
|
1 |
|
$prettyPrinter = new PrettyPrinter\Standard(); |
445
|
1 |
|
return $prettyPrinter->prettyPrintFile([ |
446
|
1 |
|
$node |
447
|
1 |
|
]) . PHP_EOL; |
448
|
|
|
} |
449
|
|
|
|
450
|
1 |
|
protected function save(string $directory, string $fileName, string $fileContents) |
451
|
|
|
{ |
452
|
1 |
|
$fileName = str_replace('\\', DIRECTORY_SEPARATOR, $fileName); |
453
|
1 |
|
if (file_exists($directory . $fileName)) { |
454
|
|
|
$this->stdio->outln(', exists!'); |
455
|
|
|
return; |
456
|
|
|
} |
457
|
|
|
|
458
|
1 |
|
$path = $directory . $fileName; |
459
|
1 |
|
$pathChunks = explode(DIRECTORY_SEPARATOR, $path); |
460
|
1 |
|
array_pop($pathChunks); |
461
|
1 |
|
$path = implode(DIRECTORY_SEPARATOR, $pathChunks); |
462
|
1 |
|
if (!file_exists($path)) { |
463
|
1 |
|
mkdir($path, 0777, true); |
464
|
|
|
} |
465
|
|
|
|
466
|
1 |
|
if (!file_exists($path)) { |
467
|
|
|
throw new Exception('Unable to create: ' . $path); |
468
|
|
|
} |
469
|
|
|
|
470
|
1 |
|
$this->stdio->out(', writing'); |
471
|
1 |
|
file_put_contents($directory . $fileName, $fileContents); |
472
|
|
|
|
473
|
|
|
do { |
474
|
1 |
|
usleep(500); |
475
|
1 |
|
} while (!file_exists($directory . $fileName)); |
476
|
|
|
|
477
|
1 |
|
$this->stdio->out(', applying PSR-2'); |
478
|
1 |
|
$this->applyPsr2($directory . $fileName); |
479
|
1 |
|
$this->stdio->outln(', done!'); |
480
|
1 |
|
} |
481
|
|
|
|
482
|
|
|
/** |
483
|
|
|
* @param string $fileName |
484
|
|
|
*/ |
485
|
1 |
|
protected function applyPsr2($fileName) |
486
|
|
|
{ |
487
|
1 |
|
$file = new \SplFileInfo($fileName); |
488
|
1 |
|
$this->fixer->fixFile( |
489
|
|
|
$file, |
490
|
1 |
|
$this->fixers, |
491
|
1 |
|
false, |
492
|
1 |
|
false, |
493
|
1 |
|
new FileCacheManager( |
494
|
1 |
|
false, |
495
|
1 |
|
'', |
496
|
1 |
|
$this->fixers |
497
|
|
|
) |
498
|
|
|
); |
499
|
|
|
|
500
|
1 |
|
file_put_contents( |
501
|
|
|
$fileName, |
502
|
|
|
str_replace( |
503
|
1 |
|
'<?php', |
504
|
1 |
|
'<?php declare(strict_types=1);', |
505
|
|
|
file_get_contents( |
506
|
|
|
$fileName |
507
|
|
|
) |
508
|
|
|
) |
509
|
|
|
); |
510
|
1 |
|
} |
511
|
|
|
|
512
|
|
|
|
513
|
|
|
/** |
514
|
|
|
* @param ConfigInterface $config |
515
|
|
|
* |
516
|
|
|
* @return FixerInterface[] |
517
|
|
|
*/ |
518
|
2 |
|
private function prepareFixers(ConfigInterface $config): array |
519
|
|
|
{ |
520
|
2 |
|
$fixers = $config->getFixers(); |
521
|
|
|
|
522
|
2 |
|
foreach ($fixers as $fixer) { |
523
|
2 |
|
if ($fixer instanceof ConfigAwareInterface) { |
524
|
2 |
|
$fixer->setConfig($config); |
525
|
|
|
} |
526
|
|
|
} |
527
|
|
|
|
528
|
2 |
|
return $fixers; |
529
|
|
|
} |
530
|
|
|
} |
531
|
|
|
|
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.