PluginProbe
WP Console – WordPress PHP Console powered by PsySH / trunk
WP Console – WordPress PHP Console powered by PsySH vtrunk
trunk 2.4.0 2.4.1 2.5.0 2.5.1 2.6.0
wp-console / includes / Core / Console / RestController.php

RestController.php in WP Console – WordPress PHP Console powered by PsySH trunk, at includes/Core/Console/RestController.php

194 lines 4.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WPConsole\Core\Console;
4
5 use WP_Error;
6 use Exception;
7 use Psy\Shell;
8 use Throwable;
9 use WP_REST_Server;
10 use WP_REST_Controller;
11 use Psy\Output\ShellOutput;
12
13 class RestController extends WP_REST_Controller {
14
15 /**
16 * Endpoint namespace
17 *
18 * @since 1.0.0
19 *
20 * @var string
21 */
22 protected $namespace = 'wp-console/v1';
23
24 /**
25 * Route name
26 *
27 * @since 1.0.0
28 *
29 * @var string
30 */
31 protected $base = 'console';
32
33 /**
34 * Class constructor
35 *
36 * @since 1.0.0
37 *
38 * @return void
39 */
40 public function __construct() {
41 $this->register_routes();
42 }
43
44 /**
45 * Register REST routes
46 *
47 * @since 1.0.0
48 *
49 * @return void
50 */
51 public function register_routes() {
52 register_rest_route( $this->namespace, '/' . $this->base, [
53 [
54 'methods' => WP_REST_Server::CREATABLE,
55 'callback' => [ $this, 'create_item' ],
56 'permission_callback' => [ $this, 'can_manage_options' ],
57 'args' => [
58 'input' => [
59 'required' => true,
60 'type' => 'string',
61 'description' => esc_html__( 'Code to be executed.', 'wp-console' ),
62 'validate_callback' => [ $this, 'input_validation' ],
63 ],
64 ],
65 ],
66 ] );
67 }
68
69 /**
70 * Check if current user has manage_options capability
71 *
72 * @since 2.0.0
73 *
74 * @param \WP_REST_Request $request
75 *
76 * @return bool
77 */
78 public function can_manage_options( $request ) {
79 return current_user_can( 'manage_options' );
80 }
81
82 /**
83 * Validate input arg
84 *
85 * @since 1.0.0
86 *
87 * @param string $value
88 * @param \WP_REST_Request $request
89 * @param string $param
90 *
91 * @return bool|\WP_Error
92 */
93 public function input_validation( $value, $request, $param ) {
94 if ( ! empty( trim( $value ) ) ) {
95 return true;
96 }
97
98 return new WP_Error( 'wp_console_rest_invalid_input', esc_html__( 'Input is empty', 'wp-console' ) );
99 }
100
101 /**
102 * Evaluate input code
103 *
104 * @since 1.0.0
105 * @since 1.1.0 Use \Psy\Shell::writeStdout as output buffer
106 *
107 * @param \WP_REST_Request $request
108 *
109 * @return \WP_REST_Response
110 */
111 public function create_item( $request ) {
112 global $wp_console_dump;
113
114 try {
115 $timer = microtime( true );
116 $input = $request['input'];
117
118 $config = new \Psy\Configuration( [
119 'configDir' => WP_CONTENT_DIR,
120 ] );
121
122 $output = new ShellOutput( ShellOutput::VERBOSITY_NORMAL, true );
123
124 $config->setOutput( $output );
125 $config->setColorMode( \Psy\Configuration::COLOR_MODE_DISABLED );
126
127 $psysh = new Shell( $config );
128
129 $psysh->setOutput( $output );
130
131 $psysh->addCode( $input );
132
133 extract( $psysh->getScopeVariablesDiff( get_defined_vars() ) );
134
135 ob_start( [ $psysh, 'writeStdout' ], 1 );
136
137 set_error_handler( [ $psysh, 'handleError' ] );
138
139 $_ = eval( $psysh->onExecute( $psysh->flushCode() ?: \Psy\ExecutionClosure::NOOP_INPUT ) );
140
141 restore_error_handler();
142
143 $psysh->setScopeVariables( get_defined_vars() );
144 $psysh->writeReturnValue( $_ );
145
146 ob_end_flush();
147
148 if ( $output->exception ) {
149 throw $output->exception;
150 }
151
152 $execution_time = microtime( true ) - $timer;
153
154 $data = [
155 'output' => $output->outputMessage,
156 'dump' => $wp_console_dump,
157 'execution_time' => number_format( $execution_time, 3, '.', '' ),
158 ];
159
160 return rest_ensure_response( $data );
161
162 } catch ( Throwable $error ) {
163 // This code only executes in PHP >= 7.x and is ignored in PHP 5.x.
164 return $this->request_error( $request['input'], $error );
165
166 } catch ( Exception $error ) {
167 // This code only executes in PHP 5.x and is ignored in PHP 7.
168 return $this->request_error( $request['input'], $error );
169 }
170 }
171
172 /**
173 * Evaluate input code
174 *
175 * @since 2.3.0
176 *
177 * @param string $input
178 * @param \Throwable $request
179 *
180 * @return \WP_Error
181 */
182 protected function request_error( $input, $error ) {
183 if ( ob_get_length() ) {
184 ob_end_flush();
185 }
186
187 return new WP_Error( 'wp_console_rest_error', $error->getMessage(), [
188 'input' => $input,
189 'status' => 422,
190 'trace' => $error->getTraceAsString(),
191 ] );
192 }
193 }
194