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
@paramannotations 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.