config = $config; } /** * {@inheritdoc} */ protected function configure(): void { $this ->setName('copy') ->setDefinition([ new CodeArgument('expression', CodeArgument::OPTIONAL, 'Expression to copy.'), ]) ->setDescription('Copy a value to the clipboard.') ->setHelp( <<<'HELP' Copy a value to the clipboard. When given: - an expression, copy the exported value of the expression to the clipboard. - no arguments, copy the last evaluated result ($_) to the clipboard. e.g. >>> copy new Foo() >>> copy User::all()->toArray() >>> copy HELP ); } /** * {@inheritdoc} * * @return int 0 if everything went fine, or an exit code */ protected function execute(InputInterface $input, OutputInterface $output): int { $expression = $input->getArgument('expression'); $value = $expression === null ? $this->context->get('_') : $this->resolveCode($expression); if (\is_object($value)) { $this->setCommandScopeVariables(new \ReflectionObject($value)); } if (!$this->getClipboardMethod()->copy($this->exportValue($value, $output), $output)) { $output->writeln('Unable to copy value to clipboard.'); return 1; } $output->writeln('Copied to clipboard.'); return 0; } private function getClipboardMethod(): ClipboardMethod { return $this->config ? $this->config->getClipboard() : new NullClipboardMethod(false); } private function exportValue($value, OutputInterface $output): string { $export = ''; $warnings = []; \set_error_handler(static function (int $errno, string $errstr) use (&$warnings): bool { $warnings[$errstr] = true; return true; }); try { $export = (string) \var_export($value, true); } finally { \restore_error_handler(); } foreach (\array_keys($warnings) as $warning) { if ($warning === 'var_export does not handle circular references') { $output->writeln('Value contains circular references; copied export may be incomplete.'); break; } $output->writeln(\sprintf('%s', $warning)); break; } return $export; } }