4 use Symfony\Component\Console\ConsoleEvents;
5 use Symfony\Component\Console\Event\ConsoleCommandEvent;
6 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
7 use Robo\Contract\ConfigAwareInterface;
8 use Robo\Common\ConfigAwareTrait;
9 use Robo\Config\GlobalOptionDefaultValuesInterface;
11 class GlobalOptionsEventListener implements EventSubscriberInterface, ConfigAwareInterface
15 /** @var Application */
16 protected $application;
22 * GlobalOptionsEventListener listener
24 public function __construct()
26 $this->prefix = 'options';
30 * Add a reference to the Symfony Console application object.
32 public function setApplication($application)
34 $this->application = $application;
39 * Stipulate the prefix to use for option injection.
40 * @param string $prefix
42 public function setGlobalOptionsPrefix($prefix)
44 $this->prefix = $prefix;
51 public static function getSubscribedEvents()
53 return [ConsoleEvents::COMMAND => 'handleCommandEvent'];
57 * Run all of our individual operations when a command event is received.
59 public function handleCommandEvent(ConsoleCommandEvent $event)
61 $this->setGlobalOptions($event);
62 $this->setConfigurationValues($event);
66 * Before a Console command runs, examine the global
67 * commandline options from the event Input, and set
68 * configuration values as appropriate.
70 * @param \Symfony\Component\Console\Event\ConsoleCommandEvent $event
72 public function setGlobalOptions(ConsoleCommandEvent $event)
74 $config = $this->getConfig();
75 $input = $event->getInput();
77 $globalOptions = $config->get($this->prefix, []);
78 if ($config instanceof \Consolidation\Config\GlobalOptionDefaultValuesInterface) {
79 $globalOptions += $config->getGlobalOptionDefaultValues();
82 $globalOptions += $this->applicationOptionDefaultValues();
84 // Set any config value that has a defined global option (e.g. --simulate)
85 foreach ($globalOptions as $option => $default) {
86 $value = $input->hasOption($option) ? $input->getOption($option) : null;
87 // Unfortunately, the `?:` operator does not differentate between `0` and `null`
91 $config->set($this->prefix . '.' . $option, $value);
96 * Examine the commandline --define / -D options, and apply the provided
97 * values to the active configuration.
99 * @param \Symfony\Component\Console\Event\ConsoleCommandEvent $event
101 public function setConfigurationValues(ConsoleCommandEvent $event)
103 $config = $this->getConfig();
104 $input = $event->getInput();
106 // Also set any `-D config.key=value` options from the commandline.
107 if ($input->hasOption('define')) {
108 $configDefinitions = $input->getOption('define');
109 foreach ($configDefinitions as $value) {
110 list($key, $value) = $this->splitConfigKeyValue($value);
111 $config->set($key, $value);
117 * Split up the key=value config setting into its component parts. If
118 * the input string contains no '=' character, then the value will be 'true'.
120 * @param string $value
123 protected function splitConfigKeyValue($value)
125 $parts = explode('=', $value, 2);
131 * Get default option values from the Symfony Console application, if
134 protected function applicationOptionDefaultValues()
136 if (!$this->application) {
141 foreach ($this->application->getDefinition()->getOptions() as $key => $option) {
142 $result[$key] = $option->acceptValue() ? $option->getDefault() : null;