-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathTinker.php
More file actions
93 lines (71 loc) · 2.5 KB
/
Copy pathTinker.php
File metadata and controls
93 lines (71 loc) · 2.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<?php
namespace TweakPHP\Client;
use PhpParser\ParserFactory;
use PhpParser\PrettyPrinter\Standard;
use Psy\Configuration;
use Psy\ExecutionLoopClosure;
use Psy\Shell;
use Symfony\Component\Console\Output\BufferedOutput;
use TweakPHP\Client\OutputModifiers\OutputModifier;
class Tinker
{
protected BufferedOutput $output;
protected Shell $shell;
protected OutputModifier $outputModifier;
public static array $statements = [];
public static int $current = 0;
public function __construct(OutputModifier $outputModifier, Configuration $config)
{
$this->output = new BufferedOutput;
$this->shell = $this->createShell($this->output, $config);
$this->outputModifier = $outputModifier;
}
public function execute(string $rawPHPCode): array
{
if (strpos($rawPHPCode, '<?php') === false) {
$rawPHPCode = "<?php\n".$rawPHPCode;
}
$parser = (new ParserFactory)->createForHostVersion();
$prettyPrinter = new Standard;
foreach ($parser->parse($rawPHPCode) as $key => $stmt) {
$code = $prettyPrinter->prettyPrint([$stmt]);
self::$current = $key;
self::$statements[] = [
'line' => $stmt->getStartLine(),
'code' => $code,
];
$output = $this->doExecute($code);
self::$statements[$key]['output'] = $output;
}
return [
'output' => self::$statements,
];
}
protected function doExecute(string $code): string
{
$this->shell->addInput($code);
$this->shell->addInput("\necho('TWEAKPHP_END'); exit();");
$this->output = new BufferedOutput;
$this->shell->setOutput($this->output);
$closure = new ExecutionLoopClosure($this->shell);
$closure->execute();
$result = $this->outputModifier->modify($this->cleanOutput($this->output->fetch()));
return trim($result);
}
protected function createShell(BufferedOutput $output, Configuration $config): Shell
{
$shell = new Shell($config);
$shell->setOutput($output);
return $shell;
}
protected function cleanOutput(string $output): string
{
$output = preg_replace('/(?s)(<aside.*?<\/aside>)|Exit: Ctrl\+D/ms', '$2', $output);
$output = preg_replace('/(?s)(<whisper.*?<\/whisper>)|INFO Ctrl\+D\./ms', '$2', $output);
return trim($output);
}
public function getShell(): Shell
{
return $this->shell;
}
}