Verzeichnisstruktur phpBB-3.1.0
- Veröffentlicht
- 27.10.2014
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
Command.php
001 <?php
002
003 /*
004 * This file is part of the Symfony package.
005 *
006 * (c) Fabien Potencier <fabien@symfony.com>
007 *
008 * For the full copyright and license information, please view the LICENSE
009 * file that was distributed with this source code.
010 */
011
012 namespace Symfony\Component\Console\Command;
013
014 use Symfony\Component\Console\Descriptor\TextDescriptor;
015 use Symfony\Component\Console\Descriptor\XmlDescriptor;
016 use Symfony\Component\Console\Input\InputDefinition;
017 use Symfony\Component\Console\Input\InputOption;
018 use Symfony\Component\Console\Input\InputArgument;
019 use Symfony\Component\Console\Input\InputInterface;
020 use Symfony\Component\Console\Output\OutputInterface;
021 use Symfony\Component\Console\Application;
022 use Symfony\Component\Console\Helper\HelperSet;
023
024 /**
025 * Base class for all commands.
026 *
027 * @author Fabien Potencier <fabien@symfony.com>
028 *
029 * @api
030 */
031 class Command
032 {
033 private $application;
034 private $name;
035 private $aliases;
036 private $definition;
037 private $help;
038 private $description;
039 private $ignoreValidationErrors;
040 private $applicationDefinitionMerged;
041 private $applicationDefinitionMergedWithArgs;
042 private $code;
043 private $synopsis;
044 private $helperSet;
045
046 /**
047 * Constructor.
048 *
049 * @param string $name The name of the command
050 *
051 * @throws \LogicException When the command name is empty
052 *
053 * @api
054 */
055 public function __construct($name = null)
056 {
057 $this->definition = new InputDefinition();
058 $this->ignoreValidationErrors = false;
059 $this->applicationDefinitionMerged = false;
060 $this->applicationDefinitionMergedWithArgs = false;
061 $this->aliases = array();
062
063 if (null !== $name) {
064 $this->setName($name);
065 }
066
067 $this->configure();
068
069 if (!$this->name) {
070 throw new \LogicException('The command name cannot be empty.');
071 }
072 }
073
074 /**
075 * Ignores validation errors.
076 *
077 * This is mainly useful for the help command.
078 */
079 public function ignoreValidationErrors()
080 {
081 $this->ignoreValidationErrors = true;
082 }
083
084 /**
085 * Sets the application instance for this command.
086 *
087 * @param Application $application An Application instance
088 *
089 * @api
090 */
091 public function setApplication(Application $application = null)
092 {
093 $this->application = $application;
094 if ($application) {
095 $this->setHelperSet($application->getHelperSet());
096 } else {
097 $this->helperSet = null;
098 }
099 }
100
101 /**
102 * Sets the helper set.
103 *
104 * @param HelperSet $helperSet A HelperSet instance
105 */
106 public function setHelperSet(HelperSet $helperSet)
107 {
108 $this->helperSet = $helperSet;
109 }
110
111 /**
112 * Gets the helper set.
113 *
114 * @return HelperSet A HelperSet instance
115 */
116 public function getHelperSet()
117 {
118 return $this->helperSet;
119 }
120
121 /**
122 * Gets the application instance for this command.
123 *
124 * @return Application An Application instance
125 *
126 * @api
127 */
128 public function getApplication()
129 {
130 return $this->application;
131 }
132
133 /**
134 * Checks whether the command is enabled or not in the current environment
135 *
136 * Override this to check for x or y and return false if the command can not
137 * run properly under the current conditions.
138 *
139 * @return bool
140 */
141 public function isEnabled()
142 {
143 return true;
144 }
145
146 /**
147 * Configures the current command.
148 */
149 protected function configure()
150 {
151 }
152
153 /**
154 * Executes the current command.
155 *
156 * This method is not abstract because you can use this class
157 * as a concrete class. In this case, instead of defining the
158 * execute() method, you set the code to execute by passing
159 * a Closure to the setCode() method.
160 *
161 * @param InputInterface $input An InputInterface instance
162 * @param OutputInterface $output An OutputInterface instance
163 *
164 * @return null|int null or 0 if everything went fine, or an error code
165 *
166 * @throws \LogicException When this abstract method is not implemented
167 * @see setCode()
168 */
169 protected function execute(InputInterface $input, OutputInterface $output)
170 {
171 throw new \LogicException('You must override the execute() method in the concrete command class.');
172 }
173
174 /**
175 * Interacts with the user.
176 *
177 * @param InputInterface $input An InputInterface instance
178 * @param OutputInterface $output An OutputInterface instance
179 */
180 protected function interact(InputInterface $input, OutputInterface $output)
181 {
182 }
183
184 /**
185 * Initializes the command just after the input has been validated.
186 *
187 * This is mainly useful when a lot of commands extends one main command
188 * where some things need to be initialized based on the input arguments and options.
189 *
190 * @param InputInterface $input An InputInterface instance
191 * @param OutputInterface $output An OutputInterface instance
192 */
193 protected function initialize(InputInterface $input, OutputInterface $output)
194 {
195 }
196
197 /**
198 * Runs the command.
199 *
200 * The code to execute is either defined directly with the
201 * setCode() method or by overriding the execute() method
202 * in a sub-class.
203 *
204 * @param InputInterface $input An InputInterface instance
205 * @param OutputInterface $output An OutputInterface instance
206 *
207 * @return int The command exit code
208 *
209 * @throws \Exception
210 *
211 * @see setCode()
212 * @see execute()
213 *
214 * @api
215 */
216 public function run(InputInterface $input, OutputInterface $output)
217 {
218 // force the creation of the synopsis before the merge with the app definition
219 $this->getSynopsis();
220
221 // add the application arguments and options
222 $this->mergeApplicationDefinition();
223
224 // bind the input against the command specific arguments/options
225 try {
226 $input->bind($this->definition);
227 } catch (\Exception $e) {
228 if (!$this->ignoreValidationErrors) {
229 throw $e;
230 }
231 }
232
233 $this->initialize($input, $output);
234
235 if ($input->isInteractive()) {
236 $this->interact($input, $output);
237 }
238
239 $input->validate();
240
241 if ($this->code) {
242 $statusCode = call_user_func($this->code, $input, $output);
243 } else {
244 $statusCode = $this->execute($input, $output);
245 }
246
247 return is_numeric($statusCode) ? (int) $statusCode : 0;
248 }
249
250 /**
251 * Sets the code to execute when running this command.
252 *
253 * If this method is used, it overrides the code defined
254 * in the execute() method.
255 *
256 * @param callable $code A callable(InputInterface $input, OutputInterface $output)
257 *
258 * @return Command The current instance
259 *
260 * @throws \InvalidArgumentException
261 *
262 * @see execute()
263 *
264 * @api
265 */
266 public function setCode($code)
267 {
268 if (!is_callable($code)) {
269 throw new \InvalidArgumentException('Invalid callable provided to Command::setCode.');
270 }
271
272 $this->code = $code;
273
274 return $this;
275 }
276
277 /**
278 * Merges the application definition with the command definition.
279 *
280 * This method is not part of public API and should not be used directly.
281 *
282 * @param bool $mergeArgs Whether to merge or not the Application definition arguments to Command definition arguments
283 */
284 public function mergeApplicationDefinition($mergeArgs = true)
285 {
286 if (null === $this->application || (true === $this->applicationDefinitionMerged && ($this->applicationDefinitionMergedWithArgs || !$mergeArgs))) {
287 return;
288 }
289
290 if ($mergeArgs) {
291 $currentArguments = $this->definition->getArguments();
292 $this->definition->setArguments($this->application->getDefinition()->getArguments());
293 $this->definition->addArguments($currentArguments);
294 }
295
296 $this->definition->addOptions($this->application->getDefinition()->getOptions());
297
298 $this->applicationDefinitionMerged = true;
299 if ($mergeArgs) {
300 $this->applicationDefinitionMergedWithArgs = true;
301 }
302 }
303
304 /**
305 * Sets an array of argument and option instances.
306 *
307 * @param array|InputDefinition $definition An array of argument and option instances or a definition instance
308 *
309 * @return Command The current instance
310 *
311 * @api
312 */
313 public function setDefinition($definition)
314 {
315 if ($definition instanceof InputDefinition) {
316 $this->definition = $definition;
317 } else {
318 $this->definition->setDefinition($definition);
319 }
320
321 $this->applicationDefinitionMerged = false;
322
323 return $this;
324 }
325
326 /**
327 * Gets the InputDefinition attached to this Command.
328 *
329 * @return InputDefinition An InputDefinition instance
330 *
331 * @api
332 */
333 public function getDefinition()
334 {
335 return $this->definition;
336 }
337
338 /**
339 * Gets the InputDefinition to be used to create XML and Text representations of this Command.
340 *
341 * Can be overridden to provide the original command representation when it would otherwise
342 * be changed by merging with the application InputDefinition.
343 *
344 * This method is not part of public API and should not be used directly.
345 *
346 * @return InputDefinition An InputDefinition instance
347 */
348 public function getNativeDefinition()
349 {
350 return $this->getDefinition();
351 }
352
353 /**
354 * Adds an argument.
355 *
356 * @param string $name The argument name
357 * @param int $mode The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL
358 * @param string $description A description text
359 * @param mixed $default The default value (for InputArgument::OPTIONAL mode only)
360 *
361 * @return Command The current instance
362 *
363 * @api
364 */
365 public function addArgument($name, $mode = null, $description = '', $default = null)
366 {
367 $this->definition->addArgument(new InputArgument($name, $mode, $description, $default));
368
369 return $this;
370 }
371
372 /**
373 * Adds an option.
374 *
375 * @param string $name The option name
376 * @param string $shortcut The shortcut (can be null)
377 * @param int $mode The option mode: One of the InputOption::VALUE_* constants
378 * @param string $description A description text
379 * @param mixed $default The default value (must be null for InputOption::VALUE_REQUIRED or InputOption::VALUE_NONE)
380 *
381 * @return Command The current instance
382 *
383 * @api
384 */
385 public function addOption($name, $shortcut = null, $mode = null, $description = '', $default = null)
386 {
387 $this->definition->addOption(new InputOption($name, $shortcut, $mode, $description, $default));
388
389 return $this;
390 }
391
392 /**
393 * Sets the name of the command.
394 *
395 * This method can set both the namespace and the name if
396 * you separate them by a colon (:)
397 *
398 * $command->setName('foo:bar');
399 *
400 * @param string $name The command name
401 *
402 * @return Command The current instance
403 *
404 * @throws \InvalidArgumentException When command name given is empty
405 *
406 * @api
407 */
408 public function setName($name)
409 {
410 $this->validateName($name);
411
412 $this->name = $name;
413
414 return $this;
415 }
416
417 /**
418 * Returns the command name.
419 *
420 * @return string The command name
421 *
422 * @api
423 */
424 public function getName()
425 {
426 return $this->name;
427 }
428
429 /**
430 * Sets the description for the command.
431 *
432 * @param string $description The description for the command
433 *
434 * @return Command The current instance
435 *
436 * @api
437 */
438 public function setDescription($description)
439 {
440 $this->description = $description;
441
442 return $this;
443 }
444
445 /**
446 * Returns the description for the command.
447 *
448 * @return string The description for the command
449 *
450 * @api
451 */
452 public function getDescription()
453 {
454 return $this->description;
455 }
456
457 /**
458 * Sets the help for the command.
459 *
460 * @param string $help The help for the command
461 *
462 * @return Command The current instance
463 *
464 * @api
465 */
466 public function setHelp($help)
467 {
468 $this->help = $help;
469
470 return $this;
471 }
472
473 /**
474 * Returns the help for the command.
475 *
476 * @return string The help for the command
477 *
478 * @api
479 */
480 public function getHelp()
481 {
482 return $this->help;
483 }
484
485 /**
486 * Returns the processed help for the command replacing the %command.name% and
487 * %command.full_name% patterns with the real values dynamically.
488 *
489 * @return string The processed help for the command
490 */
491 public function getProcessedHelp()
492 {
493 $name = $this->name;
494
495 $placeholders = array(
496 '%command.name%',
497 '%command.full_name%',
498 );
499 $replacements = array(
500 $name,
501 $_SERVER['PHP_SELF'].' '.$name,
502 );
503
504 return str_replace($placeholders, $replacements, $this->getHelp());
505 }
506
507 /**
508 * Sets the aliases for the command.
509 *
510 * @param string[] $aliases An array of aliases for the command
511 *
512 * @return Command The current instance
513 *
514 * @api
515 */
516 public function setAliases($aliases)
517 {
518 if (!is_array($aliases) && !$aliases instanceof \Traversable) {
519 throw new \InvalidArgumentException('$aliases must be an array or an instance of \Traversable');
520 }
521
522 foreach ($aliases as $alias) {
523 $this->validateName($alias);
524 }
525
526 $this->aliases = $aliases;
527
528 return $this;
529 }
530
531 /**
532 * Returns the aliases for the command.
533 *
534 * @return array An array of aliases for the command
535 *
536 * @api
537 */
538 public function getAliases()
539 {
540 return $this->aliases;
541 }
542
543 /**
544 * Returns the synopsis for the command.
545 *
546 * @return string The synopsis
547 */
548 public function getSynopsis()
549 {
550 if (null === $this->synopsis) {
551 $this->synopsis = trim(sprintf('%s %s', $this->name, $this->definition->getSynopsis()));
552 }
553
554 return $this->synopsis;
555 }
556
557 /**
558 * Gets a helper instance by name.
559 *
560 * @param string $name The helper name
561 *
562 * @return mixed The helper value
563 *
564 * @throws \InvalidArgumentException if the helper is not defined
565 *
566 * @api
567 */
568 public function getHelper($name)
569 {
570 return $this->helperSet->get($name);
571 }
572
573 /**
574 * Returns a text representation of the command.
575 *
576 * @return string A string representing the command
577 *
578 * @deprecated Deprecated since version 2.3, to be removed in 3.0.
579 */
580 public function asText()
581 {
582 $descriptor = new TextDescriptor();
583
584 return $descriptor->describe($this);
585 }
586
587 /**
588 * Returns an XML representation of the command.
589 *
590 * @param bool $asDom Whether to return a DOM or an XML string
591 *
592 * @return string|\DOMDocument An XML string representing the command
593 *
594 * @deprecated Deprecated since version 2.3, to be removed in 3.0.
595 */
596 public function asXml($asDom = false)
597 {
598 $descriptor = new XmlDescriptor();
599
600 return $descriptor->describe($this, array('as_dom' => $asDom));
601 }
602
603 private function validateName($name)
604 {
605 if (!preg_match('/^[^\:]+(\:[^\:]+)*$/', $name)) {
606 throw new \InvalidArgumentException(sprintf('Command name "%s" is invalid.', $name));
607 }
608 }
609 }
610