| <?php |
|
|
| |
| |
| |
| |
| |
| |
|
|
| namespace Piwik\Plugin; |
|
|
| use Piwik\Container\StaticContainer; |
| use Piwik\Plugins\CoreConsole\FeatureFlags\SystemSignals; |
| use Piwik\Plugins\FeatureFlags\FeatureFlagManager; |
| use Symfony\Component\Console\Command\Command as SymfonyCommand; |
| use Symfony\Component\Console\Command\SignalableCommandInterface; |
| use Symfony\Component\Console\Exception\LogicException; |
| use Symfony\Component\Console\Helper\ProgressBar; |
| use Symfony\Component\Console\Helper\QuestionHelper; |
| use Symfony\Component\Console\Helper\Table; |
| use Symfony\Component\Console\Input\ArrayInput; |
| use Symfony\Component\Console\Input\InputArgument; |
| use Symfony\Component\Console\Input\InputInterface; |
| use Symfony\Component\Console\Input\InputOption; |
| use Symfony\Component\Console\Output\NullOutput; |
| use Symfony\Component\Console\Output\OutputInterface; |
| use Symfony\Component\Console\Question\ConfirmationQuestion; |
| use Symfony\Component\Console\Question\Question; |
| use Throwable; |
|
|
| |
| |
| |
| |
| |
| class ConsoleCommand extends SymfonyCommand implements SignalableCommandInterface |
| { |
| |
| |
| |
| private $progress = null; |
|
|
| |
| |
| |
| private $output = null; |
|
|
| |
| |
| |
| private $input = null; |
|
|
| |
| |
| |
| |
| |
| public function writeSuccessMessage($messages): void |
| { |
| if (is_string($messages)) { |
| $messages = [$messages]; |
| } |
|
|
| $this->getOutput()->writeln(''); |
|
|
| foreach ($messages as $message) { |
| $this->getOutput()->writeln(self::wrapInTag('info', $message)); |
| } |
|
|
| $this->getOutput()->writeln(''); |
| } |
|
|
| |
| |
| |
| |
| |
| public function writeErrorMessage($messages): void |
| { |
| if (is_string($messages)) { |
| $messages = [$messages]; |
| } |
|
|
| $this->getOutput()->writeln(''); |
|
|
| foreach ($messages as $message) { |
| $this->getOutput()->writeln(self::wrapInTag('error', $message)); |
| } |
|
|
| $this->getOutput()->writeln(''); |
| } |
|
|
| |
| |
| |
| |
| |
| public function writeComment($messages): void |
| { |
| if (is_string($messages)) { |
| $messages = [$messages]; |
| } |
|
|
| $this->getOutput()->writeln(''); |
|
|
| foreach ($messages as $message) { |
| $this->getOutput()->writeln(self::wrapInTag('comment', $message)); |
| } |
|
|
| $this->getOutput()->writeln(''); |
| } |
|
|
| |
| |
| |
| |
| |
| protected function checkAllRequiredOptionsAreNotEmpty(): void |
| { |
| $options = $this->getDefinition()->getOptions(); |
|
|
| foreach ($options as $option) { |
| $name = $option->getName(); |
| $value = $this->getInput()->getOption($name); |
|
|
| if ($option->isValueRequired() && empty($value)) { |
| throw new \InvalidArgumentException(sprintf('The required option --%s is not set', $name)); |
| } |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| final protected function execute(InputInterface $input, OutputInterface $output): int |
| { |
| return $this->doExecute(); |
| } |
|
|
| |
| |
| |
| final public function run(InputInterface $input, OutputInterface $output): int |
| { |
| |
| $this->input = $input; |
| $this->output = $output; |
| return parent::run($input, $output); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| final public function getSubscribedSignals(): array |
| { |
| $canSubscribe = false; |
|
|
| |
| |
| |
| try { |
| $featureFlagManager = StaticContainer::get(FeatureFlagManager::class); |
| $canSubscribe = $featureFlagManager->isFeatureActive(SystemSignals::class); |
| } catch (Throwable $e) { |
| } |
|
|
| if (!$canSubscribe) { |
| return []; |
| } |
|
|
| return $this->getSystemSignalsToHandle(); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| final public function handleSignal(int $signal): void |
| { |
| $this->handleSystemSignal($signal); |
| } |
|
|
| |
| |
| |
| |
| |
| public function getSystemSignalsToHandle(): array |
| { |
| return []; |
| } |
|
|
| |
| |
| |
| public function handleSystemSignal(int $signal): void |
| { |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| public function addNegatableOption(string $name, $shortcut = null, string $description = '', $default = null) |
| { |
| return parent::addOption($name, $shortcut, InputOption::VALUE_NEGATABLE, $description, $default); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| public function addOptionalValueOption( |
| string $name, |
| $shortcut = null, |
| string $description = '', |
| $default = null, |
| bool $acceptArrays = false |
| ) { |
| $mode = $acceptArrays ? InputOption::VALUE_IS_ARRAY : 0; |
| return parent::addOption($name, $shortcut, $mode | InputOption::VALUE_OPTIONAL, $description, $default); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| public function addNoValueOption(string $name, $shortcut = null, string $description = '', $default = null) |
| { |
| return parent::addOption($name, $shortcut, InputOption::VALUE_NONE, $description, $default); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| public function addRequiredValueOption( |
| string $name, |
| $shortcut = null, |
| string $description = '', |
| $default = null, |
| bool $acceptArrays = false |
| ) { |
| $mode = $acceptArrays ? InputOption::VALUE_IS_ARRAY : 0; |
| return parent::addOption($name, $shortcut, $mode | InputOption::VALUE_REQUIRED, $description, $default); |
| } |
|
|
| |
| |
| |
| |
| |
| public function addOption( |
| string $name, |
| $shortcut = null, |
| ?int $mode = null, |
| string $description = '', |
| $default = null |
| ) { |
| throw new \LogicException('addOption should not be used.'); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| public function addOptionalArgument( |
| string $name, |
| string $description = '', |
| $default = null, |
| bool $acceptArrays = false |
| ) { |
| $mode = $acceptArrays ? InputArgument::IS_ARRAY : 0; |
| return parent::addArgument($name, $mode | InputArgument::OPTIONAL, $description, $default); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| public function addRequiredArgument( |
| string $name, |
| string $description = '', |
| $default = null, |
| bool $acceptArrays = false |
| ) { |
| $mode = $acceptArrays ? InputArgument::IS_ARRAY : 0; |
| return parent::addArgument($name, $mode | InputArgument::REQUIRED, $description, $default); |
| } |
|
|
| |
| |
| |
| |
| |
| public function addArgument(string $name, ?int $mode = null, string $description = '', $default = null) |
| { |
| throw new \LogicException('addArgument can not be used.'); |
| } |
|
|
| |
| |
| |
| |
| |
| protected function doExecute(): int |
| { |
| throw new LogicException('You must override the doExecute() method in the concrete command class.'); |
| } |
|
|
| |
| |
| |
| |
| |
| final protected function interact(InputInterface $input, OutputInterface $output) |
| { |
| $this->doInteract(); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| protected function doInteract(): void |
| { |
| } |
|
|
| |
| |
| |
| |
| |
| final protected function initialize(InputInterface $input, OutputInterface $output) |
| { |
| $this->doInitialize(); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| protected function doInitialize(): void |
| { |
| } |
|
|
| protected function getOutput(): OutputInterface |
| { |
| return $this->output; |
| } |
|
|
| protected function setOutput(OutputInterface $output): void |
| { |
| $this->output = $output; |
| } |
|
|
| protected function getInput(): InputInterface |
| { |
| return $this->input; |
| } |
|
|
| |
| |
| |
| |
| |
| public function getHelper(string $name) |
| { |
| throw new \LogicException('getHelper can not be used'); |
| } |
|
|
| |
| |
| |
| |
| |
| protected function askForConfirmation(string $question, bool $default = true, string $trueAnswerRegex = '/^y/i'): bool |
| { |
| |
| $helper = parent::getHelper('question'); |
| $question = new ConfirmationQuestion($question, $default, $trueAnswerRegex); |
| return (bool) $helper->ask($this->getInput(), $this->getOutput(), $question); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| protected function askAndValidate( |
| string $question, |
| ?callable $validator = null, |
| $default = null, |
| ?iterable $autocompleterValues = null |
| ) { |
| |
| $helper = parent::getHelper('question'); |
| $question = new Question($question, $default); |
| $question->setValidator($validator); |
| $question->setAutocompleterValues($autocompleterValues); |
| return $helper->ask($this->getInput(), $this->getOutput(), $question); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| protected function ask(string $question, $default = null) |
| { |
| return $this->askAndValidate($question, null, $default); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| protected function initProgressBar(int $numChangesToPerform = 0): ProgressBar |
| { |
| $this->progress = new ProgressBar($this->getOutput(), $numChangesToPerform); |
| return $this->progress; |
| } |
|
|
| |
| |
| |
| protected function startProgressBar(int $numChangesToPerform = 0): void |
| { |
| $this->progress->start($numChangesToPerform); |
| } |
|
|
| |
| |
| |
| protected function advanceProgressBar(int $step = 1): void |
| { |
| if (empty($this->progress)) { |
| throw new \Exception('No progress bar initialized.'); |
| } |
|
|
| $this->progress->advance($step); |
| } |
|
|
| |
| |
| |
| protected function finishProgressBar(): void |
| { |
| if (empty($this->progress)) { |
| throw new \Exception('No progress bar initialized.'); |
| } |
|
|
| $this->progress->finish(); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| protected function renderTable(array $header, array $rows) |
| { |
| $table = new Table($this->getOutput()); |
| $table |
| ->setHeaders($header) |
| ->setRows($rows); |
| $table->render(); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| protected function runCommand(string $command, array $arguments, bool $hideOutput = false): int |
| { |
| $command = $this->getApplication()->find($command); |
| $arguments = ['command' => $command] + $arguments; |
| $inputObject = new ArrayInput($arguments); |
| $inputObject->setInteractive($this->getInput()->isInteractive()); |
| return $command->run($inputObject, $hideOutput ? new NullOutput() : $this->getOutput()); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| public static function wrapInTag(string $tagname, string $str): string |
| { |
| return "<$tagname>$str</$tagname>"; |
| } |
| } |
|
|