PluginProbe
Code Profiler – WordPress Performance Profiling and Debugging Made Easy / 1.7.4
Code Profiler – WordPress Performance Profiling and Debugging Made Easy v1.7.4
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 1.6.8 All 40 releases
← All changes | lib/ajax.php +307 -78 1.5.51.7.4 View file →
@@ -6,15 +6,17 @@
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 -if (! defined('ABSPATH') ) { die('Forbidden'); }
14 +if (! defined('ABSPATH') ) {
15 + die('Forbidden');
16 +}
15 17
16 -// =====================================================================
18 +// ===================================================================== 2023-11-17
17 19 // Start the profiler.
18 20
19 21 add_action('wp_ajax_codeprofiler_start_profiler', 'codeprofiler_start_profiler');
20 22
@@ -21,8 +23,10 @@
21 23 function codeprofiler_start_profiler() {
22 24
23 25 $response = ['status' => 'error'];
24 26
27 + code_profiler_hide_errors();
28 +
25 29 $cp_options = get_option('code-profiler');
26 30
27 31 code_profiler_log_debug(
28 32 esc_html__('Entering AJAX endpoint (profiler initialization)', 'code-profiler')
@@ -43,10 +47,15 @@
43 47 esc_html__('Verifying security nonce', 'code-profiler')
44 48 );
45 49
46 50 // Verify the security nonce
47 - if ( empty( $_POST['cp_nonce'] ) || ! wp_verify_nonce( $_POST['cp_nonce'], 'start_profiler_nonce') ) {
48 - $msg = esc_html__('Missing or wrong security nonce. Reload the page and try again', 'code-profiler');
51 + if ( empty( $_POST['cp_nonce'] ) ||
52 + ! wp_verify_nonce( $_POST['cp_nonce'], 'start_profiler_nonce') ) {
53 +
54 + $msg = esc_html__(
55 + 'Missing or wrong security nonce. Reload the page and try again',
56 + 'code-profiler'
57 + );
49 58 $response['message'] = $msg;
50 59 code_profiler_log_error( $msg );
51 60 code_profiler_wp_send_json( $response );
52 61 }
@@ -63,21 +72,18 @@
63 72 code_profiler_wp_send_json( $response );
64 73 }
65 74
66 75 code_profiler_log_debug(
67 - esc_html__('Cleaning up the temporary folder', 'code-profiler')
68 - );
69 -
70 - // Clean-up temp files left in the profiles folder
71 - code_profiler_cleantmpfiles();
72 -
73 - code_profiler_log_debug(
74 76 esc_html__('Retrieving parameters #1', 'code-profiler')
75 77 );
76 78
77 79 // Frontend or backend
78 - if ( empty( $_POST['where'] ) || ! in_array( $_POST['where'], ['frontend', 'backend', 'custom'] ) ) {
79 - $msg = sprintf( esc_html__('Missing or incorrect parameter (%s)', 'code-profiler'), 'where');
80 + if ( empty( $_POST['where'] ) ||
81 + ! in_array( $_POST['where'], ['frontend', 'backend', 'custom'] ) ) {
82 +
83 + $msg = sprintf(
84 + esc_html__('Missing or incorrect parameter (%s)', 'code-profiler'), 'where'
85 + );
80 86 $response['message'] = $msg;
81 87 code_profiler_log_error( $msg );
82 88 code_profiler_wp_send_json( $response );
83 89 }
@@ -103,13 +109,10 @@
103 109 esc_html__('Retrieving parameters #3', 'code-profiler')
104 110 );
105 111
106 112 // Authentication
107 - if ( empty( $_POST['user'] ) || ! in_array( $_POST['user'], ['authenticated', 'unauthenticated'] ) ) {
108 - $msg = sprintf( esc_html__('Missing or incorrect parameter (%s)', 'code-profiler'), 'user');
109 - $response['message'] = $msg;
110 - code_profiler_log_error( $msg );
111 - code_profiler_wp_send_json( $response );
113 + if ( empty( $_POST['user'] ) || $_POST['user'] != 'authenticated' ) {
114 + $_POST['user'] = 'unauthenticated';
112 115 }
113 116 $cp_options['mem_user'] = $_POST['user'];
114 117
115 118 code_profiler_log_debug(
@@ -122,14 +125,17 @@
122 125 $profile = sanitize_file_name( $_POST['profile'] );
123 126 }
124 127
125 128 // URI to profile
126 - $url = esc_url_raw( $_POST['post'] );
129 + $url = esc_url_raw( $_POST['post'] );
130 + $siteurl = esc_html( site_url() );
127 131 code_profiler_log_info( sprintf(
128 - esc_html__('Initializing Code Profiler v%s for %s (profile: %s)', 'code-profiler'),
132 + /* Translators: version, site url, profile name, profile url */
133 + esc_html__('Initializing Code Profiler v%s on %s. Profile: %s - %s', 'code-profiler'),
129 134 CODE_PROFILER_VERSION,
130 - $url,
131 - $profile
135 + $siteurl,
136 + $profile,
137 + $url
132 138 ) );
133 139
134 140 code_profiler_log_debug(
135 141 esc_html__('Retrieving parameters #5', 'code-profiler')
@@ -153,8 +159,27 @@
153 159 $ua_signature = CODE_PROFILER_UA['Desktop']['Firefox'];
154 160 }
155 161 $cp_options['ua'] = $ua;
156 162
163 + // Theme
164 + $themes = code_profiler_get_themes();
165 + if ( empty( $_POST['theme'] ) || empty( $themes[ $_POST['theme'] ] ) ) {
166 + $theme = '';
167 + unset( $cp_options['mem_theme'] );
168 + } else {
169 + code_profiler_log_debug(
170 + esc_html__('Retrieving parameters #6', 'code-profiler')
171 + );
172 + $theme = $_POST['theme'];
173 + $cp_options['mem_theme'] = $theme;
174 + // Append the template to the stylesheet
175 + if (! empty( $themes[ $theme ]['t'] ) ) {
176 + $theme .= "::{$themes[ $theme ]['t']}";
177 + } else {
178 + $theme .= "::$theme";
179 + }
180 + }
181 +
157 182 code_profiler_log_debug(
158 183 esc_html__('Creating security key', 'code-profiler')
159 184 );
160 185
@@ -159,15 +184,18 @@
159 184 );
160 185
161 186 // Create security key
162 187 $profiler_key = bin2hex( random_bytes( 16 ) );
163 - $cp_options['hash'] = sha1( $profiler_key );
188 + touch( CODE_PROFILER_UPLOAD_DIR .'/key_'. sha1( $profiler_key ) .'.tmp');
164 189
165 190 code_profiler_log_debug(
166 191 esc_html__('Building HTTP query', 'code-profiler')
167 192 );
168 193
169 - // Build query
194 + /**
195 + * Build the query.
196 + */
197 + $raw_url = $url;
170 198 $url = add_query_arg( [
171 199 'CODE_PROFILER_ON' => $microtime,
172 200 'profiler_key' => $profiler_key
173 201 ], $url );
@@ -182,14 +210,47 @@
182 210 'sslverify' => apply_filters('https_local_ssl_verify', false ),
183 211 'timeout' => 300, // 300-second timeout instead of the default 5s
184 212 'redirection' => 0, // We don't want to be redirected
185 213 'headers' => [
186 - 'code-profiler-key' => $profiler_key,
187 - 'Accept-Language' => 'en-US,en;q=0.5',
188 - 'User-Agent' => $ua_signature
214 + // Lowercase header name
215 + 'code-profiler-key' => $profiler_key,
216 + 'accept-language' => 'en-US,en;q=0.5',
217 + 'user-agent' => $ua_signature,
218 + 'theme' => $theme
189 219 ]
190 220 ];
191 221
222 + // Custom HTTP headers
223 + if (! empty( $_POST['custom_headers'] ) ) {
224 + $custom_headers = explode( PHP_EOL, trim( stripslashes( $_POST['custom_headers'] ) ) );
225 + if (! empty( $custom_headers[0] ) ) {
226 + code_profiler_log_debug(
227 + esc_html__('Building custom HTTP headers', 'code-profiler')
228 + );
229 + $is_custom_headers = '';
230 + foreach( $custom_headers as $custom_header ) {
231 + if ( strpos( $custom_header, ':') === false ) {
232 + continue;
233 + }
234 + list( $key, $value ) = explode(':', $custom_header, 2 );
235 + // Lowercase header name
236 + $key = trim( strtolower( $key ) );
237 + $value = trim( $value );
238 + // We want printable ASCII characters only
239 + $value = code_profiler_ASCII_filter( $value );
240 + if (! empty( $key ) && ! empty( $value ) ) {
241 + $headers['headers'][ $key ] = $value;
242 + $is_custom_headers .= "$key: $value\n";
243 + }
244 + }
245 + }
246 + }
247 + if (! empty( $is_custom_headers ) ) {
248 + $cp_options['custom_headers'] = json_encode( $is_custom_headers );
249 + } else {
250 + unset( $cp_options['custom_headers'] );
251 + }
252 +
192 253 code_profiler_log_debug(
193 254 esc_html__('Checking HTTP options', 'code-profiler')
194 255 );
195 256
@@ -212,12 +273,12 @@
212 273
213 274 // Used for authentication
214 275 if ( is_ssl() ) {
215 276 $cookie_auth = SECURE_AUTH_COOKIE;
216 - $scheme = 'secure_auth';
277 + $scheme = 'secure_auth';
217 278 } else {
218 279 $cookie_auth = AUTH_COOKIE;
219 - $scheme = 'auth';
280 + $scheme = 'auth';
220 281 }
221 282
222 283 // Retrieve the user name (since 1.4.3)
223 284 if (! defined('WP_CLI') ) {
@@ -234,10 +295,14 @@
234 295 $response['message'] = $msg;
235 296 code_profiler_log_error( $msg );
236 297 code_profiler_wp_send_json( $response );
237 298 }
238 - $cp_options['mem_username'] = strtolower( $username );
239 - $headers['cookies'][ $cookie_auth ] = wp_generate_auth_cookie( $user_object->ID, time() + 180, $scheme );
299 + $cp_options['mem_username'] = strtolower( $username );
300 + $headers['cookies'][ $cookie_auth ] = wp_generate_auth_cookie(
301 + $user_object->ID,
302 + time() + 180,
303 + $scheme
304 + );
240 305 if ( empty( $headers['cookies'][ $cookie_auth ] ) ) {
241 306 $msg = esc_html__('Unable to create the authentication cookie', 'code-profiler');
242 307 code_profiler_log_error( $msg );
243 308 $response['message'] = $msg;
@@ -242,9 +307,13 @@
242 307 code_profiler_log_error( $msg );
243 308 $response['message'] = $msg;
244 309 code_profiler_wp_send_json( $response );
245 310 }
246 - $headers['cookies'][ LOGGED_IN_COOKIE ] = wp_generate_auth_cookie( $user_object->ID, time() + 180, 'logged_in');
311 + $headers['cookies'][ LOGGED_IN_COOKIE ] = wp_generate_auth_cookie(
312 + $user_object->ID,
313 + time() + 180,
314 + 'logged_in'
315 + );
247 316 if ( empty( $headers['cookies'][ LOGGED_IN_COOKIE ] ) ) {
248 317 $msg = esc_html__('Unable to create the "logged_in" cookie', 'code-profiler');
249 318 code_profiler_log_error( $msg );
250 319 $response['message'] = $msg;
@@ -251,10 +320,14 @@
251 320 code_profiler_wp_send_json( $response );
252 321 }
253 322 // WP CLI
254 323 } else {
255 - $id = get_current_user_id();
256 - $headers['cookies'][ $cookie_auth ] = wp_generate_auth_cookie( $id, time() + 180, $scheme );
324 + $id = get_current_user_id();
325 + $headers['cookies'][ $cookie_auth ] = wp_generate_auth_cookie(
326 + $id,
327 + time() + 180,
328 + $scheme
329 + );
257 330 if ( empty( $headers['cookies'][ $cookie_auth ] ) ) {
258 331 $msg = esc_html__('Unable to create the authentication cookie', 'code-profiler');
259 332 code_profiler_log_error( $msg );
260 333 $response['message'] = $msg;
@@ -259,9 +332,13 @@
259 332 code_profiler_log_error( $msg );
260 333 $response['message'] = $msg;
261 334 code_profiler_wp_send_json( $response );
262 335 }
263 - $headers['cookies'][ LOGGED_IN_COOKIE ] = wp_generate_auth_cookie( $id, time() + 180, 'logged_in');
336 + $headers['cookies'][ LOGGED_IN_COOKIE ] = wp_generate_auth_cookie(
337 + $id,
338 + time() + 180,
339 + 'logged_in'
340 + );
264 341 if ( empty( $headers['cookies'][ LOGGED_IN_COOKIE ] ) ) {
265 342 $msg = esc_html__('Unable to create the "logged_in" cookie', 'code-profiler');
266 343 code_profiler_log_error( $msg );
267 344 $response['message'] = $msg;
@@ -267,12 +344,12 @@
267 344 $response['message'] = $msg;
268 345 code_profiler_wp_send_json( $response );
269 346 }
270 347 }
271 - $session_id = session_id();
348 + $session_id = session_id();
272 349 if ( $session_id !== false ) {
273 - $session_name = session_name();
274 - $headers['cookies'][ $session_name ] = $session_id;
350 + $session_name = session_name();
351 + $headers['cookies'][ $session_name ] = $session_id;
275 352 }
276 353 }
277 354
278 355 if ( function_exists('opcache_reset') ) {
@@ -283,37 +360,58 @@
283 360 }
284 361
285 362 // GET or POST method
286 363 if (! empty( $_POST['method'] ) && $_POST['method'] == 'post') {
287 - $safe_method = 'wp_safe_remote_post';
288 - $cp_options['mem_method'] = 'post';
364 + $safe_method = 'wp_safe_remote_post';
365 + $cp_options['mem_method'] = 'post';
289 366
367 + // Content-type
368 + $content_type = [
369 + 1 => 'application/x-www-form-urlencoded',
370 + 2 => 'application/json'
371 + ];
372 + if ( empty( $_POST['content_type'] ) ||
373 + ! in_array( $_POST['content_type'], [ 1, 2 ] ) ) {
374 +
375 + $cp_options['mem_content_type'] = 1;
376 + } else {
377 + $cp_options['mem_content_type'] = (int) $_POST['content_type'];
378 + }
379 + $headers['headers']['content-type'] = $content_type[ $cp_options['mem_content_type'] ];
380 +
290 381 // Optional POST payload
291 382 if (! empty( $_POST['payload'] ) ) {
383 + $_payload = trim( stripslashes( $_POST['payload'] ) );
292 384
293 385 code_profiler_log_debug(
294 386 esc_html__('Building POST payload', 'code-profiler')
295 387 );
296 388
297 - $payload_array = explode( PHP_EOL, trim( $_POST['payload'] ) );
298 - foreach( $payload_array as $item ) {
299 - $payload = explode('=', trim( $item ), 2 );
300 - if ( isset( $payload[1] ) ) {
301 - $payload[0] = trim( $payload[0] );
302 - $payload[1] = trim( $payload[1] );
303 - $headers['body'][ $payload[0] ] = $payload[1];
389 + // application/x-www-form-urlencoded
390 + if ( $cp_options['mem_content_type'] == 1 ) {
391 + $payload_array = explode( PHP_EOL, $_payload );
392 + foreach( $payload_array as $item ) {
393 + $payload = explode('=', trim( $item ), 2 );
394 + if ( isset( $payload[1] ) ) {
395 + $payload[0] = trim( $payload[0] );
396 + $payload[1] = trim( $payload[1] );
397 + $headers['body'][ $payload[0] ] = $payload[1];
398 + }
304 399 }
400 + } else {
401 +
402 + $headers['body'] = $_payload;
305 403 }
306 - $cp_options['payload'] = json_encode( $_POST['payload'] );
307 - $cp_options['mem_payload'] = $_POST['payload'];
404 + $cp_options['payload'] = json_encode( $_payload );
405 +
308 406 } else {
309 407 // POST request without a payload
310 408 unset( $cp_options['payload'] );
311 - $cp_options['mem_payload'] = '';
312 409 }
410 +
313 411 } else {
314 - $safe_method = 'wp_safe_remote_get';
315 - $cp_options['mem_method'] = 'get';
412 + $safe_method = 'wp_safe_remote_get';
413 + $cp_options['mem_method'] = 'get';
316 414 }
317 415
318 416 // Optional user-defined cookies
319 417 if (! empty( $_POST['cookies'] ) ) {
@@ -321,9 +419,9 @@
321 419 code_profiler_log_debug(
322 420 esc_html__('Building HTTP Cookies', 'code-profiler')
323 421 );
324 422
325 - $cookies_array = explode( PHP_EOL, trim( $_POST['cookies'] ) );
423 + $cookies_array = explode( PHP_EOL, trim( stripslashes( $_POST['cookies'] ) ) );
326 424 foreach( $cookies_array as $item ) {
327 425 $cookie = explode('=', trim( $item ), 2 );
328 426 if ( isset( $cookie[1] ) ) {
329 427 $cookie[0] = trim( $cookie[0] );
@@ -335,8 +433,32 @@
335 433 } else {
336 434 unset( $cp_options['cookies'] );
337 435 }
338 436
437 + /**
438 + * Optional file and folder exclusions.
439 + */
440 + $tmp_exclusions = [];
441 + if (! empty( $_POST['exclusions'] ) ) {
442 + $tmp_array = explode( PHP_EOL, trim( stripslashes( $_POST['exclusions'] ) ) );
443 + foreach( $tmp_array as $item ) {
444 + $item = trim( code_profiler_ASCII_filter( $item ) );
445 + if ( $item ) {
446 + $tmp_exclusions[] = $item;
447 + }
448 + }
449 + }
450 + /**
451 + * Remove duplicates.
452 + */
453 + $exclusions = array_unique( $tmp_exclusions );
454 +
455 + if ( $exclusions) {
456 + $cp_options['exclusions'] = json_encode( $exclusions );
457 + } else {
458 + unset( $cp_options['exclusions'] );
459 + }
460 +
339 461 update_option('code-profiler', $cp_options );
340 462
341 463 code_profiler_log_debug(
342 464 esc_html__('Sending HTTP request', 'code-profiler')
@@ -361,20 +483,103 @@
361 483 code_profiler_log_debug(
362 484 esc_html__('Fetching HTTP response', 'code-profiler')
363 485 );
364 486
487 + /**
488 + * Always log last HTTP response headers and body,
489 + * except sensitive data (cookies & PHP session ID).
490 + */
491 + if ( isset( $res['headers'] ) && isset( $res['body'] ) ) {
492 + /**
493 + * Search for an existing log or create it.
494 + */
495 + $last_log = code_profiler_glob(
496 + CODE_PROFILER_UPLOAD_DIR,
497 + '^last_request\.\d+?\.\d+?\.log$',
498 + true
499 + );
500 + if ( empty( $last_log[0] ) ) {
501 + $last_log[0] = CODE_PROFILER_UPLOAD_DIR .'/last_request.'. microtime( true ) .'.log';
502 + }
503 + /**
504 + * Parse headers.
505 + */
506 + $headers = "HTTP {$res['response']['code']} {$res['response']['message']}\n";
507 +
508 + foreach( $res['headers'] as $key => $value ) {
509 + /**
510 + * Remove cookies.
511 + */
512 + if ( $key == 'set-cookie') {
513 + $headers .= ucfirst( $key ) .': *** '. __('Removed', 'code-profiler') ." ***\n";
514 + } else {
515 + /**
516 + * HTTP headers can contain arrays.
517 + */
518 + if ( is_array( $value ) ) {
519 + foreach( $value as $k => $v ) {
520 + $headers .= ucfirst( $key ) .": $v\n";
521 + }
522 + } else {
523 + $headers .= ucfirst( $key ) .": $value\n";
524 + }
525 + }
526 + }
527 + /**
528 + * Save to the log.
529 + */
530 + file_put_contents( $last_log[0],
531 + "==================================================\n".
532 + __('Requested page:', 'code-profiler') ."\n\n".
533 + "$raw_url\n".
534 + "==================================================\n".
535 + __('Response headers:', 'code-profiler') ."\n\n".
536 + $headers .
537 + "==================================================\n".
538 + __('Response body:', 'code-profiler') ."\n\n".
539 + print_r( $res['body'], true ).
540 + "\n==================================================\n"
541 + );
542 + }
543 +
365 544 // HTTP status code
366 545 if (! empty( $cp_options['http_response'] ) ) {
367 546 if ( preg_match( "/{$cp_options['http_response']}/", $res['response']['code'] ) ) {
368 - $msg = esc_html__('The website returned the following HTTP status code: %s %s.', 'code-profiler').
369 - ' '.
370 - esc_html__('By default, the profiler will always abort and throw an error if the server did not return a 200 HTTP status code. You can change that behaviour in the Settings section if the page you are profiling needs to return a different code (3xx, 4xx or 5xx).', 'code-profiler');
547 +
548 + $msg = '';
549 +
550 + $log = esc_html__(
551 + /* Translators: HTTP response code and message */
552 + 'The website returned the following HTTP status code: %s %s.', 'code-profiler'
553 + );
554 +
555 + if ( $res['response']['code'] < 500 ) {
556 + $log .= ' '. esc_html__('By default, the profiler will always abort and throw an error if the server did not return a 200 HTTP status code. You can change that behaviour in the "Settings" section if the page you are profiling needs to return a different code (3xx, 4xx or 5xx).', 'code-profiler');
557 + }
558 +
559 + $msg .= $log .' '. esc_html__('You may find more details about this error in your PHP error log and/or in the "Logs" section.', 'code-profiler');
560 +
371 561 $response['message'] = sprintf(
372 562 $msg,
373 563 (int) $res['response']['code'],
374 - esc_html( $res['response']['message'] )
564 + $res['response']['message']
375 565 );
376 - code_profiler_log_error( sprintf( $msg, $res['response']['code'], $res['response']['message'] ) );
566 + code_profiler_log_error(
567 + sprintf( $log, $res['response']['code'], $res['response']['message'] )
568 + );
569 +
570 + // If it is a 301/302 redirection, we write the new URL to the log
571 + if ( in_array( $res['response']['code'], [301, 302] ) &&
572 + isset( $res['headers']['location'] ) ) {
573 +
574 + code_profiler_log_error(
575 + sprintf(
576 + /* Translators: URL */
577 + esc_html__('The URL redirects to: %s', 'code-profiler'),
578 + $res['headers']['location']
579 + )
580 + );
581 + }
377 582 code_profiler_wp_send_json( $response );
378 583 }
379 584 }
380 585
@@ -409,9 +614,9 @@
409 614 return json_encode( $response );
410 615
411 616 }
412 617
413 -// =====================================================================
618 +// ===================================================================== 2023-11-17
414 619
415 620 add_action('wp_ajax_codeprofiler_prepare_report', 'codeprofiler_prepare_report');
416 621
417 622 function codeprofiler_prepare_report() {
@@ -417,12 +622,8 @@
417 622 function codeprofiler_prepare_report() {
418 623
419 624 $response = ['status' => 'error'];
420 625
421 - code_profiler_log_debug(
422 - esc_html__('Entering AJAX endpoint (report preparation)', 'code-profiler')
423 - );
424 -
425 626 // If this is an AJAX call, make sure it comes from an admin/superadmin.
426 627 if ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'codeprofiler_prepare_report') {
427 628 // Admin/Superadmin only
428 629 if (! is_super_admin() ) {
@@ -433,14 +634,23 @@
433 634 }
434 635 }
435 636
436 637 code_profiler_log_debug(
638 + esc_html__('Entering AJAX endpoint (report preparation)', 'code-profiler')
639 + );
640 +
641 + code_profiler_hide_errors();
642 +
643 + code_profiler_log_debug(
437 644 esc_html__('Verifying security nonce', 'code-profiler')
438 645 );
439 646
440 647 // Verify the security nonce
441 - if ( empty( $_POST['cp_nonce'] ) || ! wp_verify_nonce( $_POST['cp_nonce'], 'start_profiler_nonce') ) {
442 - $msg = esc_html__('Missing or wrong security nonce. Reload the page and try again', 'code-profiler');
648 + if ( empty( $_POST['cp_nonce'] ) ||
649 + ! wp_verify_nonce( $_POST['cp_nonce'], 'start_profiler_nonce') ) {
650 +
651 + $msg = esc_html__('Missing or wrong security nonce. Reload the page and try again',
652 + 'code-profiler');
443 653 $response['message'] = $msg;
444 654 code_profiler_log_error( $msg );
445 655 code_profiler_wp_send_json( $response );
446 656 }
@@ -477,15 +687,10 @@
477 687 $report->prepare_report();
478 688
479 689 // Take a 1s break so that we can spot any potential error
480 690 // in the backend before AJAX refresh the page
481 - usleep(1000000);
691 + usleep( 1000000 );
482 692
483 - // Clear hash
484 - $cp_options = get_option('code-profiler');
485 - unset( $cp_options['hash'] );
486 - update_option('code-profiler', $cp_options );
487 -
488 693 code_profiler_log_info(
489 694 esc_html__('All done, exiting profiler', 'code-profiler')
490 695 );
491 696 $response['cp_profile'] = $microtime;
@@ -504,9 +709,9 @@
504 709 return json_encode( $response );
505 710
506 711 }
507 712
508 -// =====================================================================
713 +// ===================================================================== 2023-11-17
509 714 // Rename a profile.
510 715
511 716 add_action('wp_ajax_codeprofiler_rename', 'codeprofiler_rename');
512 717
@@ -513,17 +718,23 @@
513 718 function codeprofiler_rename() {
514 719
515 720 $response = ['status' => 'error'];
516 721
722 + code_profiler_hide_errors();
723 +
517 724 // Admin/Superadmin only
518 725 if (! is_super_admin() ) {
519 - $response['message'] = esc_html__('You are not allowed to performed this action', 'code-profiler');
726 + $response['message'] = esc_html__(
727 + 'You are not allowed to performed this action.', 'code-profiler'
728 + );
520 729 wp_send_json( $response );
521 730 }
522 731
523 732 // Verify the security nonce
524 733 if ( empty( $_POST['cp_nonce'] ) || ! wp_verify_nonce( $_POST['cp_nonce'], 'rename-profile') ) {
525 - $response['message'] = esc_html__('Missing or wrong security nonce. Reload the page and try again', 'code-profiler');
734 + $response['message'] = esc_html__(
735 + 'Missing or wrong security nonce. Reload the page and try again.', 'code-profiler'
736 + );
526 737 wp_send_json( $response );
527 738 }
528 739
529 740 if ( empty( $_POST['new_name'] ) ) {
@@ -544,16 +755,34 @@
544 755 wp_send_json( $response );
545 756 }
546 757 $profile = $_POST['profile'];
547 758
548 - $glob = glob( CODE_PROFILER_UPLOAD_DIR ."/$profile*" );
759 + $glob = code_profiler_glob( CODE_PROFILER_UPLOAD_DIR, "^$profile", true );
760 +
761 + $res = false;
762 +
549 763 if ( is_array( $glob ) ) {
550 764 foreach( $glob as $path ) {
551 765 // preg_quote is needed for Windows servers because ABSPATH will contain backslashes
552 - if ( preg_match('`^'. preg_quote( CODE_PROFILER_UPLOAD_DIR ) .'/(\d{10}\.\d{4})\..+?\.([a-z]+?\.profile)$`', $path, $match ) ) {
553 - rename( $path, CODE_PROFILER_UPLOAD_DIR . "/{$match[1]}.$new_name.{$match[2]}" );
766 + if ( preg_match('`^'. preg_quote( CODE_PROFILER_UPLOAD_DIR . DIRECTORY_SEPARATOR ) .
767 + '(\d{10}\.\d{4})\..+?\.([a-z]+?\.profile)$`', $path, $match ) ) {
768 +
769 + $res = rename( $path, CODE_PROFILER_UPLOAD_DIR . "/{$match[1]}.$new_name.{$match[2]}" );
770 + if ( $res === false ) {
771 + $response['message'] = esc_html__(
772 + 'The operation failed.', 'code-profiler'
773 + );
774 + wp_send_json( $response );
775 + }
554 776 }
555 777 }
778 + }
779 +
780 + if ( $res === false ) {
781 + $response['message'] = esc_html__(
782 + 'The operation failed.', 'code-profiler'
783 + );
784 + wp_send_json( $response );
556 785 }
557 786
558 787 $response['status'] = 'success';
559 788 $response['newname'] = $new_name;