Chris@0: parser = $parserFactory->createParser(); Chris@0: Chris@0: $this->traverser = new NodeTraverser(); Chris@0: $this->traverser->addVisitor(new SudoVisitor()); Chris@0: Chris@0: $this->printer = new Printer(); Chris@0: Chris@0: parent::__construct($name); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Set the Shell's Readline service. Chris@0: * Chris@0: * @param Readline $readline Chris@0: */ Chris@0: public function setReadline(Readline $readline) Chris@0: { Chris@0: $this->readline = $readline; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: protected function configure() Chris@0: { Chris@0: $this Chris@0: ->setName('sudo') Chris@0: ->setDefinition([ Chris@0: new CodeArgument('code', CodeArgument::REQUIRED, 'Code to execute.'), Chris@0: ]) Chris@0: ->setDescription('Evaluate PHP code, bypassing visibility restrictions.') Chris@0: ->setHelp( Chris@0: <<<'HELP' Chris@0: Evaluate PHP code, bypassing visibility restrictions. Chris@0: Chris@0: e.g. Chris@0: >>> $sekret->whisper("hi") Chris@0: PHP error: Call to private method Sekret::whisper() from context '' on line 1 Chris@0: Chris@0: >>> sudo $sekret->whisper("hi") Chris@0: => "hi" Chris@0: Chris@0: >>> $sekret->word Chris@0: PHP error: Cannot access private property Sekret::$word on line 1 Chris@0: Chris@0: >>> sudo $sekret->word Chris@0: => "hi" Chris@0: Chris@0: >>> $sekret->word = "please" Chris@0: PHP error: Cannot access private property Sekret::$word on line 1 Chris@0: Chris@0: >>> sudo $sekret->word = "please" Chris@0: => "please" Chris@0: HELP Chris@0: ); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: protected function execute(InputInterface $input, OutputInterface $output) Chris@0: { Chris@0: $code = $input->getArgument('code'); Chris@0: Chris@0: // special case for !! Chris@0: if ($code === '!!') { Chris@0: $history = $this->readline->listHistory(); Chris@4: if (\count($history) < 2) { Chris@0: throw new \InvalidArgumentException('No previous command to replay'); Chris@0: } Chris@4: $code = $history[\count($history) - 2]; Chris@0: } Chris@0: Chris@4: if (\strpos('traverser->traverse($this->parse($code)); Chris@0: Chris@0: $sudoCode = $this->printer->prettyPrint($nodes); Chris@0: $shell = $this->getApplication(); Chris@0: $shell->addCode($sudoCode, !$shell->hasCode()); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Lex and parse a string of code into statements. Chris@0: * Chris@0: * @param string $code Chris@0: * Chris@0: * @return array Statements Chris@0: */ Chris@0: private function parse($code) Chris@0: { Chris@0: try { Chris@0: return $this->parser->parse($code); Chris@0: } catch (\PhpParser\Error $e) { Chris@4: if (\strpos($e->getMessage(), 'unexpected EOF') === false) { Chris@0: throw $e; Chris@0: } Chris@0: Chris@0: // If we got an unexpected EOF, let's try it again with a semicolon. Chris@0: return $this->parser->parse($code . ';'); Chris@0: } Chris@0: } Chris@0: }