Mercurial > hg > isophonics-drupal-site
diff vendor/psy/psysh/src/Psy/Command/SudoCommand.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/psy/psysh/src/Psy/Command/SudoCommand.php Wed Nov 29 16:09:58 2017 +0000 @@ -0,0 +1,143 @@ +<?php + +/* + * This file is part of Psy Shell. + * + * (c) 2012-2017 Justin Hileman + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Psy\Command; + +use PhpParser\NodeTraverser; +use PhpParser\PrettyPrinter\Standard as Printer; +use Psy\Input\CodeArgument; +use Psy\ParserFactory; +use Psy\Readline\Readline; +use Psy\Sudo\SudoVisitor; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * Evaluate PHP code, bypassing visibility restrictions. + */ +class SudoCommand extends Command +{ + private $readline; + private $parser; + private $traverser; + private $printer; + + /** + * {@inheritdoc} + */ + public function __construct($name = null) + { + $parserFactory = new ParserFactory(); + $this->parser = $parserFactory->createParser(); + + $this->traverser = new NodeTraverser(); + $this->traverser->addVisitor(new SudoVisitor()); + + $this->printer = new Printer(); + + parent::__construct($name); + } + + /** + * Set the Shell's Readline service. + * + * @param Readline $readline + */ + public function setReadline(Readline $readline) + { + $this->readline = $readline; + } + + /** + * {@inheritdoc} + */ + protected function configure() + { + $this + ->setName('sudo') + ->setDefinition(array( + new CodeArgument('code', InputArgument::REQUIRED, 'Code to execute.'), + )) + ->setDescription('Evaluate PHP code, bypassing visibility restrictions.') + ->setHelp( + <<<'HELP' +Evaluate PHP code, bypassing visibility restrictions. + +e.g. +<return>>>> $sekret->whisper("hi")</return> +<return>PHP error: Call to private method Sekret::whisper() from context '' on line 1</return> + +<return>>>> sudo $sekret->whisper("hi")</return> +<return>=> "hi"</return> + +<return>>>> $sekret->word</return> +<return>PHP error: Cannot access private property Sekret::$word on line 1</return> + +<return>>>> sudo $sekret->word</return> +<return>=> "hi"</return> + +<return>>>> $sekret->word = "please"</return> +<return>PHP error: Cannot access private property Sekret::$word on line 1</return> + +<return>>>> sudo $sekret->word = "please"</return> +<return>=> "please"</return> +HELP + ); + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $code = $input->getArgument('code'); + + // special case for !! + if ($code === '!!') { + $history = $this->readline->listHistory(); + if (count($history) < 2) { + throw new \InvalidArgumentException('No previous command to replay'); + } + $code = $history[count($history) - 2]; + } + + if (strpos('<?', $code) === false) { + $code = '<?php ' . $code; + } + + $nodes = $this->traverser->traverse($this->parse($code)); + + $sudoCode = $this->printer->prettyPrint($nodes); + $this->getApplication()->addInput($sudoCode, true); + } + + /** + * Lex and parse a string of code into statements. + * + * @param string $code + * + * @return array Statements + */ + private function parse($code) + { + try { + return $this->parser->parse($code); + } catch (\PhpParser\Error $e) { + if (strpos($e->getMessage(), 'unexpected EOF') === false) { + throw $e; + } + + // If we got an unexpected EOF, let's try it again with a semicolon. + return $this->parser->parse($code . ';'); + } + } +}