1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* The Mocker class creates mock data userful for testing. |
4
|
|
|
* |
5
|
|
|
* @package Jetpack |
6
|
|
|
*/ |
7
|
|
|
|
8
|
|
|
namespace Automattic\Jetpack\Debug_Helper; |
9
|
|
|
|
10
|
|
|
use Automattic\Jetpack\Debug_Helper\Mocker\Runner_Interface; |
11
|
|
|
use WP_Error; |
12
|
|
|
use WP_REST_Request; |
13
|
|
|
use WP_REST_Server; |
14
|
|
|
|
15
|
|
|
require_once __DIR__ . '/inc/mockers/interface-runner.php'; |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* REST_API_Tester to test REST API endpoints. |
19
|
|
|
*/ |
20
|
|
|
class Mocker { |
21
|
|
|
|
22
|
|
|
const REST_BASE = 'jetpack-debug'; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* List of available runners. |
26
|
|
|
* |
27
|
|
|
* @var string[] |
28
|
|
|
*/ |
29
|
|
|
private $runners = array( |
30
|
|
|
'options' => 'Options', |
31
|
|
|
'nonces' => 'Nonces (stored in options)', |
32
|
|
|
); |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* Construction. |
36
|
|
|
*/ |
37
|
|
|
public function __construct() { |
38
|
|
|
add_action( 'admin_menu', array( $this, 'register_submenu_page' ), 1000 ); |
39
|
|
|
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); |
40
|
|
|
add_action( 'rest_api_init', array( $this, 'register_endpoints' ) ); |
41
|
|
|
} |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* Register the REST endpoint. |
45
|
|
|
*/ |
46
|
|
View Code Duplication |
public function register_endpoints() { |
47
|
|
|
register_rest_route( |
48
|
|
|
self::REST_BASE, |
49
|
|
|
'/mocker', |
50
|
|
|
array( |
51
|
|
|
'methods' => WP_REST_Server::READABLE, |
52
|
|
|
'callback' => array( $this, 'run' ), |
53
|
|
|
'permission_callback' => '__return_true', |
54
|
|
|
) |
55
|
|
|
); |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* Add submenu item. |
60
|
|
|
*/ |
61
|
|
|
public function register_submenu_page() { |
62
|
|
|
add_submenu_page( |
63
|
|
|
'jetpack-debug-tools', |
64
|
|
|
'Mocker', |
65
|
|
|
'Mocker', |
66
|
|
|
'manage_options', |
67
|
|
|
'mocker', |
68
|
|
|
array( $this, 'render_ui' ), |
69
|
|
|
99 |
70
|
|
|
); |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
/** |
74
|
|
|
* Enqueue scripts! |
75
|
|
|
* |
76
|
|
|
* @param string $hook Page hook. |
77
|
|
|
*/ |
78
|
|
View Code Duplication |
public function enqueue_scripts( $hook ) { |
79
|
|
|
if ( strpos( $hook, 'jetpack-debug_page_mocker' ) === 0 ) { |
80
|
|
|
wp_enqueue_style( 'mocker_style', plugin_dir_url( __FILE__ ) . 'inc/css/mocker.css', array(), JETPACK_DEBUG_HELPER_VERSION ); |
81
|
|
|
wp_enqueue_script( 'mocker_script', plugin_dir_url( __FILE__ ) . 'inc/js/mocker.js', array( 'wp-api' ), JETPACK_DEBUG_HELPER_VERSION, true ); |
82
|
|
|
|
83
|
|
|
add_filter( |
84
|
|
|
'script_loader_tag', |
85
|
|
|
function( $tag, $handle ) { |
86
|
|
|
if ( 'mocker_script' === $handle ) { |
87
|
|
|
$tag = str_replace( '<script ', '<script type="module" ', $tag ); |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
return $tag; |
91
|
|
|
}, |
92
|
|
|
10, |
93
|
|
|
2 |
94
|
|
|
); |
95
|
|
|
} |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
/** |
99
|
|
|
* Render UI. |
100
|
|
|
*/ |
101
|
|
|
public function render_ui() { |
102
|
|
|
wp_localize_script( |
103
|
|
|
'wp-mocker', |
104
|
|
|
'wpApiSettings', |
105
|
|
|
array( |
106
|
|
|
'root' => esc_url_raw( rest_url() ), |
107
|
|
|
'nonce' => wp_create_nonce( 'wp_mocker' ), |
108
|
|
|
) |
109
|
|
|
); |
110
|
|
|
|
111
|
|
|
?> |
112
|
|
|
<h1>Fastest Data Mocker in Town!</h1> |
113
|
|
|
|
114
|
|
|
<div class="jetpack-debug-mocker"> |
115
|
|
|
<form method="post" id="jetpack-debug-mocker-form"> |
116
|
|
|
<div class="mocker-block"> |
117
|
|
|
<label for="mocker-data">Data:</label> |
118
|
|
|
<div class="mocker-field"> |
119
|
|
|
<select name="data" id="mocker-data"> |
120
|
|
|
<?php foreach ( $this->runners as $key => $name ) : ?> |
121
|
|
|
<option value="<?php echo esc_html( $key ); ?>"><?php echo esc_html( $name ); ?></option> |
122
|
|
|
<?php endforeach ?> |
123
|
|
|
</select> |
124
|
|
|
</div> |
125
|
|
|
</div> |
126
|
|
|
|
127
|
|
|
<div class="mocker-block"> |
128
|
|
|
<label for="mocker-number">How Many:</label> |
129
|
|
|
<div class="mocker-field"> |
130
|
|
|
<input type="number" name="number" class="input-number" id="mocker-number" value="50"> |
131
|
|
|
</div> |
132
|
|
|
</div> |
133
|
|
|
|
134
|
|
|
<div class="mocker-block align-right"> |
135
|
|
|
<button type="submit" class="button-right" id="mocker-submit">Run! 🚀</button> |
136
|
|
|
</div> |
137
|
|
|
|
138
|
|
|
<div id="mocker-response" class="block-hide"></div> |
139
|
|
|
</form> |
140
|
|
|
</div> |
141
|
|
|
<?php |
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
/** |
145
|
|
|
* Load the class. |
146
|
|
|
*/ |
147
|
|
|
public static function register_mocker() { |
148
|
|
|
new Mocker(); |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* Initialize the runner and run it. |
153
|
|
|
* |
154
|
|
|
* @param WP_REST_Request $request The request object. |
155
|
|
|
* |
156
|
|
|
* @return \WP_REST_Response|WP_Error |
157
|
|
|
*/ |
158
|
|
|
public function run( WP_REST_Request $request ) { |
159
|
|
|
$params = $request->get_query_params(); |
160
|
|
|
|
161
|
|
|
$runner = empty( $params['data'] ) ? null : $params['data']; |
162
|
|
|
$number = empty( $params['number'] ) ? null : (int) $params['number']; |
163
|
|
|
|
164
|
|
|
if ( ! $runner || ! array_key_exists( $runner, $this->runners ) ) { |
165
|
|
|
return new WP_Error( 'unknown_runner' ); |
|
|
|
|
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
if ( ! $number ) { |
169
|
|
|
return new WP_Error( 'invalid_number' ); |
|
|
|
|
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
$filename = __DIR__ . "/inc/mockers/class-{$runner}-runner.php"; |
173
|
|
|
if ( ! file_exists( $filename ) ) { |
174
|
|
|
return new WP_Error( 'runner_not_found' ); |
|
|
|
|
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
require_once $filename; |
178
|
|
|
|
179
|
|
|
$class_name = '\Automattic\Jetpack\Debug_Helper\Mocker\\' . ucfirst( $runner ) . '_Runner'; |
180
|
|
|
|
181
|
|
|
if ( ! class_exists( $class_name ) || ! is_a( $class_name, Runner_Interface::class, true ) ) { |
182
|
|
|
return new WP_Error( 'invalid_runner' ); |
|
|
|
|
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
$runner = new $class_name(); |
186
|
|
|
|
187
|
|
|
$result = $runner->run( (int) $params['number'] ); |
188
|
|
|
|
189
|
|
|
if ( $result instanceof WP_Error ) { |
190
|
|
|
return $result; |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
if ( false === $result ) { |
194
|
|
|
return new WP_Error( 'runner_error' ); |
|
|
|
|
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
return rest_ensure_response( array( 'success' => true ) ); |
198
|
|
|
} |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
add_action( 'plugins_loaded', array( Mocker::class, 'register_mocker' ), 1000 ); |
202
|
|
|
|
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.