Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like CommandConfig often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use CommandConfig, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
97 | class CommandConfig extends Config |
||
98 | { |
||
99 | /** |
||
100 | * @var string |
||
101 | */ |
||
102 | private $name; |
||
103 | |||
104 | /** |
||
105 | * @var ApplicationConfig |
||
106 | */ |
||
107 | private $applicationConfig; |
||
108 | |||
109 | /** |
||
110 | * @var string[] |
||
111 | */ |
||
112 | private $aliases = array(); |
||
113 | |||
114 | /** |
||
115 | * @var string |
||
116 | */ |
||
117 | private $description; |
||
118 | |||
119 | /** |
||
120 | * @var string |
||
121 | */ |
||
122 | private $help; |
||
123 | |||
124 | /** |
||
125 | * @var bool |
||
126 | */ |
||
127 | private $enabled = true; |
||
128 | |||
129 | /** |
||
130 | * @var string |
||
131 | */ |
||
132 | private $processTitle; |
||
133 | |||
134 | /** |
||
135 | * @var bool |
||
136 | */ |
||
137 | private $default = false; |
||
138 | |||
139 | /** |
||
140 | * @var bool |
||
141 | */ |
||
142 | private $anonymous = false; |
||
143 | |||
144 | /** |
||
145 | * @var SubCommandConfig[] |
||
146 | */ |
||
147 | private $subCommandConfigs = array(); |
||
148 | |||
149 | /** |
||
150 | * Creates a new configuration. |
||
151 | * |
||
152 | * @param string $name The name of the command. |
||
|
|||
153 | * @param ApplicationConfig $applicationConfig The application configuration. |
||
154 | * |
||
155 | * @return static The created configuration. |
||
156 | */ |
||
157 | 31 | public static function create($name = null, ApplicationConfig $applicationConfig = null) |
|
161 | |||
162 | /** |
||
163 | * Creates a new configuration. |
||
164 | * |
||
165 | * @param string $name The name of the command. |
||
166 | * @param ApplicationConfig $applicationConfig The application configuration. |
||
167 | */ |
||
168 | 359 | public function __construct($name = null, ApplicationConfig $applicationConfig = null) |
|
169 | { |
||
170 | 359 | $this->applicationConfig = $applicationConfig; |
|
171 | |||
172 | 359 | parent::__construct(); |
|
173 | |||
174 | 359 | if ($name) { |
|
175 | 322 | $this->setName($name); |
|
176 | } |
||
177 | 359 | } |
|
178 | |||
179 | /** |
||
180 | * Returns the name of the command. |
||
181 | * |
||
182 | * @return string The name of the command. |
||
183 | */ |
||
184 | 256 | public function getName() |
|
188 | |||
189 | /** |
||
190 | * Sets the name of the command. |
||
191 | * |
||
192 | * @param string $name The name of the command. |
||
193 | * |
||
194 | * @return static The current instance. |
||
195 | */ |
||
196 | 329 | public function setName($name) |
|
197 | { |
||
198 | 329 | if (null !== $name) { |
|
199 | 329 | Assert::string($name, 'The command name must be a string or null. Got: %s'); |
|
200 | 329 | Assert::notEmpty($name, 'The command name must not be empty.'); |
|
201 | 329 | Assert::regex($name, '~^[a-zA-Z0-9\-]+$~', 'The command name should contain letters, digits and hyphens only. Got: %s'); |
|
202 | } |
||
203 | |||
204 | 329 | $this->name = $name; |
|
205 | |||
206 | 329 | return $this; |
|
207 | } |
||
208 | |||
209 | /** |
||
210 | * Returns the application configuration. |
||
211 | * |
||
212 | * @return ApplicationConfig The application configuration. |
||
213 | */ |
||
214 | 55 | public function getApplicationConfig() |
|
218 | |||
219 | /** |
||
220 | * Sets the application configuration. |
||
221 | * |
||
222 | * @param ApplicationConfig $applicationConfig The application configuration. |
||
223 | */ |
||
224 | 30 | public function setApplicationConfig($applicationConfig) |
|
228 | |||
229 | /** |
||
230 | * Ends the block when dynamically configuring a command configuration. |
||
231 | * |
||
232 | * This method is usually used together with |
||
233 | * {@link ApplicationConfig::beginCommand()}: |
||
234 | * |
||
235 | * ```php |
||
236 | * $config |
||
237 | * ->beginCommand('command') |
||
238 | * // ... |
||
239 | * ->end() |
||
240 | * |
||
241 | * // ... |
||
242 | * ; |
||
243 | * ``` |
||
244 | * |
||
245 | * @return ApplicationConfig The application configuration. |
||
246 | */ |
||
247 | 109 | public function end() |
|
251 | |||
252 | /** |
||
253 | * Returns the alias names of the command. |
||
254 | * |
||
255 | * @return string[] An array of alias names of the command. |
||
256 | * |
||
257 | * @see addAlias(), setAliases() |
||
258 | */ |
||
259 | 241 | public function getAliases() |
|
263 | |||
264 | /** |
||
265 | * Adds an alias name. |
||
266 | * |
||
267 | * An alias is an alternative name that can be used when calling the |
||
268 | * command. Aliases are a useful way for migrating a command from one name |
||
269 | * to another. |
||
270 | * |
||
271 | * Existing alias names are preserved. |
||
272 | * |
||
273 | * @param string $alias The alias name to add. |
||
274 | * |
||
275 | * @return static The current instance. |
||
276 | * |
||
277 | * @see addAliases(), setAliases(), getAlias() |
||
278 | */ |
||
279 | 58 | public function addAlias($alias) |
|
280 | { |
||
281 | 58 | Assert::string($alias, 'The command alias must be a string. Got: %s'); |
|
282 | 49 | Assert::notEmpty($alias, 'The command alias must not be empty.'); |
|
283 | 45 | Assert::regex($alias, '~^[a-zA-Z0-9\-]+$~', 'The command alias should contain letters, digits and hyphens only. Got: %s'); |
|
284 | |||
285 | 41 | $this->aliases[] = $alias; |
|
286 | |||
287 | 41 | return $this; |
|
288 | } |
||
289 | |||
290 | /** |
||
291 | * Adds a list of alias names. |
||
292 | * |
||
293 | * Existing alias names are preserved. |
||
294 | * |
||
295 | * @param array $aliases The alias names to add. |
||
296 | * |
||
297 | * @return static The current instance. |
||
298 | * |
||
299 | * @see addAlias(), setAliases(), getAlias() |
||
300 | */ |
||
301 | 12 | public function addAliases(array $aliases) |
|
302 | { |
||
303 | 12 | foreach ($aliases as $alias) { |
|
304 | 12 | $this->addAlias($alias); |
|
305 | } |
||
306 | |||
307 | 6 | return $this; |
|
308 | } |
||
309 | |||
310 | /** |
||
311 | * Sets the alias names of the command. |
||
312 | * |
||
313 | * Existing alias names are replaced. |
||
314 | * |
||
315 | * @param array $aliases The alias names. |
||
316 | * |
||
317 | * @return static The current instance. |
||
318 | * |
||
319 | * @see addAlias(), addAliases(), getAlias() |
||
320 | */ |
||
321 | 8 | public function setAliases(array $aliases) |
|
322 | { |
||
323 | 8 | $this->aliases = array(); |
|
324 | |||
325 | 8 | $this->addAliases($aliases); |
|
326 | |||
327 | 5 | return $this; |
|
328 | } |
||
329 | |||
330 | /** |
||
331 | * Returns the description of the command. |
||
332 | * |
||
333 | * @return string The description of the command. |
||
334 | * |
||
335 | * @see setDescription() |
||
336 | */ |
||
337 | 40 | public function getDescription() |
|
341 | |||
342 | /** |
||
343 | * Sets the description of the command. |
||
344 | * |
||
345 | * The description is a short one-liner that describes the command in the |
||
346 | * command listing. The description should be written in imperative form |
||
347 | * rather than in descriptive form. So: |
||
348 | * |
||
349 | * > List the contents of a directory. |
||
350 | * |
||
351 | * should be preferred over |
||
352 | * |
||
353 | * > Lists the contents of a directory. |
||
354 | * |
||
355 | * @param string $description The description. |
||
356 | * |
||
357 | * @return static The current instance. |
||
358 | * |
||
359 | * @see getDescription() |
||
360 | */ |
||
361 | 92 | View Code Duplication | public function setDescription($description) |
362 | { |
||
363 | 92 | if (null !== $description) { |
|
364 | 91 | Assert::string($description, 'The command description must be a string or null. Got: %s'); |
|
365 | 90 | Assert::notEmpty($description, 'The command description must not be empty.'); |
|
366 | } |
||
367 | |||
368 | 90 | $this->description = $description; |
|
369 | |||
370 | 90 | return $this; |
|
371 | } |
||
372 | |||
373 | /** |
||
374 | * Returns the help text of the command. |
||
375 | * |
||
376 | * The help text provides additional information about a command that is |
||
377 | * displayed in the help view. |
||
378 | * |
||
379 | * @return string The help text of the command. |
||
380 | * |
||
381 | * @see setHelp() |
||
382 | */ |
||
383 | 46 | public function getHelp() |
|
387 | |||
388 | /** |
||
389 | * Sets the help text of the command. |
||
390 | * |
||
391 | * The help text provides additional information about a command that is |
||
392 | * displayed in the help view. |
||
393 | * |
||
394 | * @param string $help The help text of the command. |
||
395 | * |
||
396 | * @return static The current instance. |
||
397 | * |
||
398 | * @see getHelp() |
||
399 | */ |
||
400 | 6 | View Code Duplication | public function setHelp($help) |
401 | { |
||
402 | 6 | if (null !== $help) { |
|
403 | 5 | Assert::string($help, 'The help text must be a string or null. Got: %s'); |
|
404 | 4 | Assert::notEmpty($help, 'The help text must not be empty.'); |
|
405 | } |
||
406 | |||
407 | 4 | $this->help = $help; |
|
408 | |||
409 | 4 | return $this; |
|
410 | } |
||
411 | |||
412 | /** |
||
413 | * Returns whether the command is enabled or not in the current environment. |
||
414 | * |
||
415 | * @return bool Returns `true` if the command is currently enabled and |
||
416 | * `false` otherwise. |
||
417 | * |
||
418 | * @see enable(), disable(), enableIf(), disableIf() |
||
419 | */ |
||
420 | 147 | public function isEnabled() |
|
424 | |||
425 | /** |
||
426 | * Enables the command. |
||
427 | * |
||
428 | * @return static The current instance. |
||
429 | * |
||
430 | * @see enableIf(), disable(), isEnabled() |
||
431 | */ |
||
432 | 3 | public function enable() |
|
433 | { |
||
434 | 3 | $this->enabled = true; |
|
435 | |||
436 | 3 | return $this; |
|
437 | } |
||
438 | |||
439 | /** |
||
440 | * Enables the command if a condition holds and disables it otherwise. |
||
441 | * |
||
442 | * @param bool $condition The condition under which to enable the command. |
||
443 | * |
||
444 | * @return static The current instance. |
||
445 | * |
||
446 | * @see enable(), disable(), isEnabled() |
||
447 | */ |
||
448 | 1 | public function enableIf($condition) |
|
449 | { |
||
450 | 1 | $this->enabled = (bool) $condition; |
|
451 | |||
452 | 1 | return $this; |
|
453 | } |
||
454 | |||
455 | /** |
||
456 | * Disables the command. |
||
457 | * |
||
458 | * @return static The current instance. |
||
459 | * |
||
460 | * @see disableIf(), enable(), isEnabled() |
||
461 | */ |
||
462 | 5 | public function disable() |
|
463 | { |
||
464 | 5 | $this->enabled = false; |
|
465 | |||
466 | 5 | return $this; |
|
467 | } |
||
468 | |||
469 | /** |
||
470 | * Disables the command if a condition holds and enables it otherwise. |
||
471 | * |
||
472 | * @param bool $condition The condition under which to disable the command. |
||
473 | * |
||
474 | * @return static The current instance. |
||
475 | * |
||
476 | * @see disable(), enable(), isEnabled() |
||
477 | */ |
||
478 | 1 | public function disableIf($condition) |
|
479 | { |
||
480 | 1 | $this->enabled = !$condition; |
|
481 | |||
482 | 1 | return $this; |
|
483 | } |
||
484 | |||
485 | /** |
||
486 | * Returns the title of the command process. |
||
487 | * |
||
488 | * @return string|null The process title or `null` if no title should be |
||
489 | * set. |
||
490 | * |
||
491 | * @see setProcessTitle() |
||
492 | */ |
||
493 | 54 | public function getProcessTitle() |
|
497 | |||
498 | /** |
||
499 | * Sets the title of the command process. |
||
500 | * |
||
501 | * @param string|null $processTitle The process title or `null` if no title |
||
502 | * should be set. |
||
503 | * |
||
504 | * @return static The current instance. |
||
505 | * |
||
506 | * @see getProcessTitle() |
||
507 | */ |
||
508 | 4 | public function setProcessTitle($processTitle) |
|
509 | { |
||
510 | 4 | if (null !== $processTitle) { |
|
511 | 3 | Assert::string($processTitle, 'The command process title must be a string or null. Got: %s'); |
|
512 | 2 | Assert::notEmpty($processTitle, 'The command process title must not be empty.'); |
|
513 | } |
||
514 | |||
515 | 2 | $this->processTitle = $processTitle; |
|
516 | |||
517 | 2 | return $this; |
|
518 | } |
||
519 | |||
520 | /** |
||
521 | * Marks the command as default command. |
||
522 | * |
||
523 | * The names of default commands can be omitted when calling the command. |
||
524 | * For example, the following command can be called in two ways: |
||
525 | * |
||
526 | * ```php |
||
527 | * protected function configure() |
||
528 | * { |
||
529 | * $this |
||
530 | * ->beginCommand('add') |
||
531 | * ->markDefault() |
||
532 | * ->addArgument('host', Argument::REQUIRED) |
||
533 | * ->end() |
||
534 | * |
||
535 | * // ... |
||
536 | * ; |
||
537 | * } |
||
538 | * ``` |
||
539 | * |
||
540 | * The first way is to call the command regularly. The second way is to |
||
541 | * omit the name of the command: |
||
542 | * |
||
543 | * ```php |
||
544 | * $ ./console add localhost |
||
545 | * $ ./console localhost |
||
546 | * ``` |
||
547 | * |
||
548 | * @return static The current instance. |
||
549 | * |
||
550 | * @see markAnonymous(), markNoDefault() |
||
551 | */ |
||
552 | 90 | public function markDefault() |
|
553 | { |
||
554 | 90 | $this->default = true; |
|
555 | 90 | $this->anonymous = false; |
|
556 | |||
557 | 90 | return $this; |
|
558 | } |
||
559 | |||
560 | /** |
||
561 | * Marks the command as anonymous command. |
||
562 | * |
||
563 | * Anonymous commands cannot be called by name: |
||
564 | * |
||
565 | * ```php |
||
566 | * protected function configure() |
||
567 | * { |
||
568 | * $this |
||
569 | * ->beginCommand('add') |
||
570 | * ->markAnonymous() |
||
571 | * ->addArgument('host', Argument::REQUIRED) |
||
572 | * ->end() |
||
573 | * |
||
574 | * // ... |
||
575 | * ; |
||
576 | * } |
||
577 | * ``` |
||
578 | * |
||
579 | * The name "add" is given to the command only to access the command later |
||
580 | * on. Since the command is anonymous, the name cannot be passed when |
||
581 | * when calling the command: |
||
582 | * |
||
583 | * ```php |
||
584 | * $ ./console add localhost |
||
585 | * ``` |
||
586 | * |
||
587 | * Instead, the command should be called without name: |
||
588 | * |
||
589 | * ```php |
||
590 | * $ ./console localhost |
||
591 | * ``` |
||
592 | * |
||
593 | * @return static The current instance. |
||
594 | * |
||
595 | * @see markDefault(), markNoDefault() |
||
596 | */ |
||
597 | 10 | public function markAnonymous() |
|
598 | { |
||
599 | 10 | $this->default = true; |
|
600 | 10 | $this->anonymous = true; |
|
601 | |||
602 | 10 | return $this; |
|
603 | } |
||
604 | |||
605 | /** |
||
606 | * Marks the command as neither anonymous nor default. |
||
607 | * |
||
608 | * @return static The current instance. |
||
609 | * |
||
610 | * @see markDefault(), markAnonymous() |
||
611 | */ |
||
612 | 1 | public function markNoDefault() |
|
613 | { |
||
614 | 1 | $this->default = false; |
|
615 | 1 | $this->anonymous = false; |
|
616 | |||
617 | 1 | return $this; |
|
618 | } |
||
619 | |||
620 | /** |
||
621 | * Returns whether the command is a default command. |
||
622 | * |
||
623 | * @return bool Returns `true` if either {@link markDefault()} or |
||
624 | * {@link markAnonymous()} was called and `false` otherwise. |
||
625 | */ |
||
626 | 140 | public function isDefault() |
|
630 | |||
631 | /** |
||
632 | * Returns whether the command is anonymous. |
||
633 | * |
||
634 | * @return bool Returns `true` if {@link markAnonymous()} was called and |
||
635 | * `false` otherwise. |
||
636 | */ |
||
637 | 147 | public function isAnonymous() |
|
641 | |||
642 | /** |
||
643 | * Builds an {@link ArgsFormat} instance with the given base format. |
||
644 | * |
||
645 | * @param ArgsFormat $baseFormat The base format. |
||
646 | * |
||
647 | * @return ArgsFormat The built format for the console arguments. |
||
648 | */ |
||
649 | 227 | public function buildArgsFormat(ArgsFormat $baseFormat = null) |
|
650 | { |
||
651 | 227 | $formatBuilder = ArgsFormat::build($baseFormat); |
|
652 | |||
653 | 227 | if (!$this->anonymous) { |
|
654 | 225 | $formatBuilder->addCommandName(new CommandName($this->name, $this->aliases)); |
|
655 | } |
||
656 | |||
657 | 227 | $formatBuilder->addOptions($this->getOptions()); |
|
658 | 227 | $formatBuilder->addArguments($this->getArguments()); |
|
659 | |||
660 | 227 | return $formatBuilder->getFormat(); |
|
661 | } |
||
662 | |||
663 | /** |
||
664 | * Starts a configuration block for a sub-command. |
||
665 | * |
||
666 | * A sub-command is executed if the name of the command is passed after the |
||
667 | * name of the containing command. For example, if the command "server" has |
||
668 | * a sub-command command named "add", that command can be called with: |
||
669 | * |
||
670 | * ``` |
||
671 | * $ console server add ... |
||
672 | * ``` |
||
673 | * |
||
674 | * The configuration of the sub-command is returned by this method. You can |
||
675 | * use the fluent interface to configure the sub-command before jumping back |
||
676 | * to this configuration with {@link SubCommandConfig::end()}: |
||
677 | * |
||
678 | * ```php |
||
679 | * protected function configure() |
||
680 | * { |
||
681 | * $this |
||
682 | * ->beginCommand('server') |
||
683 | * ->setDescription('List and manage servers') |
||
684 | * |
||
685 | * ->beginSubCommand('add') |
||
686 | * ->setDescription('Add a server') |
||
687 | * ->addArgument('host', Argument::REQUIRED) |
||
688 | * ->addOption('port', 'p', Option::VALUE_OPTIONAL, null, 80) |
||
689 | * ->end() |
||
690 | * ->end() |
||
691 | * |
||
692 | * // ... |
||
693 | * ; |
||
694 | * } |
||
695 | * ``` |
||
696 | * |
||
697 | * @param string $name The name of the sub-command. |
||
698 | * |
||
699 | * @return SubCommandConfig The sub-command configuration. |
||
700 | * |
||
701 | * @see editSubCommand() |
||
702 | */ |
||
703 | 7 | public function beginSubCommand($name) |
|
704 | { |
||
705 | 7 | $config = new SubCommandConfig($name, $this); |
|
706 | |||
707 | // The name is dynamic, so don't store by name |
||
708 | 7 | $this->subCommandConfigs[] = $config; |
|
709 | |||
710 | 7 | return $config; |
|
711 | } |
||
712 | |||
713 | /** |
||
714 | * Alias for {@link getSubCommandConfig()}. |
||
715 | * |
||
716 | * This method can be used to nicely edit a sub-command inherited from a |
||
717 | * parent configuration using the fluent API: |
||
718 | * |
||
719 | * ```php |
||
720 | * protected function configure() |
||
721 | * { |
||
722 | * parent::configure(); |
||
723 | * |
||
724 | * $this |
||
725 | * ->editCommand('server') |
||
726 | * ->editSubCommand('add') |
||
727 | * // ... |
||
728 | * ->end() |
||
729 | * ->end() |
||
730 | * |
||
731 | * // ... |
||
732 | * ; |
||
733 | * } |
||
734 | * ``` |
||
735 | * |
||
736 | * @param string $name The name of the sub-command to edit. |
||
737 | * |
||
738 | * @return SubCommandConfig The sub-command configuration. |
||
739 | * |
||
740 | * @see beginSubCommand() |
||
741 | */ |
||
742 | 1 | public function editSubCommand($name) |
|
746 | |||
747 | /** |
||
748 | * Starts a configuration block for an option command. |
||
749 | * |
||
750 | * An option command is executed if the corresponding option is passed after |
||
751 | * the command name. For example, if the command "server" has an option |
||
752 | * command named "--add" with the short name "-a", that command can be |
||
753 | * called with: |
||
754 | * |
||
755 | * ``` |
||
756 | * $ console server --add ... |
||
757 | * $ console server -a ... |
||
758 | * ``` |
||
759 | * |
||
760 | * The configuration of the option command is returned by this method. |
||
761 | * You can use the fluent interface to configure the option command |
||
762 | * before jumping back to this configuration with |
||
763 | * {@link SubCommandConfig::end()}: |
||
764 | * |
||
765 | * ```php |
||
766 | * protected function configure() |
||
767 | * { |
||
768 | * $this |
||
769 | * ->beginCommand('server') |
||
770 | * ->setDescription('List and manage servers') |
||
771 | * |
||
772 | * ->beginOptionCommand('add', 'a') |
||
773 | * ->setDescription('Add a server') |
||
774 | * ->addArgument('host', Argument::REQUIRED) |
||
775 | * ->addOption('port', 'p', Option::VALUE_OPTIONAL, null, 80) |
||
776 | * ->end() |
||
777 | * ->end() |
||
778 | * |
||
779 | * // ... |
||
780 | * ; |
||
781 | * } |
||
782 | * ``` |
||
783 | * |
||
784 | * @param string $name The name of the option command. |
||
785 | * @param string $shortName The short name of the option command. |
||
786 | * |
||
787 | * @return OptionCommandConfig The option command configuration. |
||
788 | * |
||
789 | * @see editOptionCommand() |
||
790 | */ |
||
791 | 7 | public function beginOptionCommand($name, $shortName = null) |
|
792 | { |
||
793 | 7 | $config = new OptionCommandConfig($name, $shortName, $this); |
|
794 | |||
795 | // The name is dynamic, so don't store by name |
||
796 | 7 | $this->subCommandConfigs[] = $config; |
|
797 | |||
798 | 7 | return $config; |
|
799 | } |
||
800 | |||
801 | /** |
||
802 | * Alias for {@link getSubCommandConfig()}. |
||
803 | * |
||
804 | * This method can be used to nicely edit an option command inherited from a |
||
805 | * parent configuration using the fluent API: |
||
806 | * |
||
807 | * ```php |
||
808 | * protected function configure() |
||
809 | * { |
||
810 | * parent::configure(); |
||
811 | * |
||
812 | * $this |
||
813 | * ->editCommand('server') |
||
814 | * ->editOptionCommand('add') |
||
815 | * // ... |
||
816 | * ->end() |
||
817 | * ->end() |
||
818 | * |
||
819 | * // ... |
||
820 | * ; |
||
821 | * } |
||
822 | * ``` |
||
823 | * |
||
824 | * @param string $name The name of the option command to edit. |
||
825 | * |
||
826 | * @return OptionCommandConfig The option command configuration. |
||
827 | * |
||
828 | * @see beginOptionCommand() |
||
829 | */ |
||
830 | 1 | public function editOptionCommand($name) |
|
834 | |||
835 | /** |
||
836 | * Adds configuration for a sub-command. |
||
837 | * |
||
838 | * @param SubCommandConfig $config The sub-command configuration. |
||
839 | * |
||
840 | * @return static The current instance. |
||
841 | * |
||
842 | * @see beginSubCommand() |
||
843 | */ |
||
844 | 28 | public function addSubCommandConfig(SubCommandConfig $config) |
|
845 | { |
||
846 | // The name is dynamic, so don't store by name |
||
847 | 28 | $this->subCommandConfigs[] = $config; |
|
848 | |||
849 | 28 | $config->setParentConfig($this); |
|
850 | |||
851 | 28 | return $this; |
|
852 | } |
||
853 | |||
854 | /** |
||
855 | * Adds sub-command configurations to the command. |
||
856 | * |
||
857 | * @param SubCommandConfig[] $configs The sub-command configurations. |
||
858 | * |
||
859 | * @return static The current instance. |
||
860 | * |
||
861 | * @see beginSubCommand() |
||
862 | */ |
||
863 | 2 | public function addSubCommandConfigs(array $configs) |
|
864 | { |
||
865 | 2 | foreach ($configs as $command) { |
|
866 | 2 | $this->addSubCommandConfig($command); |
|
867 | } |
||
868 | |||
869 | 2 | return $this; |
|
870 | } |
||
871 | |||
872 | /** |
||
873 | * Sets the sub-command configurations of the command. |
||
874 | * |
||
875 | * @param SubCommandConfig[] $configs The sub-command configurations. |
||
876 | * |
||
877 | * @return static The current instance. |
||
878 | * |
||
879 | * @see beginSubCommand() |
||
880 | */ |
||
881 | 1 | public function setSubCommandConfigs(array $configs) |
|
882 | { |
||
883 | 1 | $this->subCommandConfigs = array(); |
|
884 | |||
885 | 1 | $this->addSubCommandConfigs($configs); |
|
886 | |||
887 | 1 | return $this; |
|
888 | } |
||
889 | |||
890 | /** |
||
891 | * Returns the sub-command configuration for a given name. |
||
892 | * |
||
893 | * @param string $name The name of the sub-command. |
||
894 | * |
||
895 | * @return SubCommandConfig The sub-command configuration. |
||
896 | * |
||
897 | * @throws NoSuchCommandException If the sub-command configuration is not |
||
898 | * found. |
||
899 | * |
||
900 | * @see beginSubCommand() |
||
901 | */ |
||
902 | 4 | public function getSubCommandConfig($name) |
|
903 | { |
||
904 | 4 | foreach ($this->subCommandConfigs as $commandConfig) { |
|
905 | 3 | if ($name === $commandConfig->getName()) { |
|
906 | 3 | return $commandConfig; |
|
907 | } |
||
908 | } |
||
909 | |||
910 | 1 | throw NoSuchCommandException::forCommandName($name); |
|
911 | } |
||
912 | |||
913 | /** |
||
914 | * Returns the configurations of all sub-commands. |
||
915 | * |
||
916 | * @return SubCommandConfig[] The sub-command configurations. |
||
917 | * |
||
918 | * @see beginSubCommand() |
||
919 | */ |
||
920 | 236 | public function getSubCommandConfigs() |
|
924 | |||
925 | /** |
||
926 | * Returns whether the command has a sub-command with a given name. |
||
927 | * |
||
928 | * @param string $name The name of the sub-command. |
||
929 | * |
||
930 | * @return bool Returns `true` if the sub-command configuration with the |
||
931 | * given name exists and `false` otherwise. |
||
932 | * |
||
933 | * @see beginSubCommand() |
||
934 | */ |
||
935 | 1 | public function hasSubCommandConfig($name) |
|
936 | { |
||
937 | 1 | foreach ($this->subCommandConfigs as $commandConfig) { |
|
938 | 1 | if ($name === $commandConfig->getName()) { |
|
939 | 1 | return true; |
|
940 | } |
||
941 | } |
||
942 | |||
943 | 1 | return false; |
|
944 | } |
||
945 | |||
946 | /** |
||
947 | * Returns whether the command has any registered sub-command configurations. |
||
948 | * |
||
949 | * @return bool Returns `true` if sub-command configurations were added to |
||
950 | * the command and `false` otherwise. |
||
951 | * |
||
952 | * @see beginSubCommand() |
||
953 | */ |
||
954 | 1 | public function hasSubCommandConfigs() |
|
958 | |||
959 | /** |
||
960 | * {@inheritdoc} |
||
961 | */ |
||
962 | 15 | protected function getDefaultHelperSet() |
|
963 | { |
||
964 | 15 | return $this->applicationConfig |
|
965 | 14 | ? $this->applicationConfig->getHelperSet() |
|
966 | 15 | : parent::getDefaultHelperSet(); |
|
967 | } |
||
968 | |||
969 | /** |
||
970 | * {@inheritdoc} |
||
971 | */ |
||
972 | 1 | protected function getDefaultHandler() |
|
973 | { |
||
974 | 1 | return $this->applicationConfig |
|
975 | 1 | ? $this->applicationConfig->getHandler() |
|
976 | 1 | : parent::getDefaultHandler(); |
|
977 | } |
||
978 | |||
979 | /** |
||
980 | * {@inheritdoc} |
||
981 | */ |
||
982 | 45 | protected function getDefaultHandlerMethod() |
|
983 | { |
||
988 | |||
989 | /** |
||
990 | * {@inheritdoc} |
||
991 | */ |
||
992 | 266 | protected function getDefaultArgsParser() |
|
998 | |||
999 | /** |
||
1000 | * {@inheritdoc} |
||
1001 | */ |
||
1002 | 259 | protected function getDefaultLenientArgsParsing() |
|
1008 | } |
||
1009 |
This check looks for
@param
annotations where the type inferred by our type inference engine differs from the declared type.It makes a suggestion as to what type it considers more descriptive.
Most often this is a case of a parameter that can be null in addition to its declared types.