PluginProbe
Code Profiler – WordPress Performance Profiling and Debugging Made Easy / 1.9.6
Code Profiler – WordPress Performance Profiling and Debugging Made Easy v1.9.6
1.9.6 1.9.5 1.9.4 1.9.3 trunk 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.5 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.6 1.6.1 1.6.10 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 All 41 releases
← All changes | lib/class-cli.php +133 -59 1.6.61.9.6 View file →
@@ -6,9 +6,9 @@
6 6 | | | / _ \ / _` |/ _ \ | |_) | '__/ _ \| |_| | |/ _ \ '__| |
7 7 | | |__| (_) | (_| | __/ | __/| | | (_) | _| | | __/ | |
8 8 | \____\___/ \__,_|\___| |_| |_| \___/|_| |_|_|\___|_| |
9 9 | |
10 - | (c) Jerome Bruandet ~ https://code-profiler.com/ |
10 + | (c) Jerome Bruandet ~ https://nintechnet.com/codeprofiler/ |
11 11 +=====================================================================+
12 12 */
13 13
14 14 if (! defined('ABSPATH') ) { die('Forbidden'); }
@@ -17,8 +17,9 @@
17 17
18 18 class CodeProfiler_CLI extends WP_CLI_Command {
19 19
20 20 private $file;
21 + private $out = 'view';
21 22 private $cmd_view = 'wp code-profiler view';
22 23 private $cmd_run = 'wp code-profiler run';
23 24
24 25 /**
@@ -29,19 +30,32 @@
29 30
30 31 $this->is_enabled();
31 32
32 33 $_POST['cp_nonce'] = wp_create_nonce('start_profiler_nonce');
33 - $_POST['post'] = home_url( '/' );
34 - $_POST['where'] = 'frontend';
35 - // Detect if we're authenticated or not
36 - if ( is_user_logged_in() === true ) {
37 - $_POST['user'] = 'authenticated';
34 +
35 + $_POST['post'] = home_url( '/' );
36 + // Mark the connection as 'HTTPS' if needed.
37 + if ( strtolower( parse_url( $_POST['post'], PHP_URL_SCHEME ) ) == 'https') {
38 + $_SERVER['HTTPS'] = 'on';
39 + }
40 +
41 + if (! empty( $assoc_args['wpcron'] ) ) {
42 + $_POST['x_end'] = 'wpcron';
43 + $_POST['post'] = $assoc_args['wpcron'];
44 +
38 45 } else {
39 - $_POST['user'] = 'unauthenticated';
46 + $_POST['x_end'] = 'frontend';
47 + // Detect if we're authenticated or not
48 + if ( is_user_logged_in() === true ) {
49 + $_POST['x_auth'] = 'authenticated';
50 + } else {
51 + $_POST['x_auth'] = 'unauthenticated';
52 + }
40 53 }
41 - $_POST['profile'] = 'WP-CLI_' . time();
42 - $_POST['ua'] = 'Firefox';
43 54
55 + $_POST['profile'] = 'WP-CLI_' . time();
56 + $_POST['user_agent'] = 'Firefox';
57 +
44 58 if (! empty( $assoc_args['dest'] ) ) {
45 59 $message = sprintf(
46 60 __('The "%s" option is only available in the pro version of Code Profiler.', 'code-profiler'),
47 61 '--dest'
@@ -49,8 +63,12 @@
49 63 WP_CLI::error( $message );
50 64 exit;
51 65 }
52 66
67 + if (! empty( $assoc_args['out'] ) && in_array( $assoc_args['out'], ['json', 'csv'] ) ) {
68 + $this->out = $assoc_args['out'];
69 + }
70 +
53 71 // HTTP basic authentication
54 72 if (! empty( $assoc_args['u'] ) ) {
55 73 _e('Enter your HTTP basic authentication password:', 'code-profiler');
56 74 echo ' ';
@@ -59,18 +77,20 @@
59 77 echo "\033[0m";
60 78 $_POST['Authorization'] = 'Basic '. base64_encode( "{$assoc_args['u']}:{$password}" );
61 79 }
62 80
63 - WP_CLI::log( sprintf(
64 - __('Starting Code Profiler v%s (profile: %s)', 'code-profiler'),
65 - CODE_PROFILER_VERSION, $_POST['profile'] ) . "\n"
66 - );
81 + if ( $this->out == 'view') {
82 + WP_CLI::log( sprintf(
83 + __('Starting Code Profiler v%s (profile: %s)', 'code-profiler'),
84 + CODE_PROFILER_VERSION, $_POST['profile'] ) . "\n"
85 + );
67 86
68 - $progress = \WP_CLI\Utils\make_progress_bar( '', 3 );
69 - $progress->tick();
87 + $progress = \WP_CLI\Utils\make_progress_bar( '', 3 );
88 + $progress->tick();
89 + }
70 90
71 91 // Run the profiler
72 - $response = json_decode( codeprofiler_start_profiler(), true );
92 + $response = json_decode( CodeProfiler_helpers::codeprofiler_start_profiler(), true );
73 93 if ( $response === false ) {
74 94 $message = __('Unknown error returned by AJAX', 'code-profiler');
75 95 WP_CLI::error( $message );
76 96 exit;
@@ -79,13 +99,15 @@
79 99 WP_CLI::error( $response['message'] );
80 100 exit;
81 101 }
82 102
83 - $progress->tick();
103 + if ( $this->out == 'view') {
104 + $progress->tick();
105 + }
84 106
85 107 // All good, run the parser
86 108 $_POST['microtime'] = $response['microtime'];
87 - $response = json_decode( codeprofiler_prepare_report(), true );
109 + $response = json_decode( CodeProfiler_helpers::codeprofiler_prepare_report(), true );
88 110 if ( $response === false ) {
89 111 $message = __('Unknown error returned by AJAX', 'code-profiler');
90 112 WP_CLI::error( $message );
91 113 exit;
@@ -94,13 +116,15 @@
94 116 WP_CLI::error( $response['message'] );
95 117 exit;
96 118 }
97 119
98 - $progress->tick();
99 - $progress->finish();
120 + if ( $this->out == 'view') {
121 + $progress->tick();
122 + $progress->finish();
123 + }
100 124
101 125 // Run the parser and show the results
102 - $this->view( $response['cp_profile'] );
126 + $this->view( $args, $assoc_args, $response['cp_profile'] );
103 127
104 128 exit;
105 129 }
106 130
@@ -108,12 +132,16 @@
108 132 /**
109 133 * Display last created profile.
110 134 *
111 135 */
112 - public function view( $profile = '') {
136 + public function view( $args = [], $assoc_args = [], $profile = '') {
113 137
114 138 $this->is_enabled();
115 139
140 + if (! empty( $assoc_args['out'] ) && in_array( $assoc_args['out'], ['json', 'csv'] ) ) {
141 + $this->out = $assoc_args['out'];
142 + }
143 +
116 144 // The profile was just created (`wp code-profiler run`)...
117 145 if (! empty( $profile ) ) {
118 146 $this->file = code_profiler_get_profile_path( $profile );
119 147 if ( $this->file === false ) {
@@ -141,16 +169,34 @@
141 169 '`'. CODE_PROFILER_UPLOAD_DIR .'/\d{10}\.\d+\.(.+?)\.slugs\.profile$`',
142 170 $this->file,
143 171 $match
144 172 );
145 - $message = sprintf( __('Viewing: %s', 'code-profiler'), $match[1] );
146 - $date = date('Y/m/d \@ H:i:s', filemtime( $this->file ) );
147 - echo WP_CLI::colorize("\n%Y$message ~ $date%n\n\n");
148 173
149 - // Display stats
150 - $summary_file = str_replace('.slugs.profile', '', $this->file );
151 - echo code_profiler_getsummarystats( $summary_file, 'text');
174 + $cp_slug = __('Slug', 'code-profiler');
175 + $cp_time = __('Execution time', 'code-profiler');
176 + $cp_name = __('Name', 'code-profiler');
177 + $cp_type = __('Type', 'code-profiler');
152 178
179 + if ( $this->out == 'view' ) {
180 + $buffer = '';
181 + $message = sprintf( __('Viewing: %s', 'code-profiler'), $match[1] );
182 + $date = date('Y/m/d \@ H:i:s', filemtime( $this->file ) );
183 + echo WP_CLI::colorize("\n%Y$message ~ $date%n\n\n");
184 + // Display stats
185 + $summary_file = str_replace('.slugs.profile', '', $this->file );
186 + echo code_profiler_getsummarystats( $summary_file, 'text');
187 + /**
188 + * CSV output.
189 + */
190 + } elseif ( $this->out == 'csv' ) {
191 + $buffer = "$cp_slug,\"$cp_time\",$cp_name,$cp_type\n";
192 + /**
193 + * JSON-encoded output.
194 + */
195 + } else {
196 + $buffer = [];
197 + }
198 +
153 199 $slugs = $this->read_profile();
154 200
155 201 $cp_options = get_option('code-profiler');
156 202
@@ -163,38 +209,58 @@
163 209 $coeff = number_format( $slugs[0][1] / $total_time * 100 );
164 210
165 211 foreach( $slugs as $k => $v ) {
166 212
167 - // Display name, time and %
168 - if ( $cp_options['display_name'] == 'slug' ) {
169 - $name = $v[0];
213 + if ( $this->out == 'csv') {
214 + $buffer .= "{$v[0]},{$v[1]},{$v[2]},{$v[3]}\n";
215 +
216 + } elseif( $this->out == 'json') {
217 + $buffer[] = [
218 + $cp_slug = $v[0],
219 + $cp_time = $v[1],
220 + $cp_name = $v[2],
221 + $cp_type = $v[3]
222 + ];
223 +
170 224 } else {
171 - $name = $v[2];
172 - }
173 - // Inform if it's the theme or a mu-plugin
174 - if ( $v[3] == 'theme') {
175 - $name .= ' (theme)';
176 - } elseif ( $v[3] == 'mu-plugin') {
177 - $name .= ' (mu-plugin)';
178 - }
225 + // Display name, time and %
226 + if ( isset( $cp_options['display_name'] ) && $cp_options['display_name'] == 'slug' ) {
227 + $name = $v[0];
228 + } else {
229 + $name = $v[2];
230 + }
231 + // Inform if it's the theme or a mu-plugin
232 + if ( $v[3] == 'theme') {
233 + $name .= ' (theme)';
234 + } elseif ( $v[3] == 'mu-plugin') {
235 + $name .= ' (mu-plugin)';
236 + }
179 237
180 - $time = number_format( $v[1], 3 );
181 - $percent = number_format( $v[1] / $total_time * 100 );
182 - $chars = number_format( $percent * 80 / $coeff );
183 - // We use `echo` instead of `WP_CLI::log` because the layout could
184 - // be all messed-up when some caching plugins such as LiteSpeed Cache
185 - // are activated.
186 - echo " $name | {$time}s | {$percent}%\n";
187 - if (! $percent ) {
188 - echo " \u{258C}\n\n";
189 - } else {
190 - $bar = '';
191 - for ( $i = 0; $i < $chars; $i++ ) {
192 - $bar .= ' ';
238 + $time = number_format( $v[1], 3 );
239 + $percent = number_format( $v[1] / $total_time * 100 );
240 + $chars = number_format( $percent * 80 / $coeff );
241 + // We use `echo` instead of `WP_CLI::log` because the layout could
242 + // be all messed-up when some caching plugins such as LiteSpeed Cache
243 + // are activated.
244 + echo " $name | {$time}s | {$percent}%\n";
245 + if (! $percent ) {
246 + echo " \u{258C}\n\n";
247 + } else {
248 + $bar = '';
249 + for ( $i = 0; $i < $chars; $i++ ) {
250 + $bar .= ' ';
251 + }
252 + echo WP_CLI::colorize(" %8$bar%n\n\n");
193 253 }
194 - echo WP_CLI::colorize(" %8$bar%n\n\n");
195 254 }
196 255 }
256 + if ( $this->out == 'csv') {
257 + echo $buffer;
258 +
259 + } elseif ( $this->out == 'json' ) {
260 + echo json_encode( $buffer );
261 + }
262 +
197 263 exit;
198 264 }
199 265
200 266
@@ -203,9 +269,9 @@
203 269 *
204 270 */
205 271 private function find_last_profile() {
206 272
207 - $profiles = glob( CODE_PROFILER_UPLOAD_DIR .'/*.slugs.profile');
273 + $profiles = code_profiler_glob( CODE_PROFILER_UPLOAD_DIR, '\.slugs\.profile$', true );
208 274
209 275 array_multisort(
210 276 array_map('filectime', $profiles ),
211 277 SORT_NUMERIC,
@@ -267,23 +333,31 @@
267 333
268 334 $this->is_enabled();
269 335
270 336 WP_CLI::log("\nCode Profiler v". CODE_PROFILER_VERSION .
271 - " (c)". date('Y') ." Jerome Bruandet & NinTechNet Limited ~ https://code-profiler.com/\n\n".
337 + " (c)". date('Y') ." Jerome Bruandet & NinTechNet Limited ~ https://nintechnet.com/codeprofiler/\n\n".
272 338 " {$this->cmd_view} ". __('View last created profile', 'code-profiler') ."\n".
273 339 " {$this->cmd_run} ". __('Run the profiler in the frontend', 'code-profiler') ."\n\n".
274 340 __('GLOBAL PARAMETERS', 'code-profiler') ."\n\n".
275 341 " --dest=<URL to profile> **". __('Pro version only', 'code-profiler') ."**\n".
276 342 " ". __('Path to the WordPress page or post to profile. If missing, profile the frontend.', 'code-profiler') ."\n\n".
277 - " --user=<id|login|email>\n".
343 + " --wpcron=<cron event> (optional)\n".
344 + " ". __('WordPress cron event to profile.', 'code-profiler') ."\n\n".
345 + " --user=<id|login|email> (optional)\n".
278 346 " ". __('Run the profiler as the corresponding WordPress user. If missing, run as an unauthenticated user.', 'code-profiler') ."\n\n".
279 - " --u=<username>\n".
280 - " ". __('HTTP Basic authentication username. You will be prompted to enter your password.', 'code-profiler') ."\n\n");
347 + " --u=<username> (optional)\n".
348 + " ". __('HTTP Basic authentication username. You will be prompted to enter your password.', 'code-profiler') ."\n\n".
349 + " --out=<json|csv> (optional)\n".
350 + " ". __('Return the results in JSON-encoded or CSV format.', 'code-profiler') ."\n\n" );
281 351 exit;
282 352 }
283 353
284 354 }
285 355
286 -WP_CLI::add_command('code-profiler', 'CodeProfiler_CLI', ['shortdesc' => __('Profile your blog with Code Profiler.', 'code-profiler') ] );
356 +WP_CLI::add_command(
357 + 'code-profiler',
358 + 'CodeProfiler_CLI',
359 + ['shortdesc' => 'Profile your blog with Code Profiler.']
360 +);
287 361
288 362 // =====================================================================
289 363 // EOF