PluginProbe
Code Profiler – WordPress Performance Profiling and Debugging Made Easy / 1.6.6
Code Profiler – WordPress Performance Profiling and Debugging Made Easy v1.6.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 1.6.8 All 40 releases
code-profiler / lib / ajax.php

ajax.php in Code Profiler – WordPress Performance Profiling and Debugging Made Easy 1.6.6, at lib/ajax.php

676 lines 20.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 +=====================================================================+
4 | ____ _ ____ __ _ _ |
5 | / ___|___ __| | ___ | _ \ _ __ ___ / _(_) | ___ _ __ |
6 | | | / _ \ / _` |/ _ \ | |_) | '__/ _ \| |_| | |/ _ \ '__| |
7 | | |__| (_) | (_| | __/ | __/| | | (_) | _| | | __/ | |
8 | \____\___/ \__,_|\___| |_| |_| \___/|_| |_|_|\___|_| |
9 | |
10 | (c) Jerome Bruandet ~ https://code-profiler.com/ |
11 +=====================================================================+
12 */
13
14 if (! defined('ABSPATH') ) {
15 die('Forbidden');
16 }
17
18 // ===================================================================== 2023-11-17
19 // Start the profiler.
20
21 add_action('wp_ajax_codeprofiler_start_profiler', 'codeprofiler_start_profiler');
22
23 function codeprofiler_start_profiler() {
24
25 $response = ['status' => 'error'];
26
27 code_profiler_hide_errors();
28
29 $cp_options = get_option('code-profiler');
30
31 code_profiler_log_debug(
32 esc_html__('Entering AJAX endpoint (profiler initialization)', 'code-profiler')
33 );
34
35 // If this is an AJAX call, make sure it comes from an admin/superadmin.
36 if ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'codeprofiler_start_profiler') {
37 // Admin/Superadmin only
38 if (! is_super_admin() ) {
39 $msg = esc_html__('You are not allowed to performed this action', 'code-profiler');
40 $response['message'] = $msg;
41 code_profiler_log_error( $msg );
42 code_profiler_wp_send_json( $response );
43 }
44 }
45
46 code_profiler_log_debug(
47 esc_html__('Verifying security nonce', 'code-profiler')
48 );
49
50 // Verify the security nonce
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 );
58 $response['message'] = $msg;
59 code_profiler_log_error( $msg );
60 code_profiler_wp_send_json( $response );
61 }
62
63 code_profiler_log_debug(
64 esc_html__('Checking MU plugin availability', 'code-profiler')
65 );
66
67 // Verify the MU plugin is loaded
68 if (! defined('CODE_PROFILER_MU_ON') ) {
69 $msg = esc_html__('The MU plugin is not loaded, please check the log', 'code-profiler');
70 $response['message'] = $msg;
71 code_profiler_log_error( $msg );
72 code_profiler_wp_send_json( $response );
73 }
74
75 code_profiler_log_debug(
76 esc_html__('Cleaning up the temporary folder', 'code-profiler')
77 );
78
79 // Clean-up temp files left in the profiles folder
80 code_profiler_cleantmpfiles();
81
82 code_profiler_log_debug(
83 esc_html__('Retrieving parameters #1', 'code-profiler')
84 );
85
86 // Frontend or backend
87 if ( empty( $_POST['where'] ) ||
88 ! in_array( $_POST['where'], ['frontend', 'backend', 'custom'] ) ) {
89
90 $msg = sprintf(
91 esc_html__('Missing or incorrect parameter (%s)', 'code-profiler'), 'where'
92 );
93 $response['message'] = $msg;
94 code_profiler_log_error( $msg );
95 code_profiler_wp_send_json( $response );
96 }
97 $cp_options['mem_where'] = $_POST['where'];
98
99 code_profiler_log_debug(
100 esc_html__('Retrieving parameters #2', 'code-profiler')
101 );
102
103 if ( empty( $_POST['post'] ) ) {
104 $msg = sprintf( esc_html__('Missing or incorrect parameter (%s)', 'code-profiler'), 'post');
105 $response['message'] = $msg;
106 code_profiler_log_error( $msg );
107 code_profiler_wp_send_json( $response );
108 }
109 $cp_options['mem_post'] = $_POST['post'];
110
111 // Make sure we have no more that 4 decimals, because when returning
112 // it via AJAX, it will display more decimals than that
113 $microtime = number_format( microtime( true ), 4, '.', '');
114
115 code_profiler_log_debug(
116 esc_html__('Retrieving parameters #3', 'code-profiler')
117 );
118
119 // Authentication
120 if ( empty( $_POST['user'] ) ||
121 ! in_array( $_POST['user'], ['authenticated', 'unauthenticated'] ) ) {
122
123 $msg = sprintf( esc_html__('Missing or incorrect parameter (%s)', 'code-profiler'), 'user');
124 $response['message'] = $msg;
125 code_profiler_log_error( $msg );
126 code_profiler_wp_send_json( $response );
127 }
128 $cp_options['mem_user'] = $_POST['user'];
129
130 code_profiler_log_debug(
131 esc_html__('Retrieving parameters #4', 'code-profiler')
132 );
133
134 if ( empty( $_POST['profile'] ) || strlen( $_POST['profile'] ) > 100 ) {
135 $profile = code_profiler_profile_name();
136 } else {
137 $profile = sanitize_file_name( $_POST['profile'] );
138 }
139
140 // URI to profile
141 $url = esc_url_raw( $_POST['post'] );
142 $siteurl = esc_html( site_url() );
143 code_profiler_log_info( sprintf(
144 /* Translators: version, site url, profile name, profile url */
145 esc_html__('Initializing Code Profiler v%s on %s. Profile: %s - %s', 'code-profiler'),
146 CODE_PROFILER_VERSION,
147 $siteurl,
148 $profile,
149 $url
150 ) );
151
152 code_profiler_log_debug(
153 esc_html__('Retrieving parameters #5', 'code-profiler')
154 );
155
156 // User-agent
157 if ( empty( $_POST['ua'] ) ) {
158 $ua = 'Firefox';
159 } else {
160 $ua = sanitize_text_field( $_POST['ua'] );
161 }
162 foreach( CODE_PROFILER_UA as $types => $types_array ) {
163 foreach( $types_array as $name => $value ) {
164 if ( $ua == $name ) {
165 $ua_signature = $value;
166 break;
167 }
168 }
169 }
170 if ( empty( $ua_signature ) ) {
171 $ua_signature = CODE_PROFILER_UA['Desktop']['Firefox'];
172 }
173 $cp_options['ua'] = $ua;
174
175 code_profiler_log_debug(
176 esc_html__('Creating security key', 'code-profiler')
177 );
178
179 // Create security key
180 $profiler_key = bin2hex( random_bytes( 16 ) );
181 $cp_options['hash'] = sha1( $profiler_key );
182
183 code_profiler_log_debug(
184 esc_html__('Building HTTP query', 'code-profiler')
185 );
186
187 // Build query
188 $url = add_query_arg( [
189 'CODE_PROFILER_ON' => $microtime,
190 'profiler_key' => $profiler_key
191 ], $url );
192
193 global $wp_version;
194 $headers = [
195 'Cache-Control' => 'no-cache, no-store, must-revalidate',
196 'Pragma' => 'no-cache',
197 'Expires' => '0',
198 'httpversion' => '1.1',
199 // Devs must be allowed to use it on localhost over TLS too
200 'sslverify' => apply_filters('https_local_ssl_verify', false ),
201 'timeout' => 300, // 300-second timeout instead of the default 5s
202 'redirection' => 0, // We don't want to be redirected
203 'headers' => [
204 // Lowercase header name
205 'code-profiler-key' => $profiler_key,
206 'accept-language' => 'en-US,en;q=0.5',
207 'user-agent' => $ua_signature
208 ]
209 ];
210
211 // Custom HTTP headers
212 if (! empty( $_POST['custom_headers'] ) ) {
213 $custom_headers = explode( PHP_EOL, trim( stripslashes( $_POST['custom_headers'] ) ) );
214 if (! empty( $custom_headers[0] ) ) {
215 code_profiler_log_debug(
216 esc_html__('Building custom HTTP headers', 'code-profiler')
217 );
218 $is_custom_headers = '';
219 foreach( $custom_headers as $custom_header ) {
220 list( $key, $value ) = explode( ':', "$custom_header:" );
221 // Lowercase header name
222 $key = trim( strtolower( $key ) );
223 $value = trim( $value );
224 // We want printable ASCII characters only
225 $value = preg_replace('/[\x00-\x1f\x7f-\xff]/', '', $value);
226 if (! empty( $key ) && ! empty( $value ) ) {
227 $headers['headers'][ $key ] = $value;
228 $is_custom_headers .= "$key: $value\n";
229 }
230 }
231 }
232 }
233 if (! empty( $is_custom_headers ) ) {
234 $cp_options['custom_headers'] = json_encode( $is_custom_headers );
235 } else {
236 unset( $cp_options['custom_headers'] );
237 }
238
239 code_profiler_log_debug(
240 esc_html__('Checking HTTP options', 'code-profiler')
241 );
242
243 // Forward basic authentication if any (not available from WP CLI)
244 if ( function_exists('apache_request_headers') ) {
245 $apache_headers = apache_request_headers();
246 if ( isset( $apache_headers['Authorization'] ) ) {
247 $headers['headers']['Authorization'] = $apache_headers['Authorization'];
248 }
249 // WP-CLI ($ wp code-profiler run --u=FOO --p=BAR)
250 } elseif ( defined('WP_CLI') && ! empty( $_POST['Authorization'] ) ) {
251 $headers['headers']['Authorization'] = $_POST['Authorization'];
252 }
253
254 if ( $_POST['user'] == 'authenticated') {
255
256 code_profiler_log_debug(
257 esc_html__('Creating authentication cookies', 'code-profiler')
258 );
259
260 // Used for authentication
261 if ( is_ssl() ) {
262 $cookie_auth = SECURE_AUTH_COOKIE;
263 $scheme = 'secure_auth';
264 } else {
265 $cookie_auth = AUTH_COOKIE;
266 $scheme = 'auth';
267 }
268
269 // Retrieve the user name (since 1.4.3)
270 if (! defined('WP_CLI') ) {
271 if ( empty( $_POST['username'] ) ) {
272 $msg = esc_html__('Missing authenticated username', 'code-profiler');
273 $response['message'] = $msg;
274 code_profiler_log_error( $msg );
275 code_profiler_wp_send_json( $response );
276 }
277 $username = sanitize_user( $_POST['username'] );
278 $user_object = get_user_by('login', $username );
279 if ( $user_object === false ) {
280 $msg = sprintf( esc_html__('User [%s] does not exist.', 'code-profiler'), $username);
281 $response['message'] = $msg;
282 code_profiler_log_error( $msg );
283 code_profiler_wp_send_json( $response );
284 }
285 $cp_options['mem_username'] = strtolower( $username );
286 $headers['cookies'][ $cookie_auth ] = wp_generate_auth_cookie(
287 $user_object->ID,
288 time() + 180,
289 $scheme
290 );
291 if ( empty( $headers['cookies'][ $cookie_auth ] ) ) {
292 $msg = esc_html__('Unable to create the authentication cookie', 'code-profiler');
293 code_profiler_log_error( $msg );
294 $response['message'] = $msg;
295 code_profiler_wp_send_json( $response );
296 }
297 $headers['cookies'][ LOGGED_IN_COOKIE ] = wp_generate_auth_cookie(
298 $user_object->ID,
299 time() + 180,
300 'logged_in'
301 );
302 if ( empty( $headers['cookies'][ LOGGED_IN_COOKIE ] ) ) {
303 $msg = esc_html__('Unable to create the "logged_in" cookie', 'code-profiler');
304 code_profiler_log_error( $msg );
305 $response['message'] = $msg;
306 code_profiler_wp_send_json( $response );
307 }
308 // WP CLI
309 } else {
310 $id = get_current_user_id();
311 $headers['cookies'][ $cookie_auth ] = wp_generate_auth_cookie(
312 $id,
313 time() + 180,
314 $scheme
315 );
316 if ( empty( $headers['cookies'][ $cookie_auth ] ) ) {
317 $msg = esc_html__('Unable to create the authentication cookie', 'code-profiler');
318 code_profiler_log_error( $msg );
319 $response['message'] = $msg;
320 code_profiler_wp_send_json( $response );
321 }
322 $headers['cookies'][ LOGGED_IN_COOKIE ] = wp_generate_auth_cookie(
323 $id,
324 time() + 180,
325 'logged_in'
326 );
327 if ( empty( $headers['cookies'][ LOGGED_IN_COOKIE ] ) ) {
328 $msg = esc_html__('Unable to create the "logged_in" cookie', 'code-profiler');
329 code_profiler_log_error( $msg );
330 $response['message'] = $msg;
331 code_profiler_wp_send_json( $response );
332 }
333 }
334 $session_id = session_id();
335 if ( $session_id !== false ) {
336 $session_name = session_name();
337 $headers['cookies'][ $session_name ] = $session_id;
338 }
339 }
340
341 if ( function_exists('opcache_reset') ) {
342 code_profiler_log_debug(
343 esc_html__('Clearing opcode cache', 'code-profiler')
344 );
345 opcache_reset();
346 }
347
348 // GET or POST method
349 if (! empty( $_POST['method'] ) && $_POST['method'] == 'post') {
350 $safe_method = 'wp_safe_remote_post';
351 $cp_options['mem_method'] = 'post';
352
353 // Content-type
354 $content_type = [
355 1 => 'application/x-www-form-urlencoded',
356 2 => 'application/json'
357 ];
358 if ( empty( $_POST['content_type'] ) ||
359 ! in_array( $_POST['content_type'], [ 1, 2 ] ) ) {
360
361 $cp_options['mem_content_type'] = 1;
362 } else {
363 $cp_options['mem_content_type'] = (int) $_POST['content_type'];
364 }
365 $headers['headers']['content-type'] = $content_type[ $cp_options['mem_content_type'] ];
366
367 // Optional POST payload
368 if (! empty( $_POST['payload'] ) ) {
369 $_payload = trim( stripslashes( $_POST['payload'] ) );
370
371 code_profiler_log_debug(
372 esc_html__('Building POST payload', 'code-profiler')
373 );
374
375 // application/x-www-form-urlencoded
376 if ( $cp_options['mem_content_type'] == 1 ) {
377 $payload_array = explode( PHP_EOL, $_payload );
378 foreach( $payload_array as $item ) {
379 $payload = explode('=', trim( $item ), 2 );
380 if ( isset( $payload[1] ) ) {
381 $payload[0] = trim( $payload[0] );
382 $payload[1] = trim( $payload[1] );
383 $headers['body'][ $payload[0] ] = $payload[1];
384 }
385 }
386 } else {
387
388 $headers['body'] = $_payload;
389 }
390 $cp_options['payload'] = json_encode( $_payload );
391
392 } else {
393 // POST request without a payload
394 unset( $cp_options['payload'] );
395 }
396
397 } else {
398 $safe_method = 'wp_safe_remote_get';
399 $cp_options['mem_method'] = 'get';
400 }
401
402 // Optional user-defined cookies
403 if (! empty( $_POST['cookies'] ) ) {
404
405 code_profiler_log_debug(
406 esc_html__('Building HTTP Cookies', 'code-profiler')
407 );
408
409 $cookies_array = explode( PHP_EOL, trim( stripslashes( $_POST['cookies'] ) ) );
410 foreach( $cookies_array as $item ) {
411 $cookie = explode('=', trim( $item ), 2 );
412 if ( isset( $cookie[1] ) ) {
413 $cookie[0] = trim( $cookie[0] );
414 $cookie[1] = trim( $cookie[1] );
415 $headers['cookies'][ $cookie[0] ] = $cookie[1];
416 }
417 }
418 $cp_options['cookies'] = json_encode( $_POST['cookies'] );
419 } else {
420 unset( $cp_options['cookies'] );
421 }
422
423 update_option('code-profiler', $cp_options );
424
425 code_profiler_log_debug(
426 esc_html__('Sending HTTP request', 'code-profiler')
427 );
428
429 // We must allow developers to run the profiler
430 // on a local IP (e.g, http://127.0.0.1/)
431 add_filter('http_request_host_is_external', '__return_true');
432 $res = $safe_method( $url, $headers );
433
434 // Connection error
435 if ( is_wp_error( $res ) ) {
436 $msg = esc_html__('Cannot connect to the requested page: %s', 'code-profiler');
437 $response['message'] = sprintf(
438 $msg,
439 esc_html( $res->get_error_message() )
440 );
441 code_profiler_log_error( sprintf( $msg, $res->get_error_message() ) );
442 code_profiler_wp_send_json( $response );
443 }
444
445 code_profiler_log_debug(
446 esc_html__('Fetching HTTP response', 'code-profiler')
447 );
448
449 // HTTP status code
450 if (! empty( $cp_options['http_response'] ) ) {
451 if ( preg_match( "/{$cp_options['http_response']}/", $res['response']['code'] ) ) {
452 $log = esc_html__(
453 'The website returned the following HTTP status code: %s %s.', 'code-profiler'
454 );
455 if ( $res['response']['code'] >= 500 ) {
456 $msg = $log .' '. esc_html__(
457 'You may find more details about this error in your PHP error log.',
458 'code-profiler'
459 );
460 } else {
461 $msg = $log .' '. esc_html__('By default, the profiler will always abort and throw an error '.
462 'if the server did not return a 200 HTTP status code. You can change that behaviour in '.
463 'the Settings section if the page you are profiling needs to return a different '.
464 'code (3xx, 4xx or 5xx).', 'code-profiler');
465 }
466 $response['message'] = sprintf(
467 $msg,
468 (int) $res['response']['code'],
469 $res['response']['message']
470 );
471 code_profiler_log_error(
472 sprintf( $log, $res['response']['code'], $res['response']['message'] )
473 );
474 code_profiler_wp_send_json( $response );
475 }
476 }
477
478 code_profiler_log_debug(
479 esc_html__('Decoding body', 'code-profiler')
480 );
481
482 // Check response
483 $message = json_decode( $res['body'], true );
484 if ( isset( $message['status'] ) && isset( $message['message'] ) ) {
485 $response['status'] = $message['status'];
486 $response['message'] = $message['message'];
487 code_profiler_wp_send_json( $response );
488 }
489 code_profiler_log_info(
490 esc_html__('Collecting data to analyze', 'code-profiler')
491 );
492 // Return success
493 $response = ['status' => 'success'];
494 $response['message'] = 'success';
495 $response['microtime'] = $microtime;
496
497 code_profiler_log_debug(
498 esc_html__('Leaving AJAX endpoint', 'code-profiler')
499 );
500
501 // AJAX action?
502 if ( defined('DOING_AJAX') && DOING_AJAX ) {
503 code_profiler_wp_send_json( $response );
504 }
505
506 return json_encode( $response );
507
508 }
509
510 // ===================================================================== 2023-11-17
511
512 add_action('wp_ajax_codeprofiler_prepare_report', 'codeprofiler_prepare_report');
513
514 function codeprofiler_prepare_report() {
515
516 $response = ['status' => 'error'];
517
518 code_profiler_log_debug(
519 esc_html__('Entering AJAX endpoint (report preparation)', 'code-profiler')
520 );
521
522 code_profiler_hide_errors();
523
524 // If this is an AJAX call, make sure it comes from an admin/superadmin.
525 if ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'codeprofiler_prepare_report') {
526 // Admin/Superadmin only
527 if (! is_super_admin() ) {
528 $msg = esc_html__('You are not allowed to performed this action', 'code-profiler');
529 $response['message'] = $msg;
530 code_profiler_log_error( $msg );
531 code_profiler_wp_send_json( $response );
532 }
533 }
534
535 code_profiler_log_debug(
536 esc_html__('Verifying security nonce', 'code-profiler')
537 );
538
539 // Verify the security nonce
540 if ( empty( $_POST['cp_nonce'] ) ||
541 ! wp_verify_nonce( $_POST['cp_nonce'], 'start_profiler_nonce') ) {
542
543 $msg = esc_html__('Missing or wrong security nonce. Reload the page and try again',
544 'code-profiler');
545 $response['message'] = $msg;
546 code_profiler_log_error( $msg );
547 code_profiler_wp_send_json( $response );
548 }
549
550 code_profiler_log_debug(
551 esc_html__('Retrieving profile ID', 'code-profiler')
552 );
553
554 if ( empty( $_POST['microtime'] ) || ! preg_match('/^\d{10}\.\d+$/', $_POST['microtime'] ) ) {
555 $msg = esc_html__('Missing parameter (microtime).', 'code-profiler');
556 $response['message'] = $msg;
557 code_profiler_log_error( $msg );
558 code_profiler_wp_send_json( $response );
559 }
560 $microtime = sanitize_text_field( $_POST['microtime'] );
561
562 code_profiler_log_debug(
563 esc_html__('Retrieving profile name', 'code-profiler')
564 );
565
566 $profile = sanitize_file_name( $_POST['profile'] );
567 if ( empty( $profile ) ) {
568 $msg = esc_html__('Missing profile name.', 'code-profiler');
569 $response['message'] = $msg;
570 code_profiler_log_error( $msg );
571 code_profiler_wp_send_json( $response );
572 }
573
574 code_profiler_log_info(
575 esc_html__('Preparing the report', 'code-profiler')
576 );
577 require 'class-report.php';
578 $report = new CodeProfiler_Report( $profile, $microtime );
579 $report->prepare_report();
580
581 // Take a 1s break so that we can spot any potential error
582 // in the backend before AJAX refresh the page
583 usleep( 1000000 );
584
585 // Clear hash
586 $cp_options = get_option('code-profiler');
587 unset( $cp_options['hash'] );
588 update_option('code-profiler', $cp_options );
589
590 code_profiler_log_info(
591 esc_html__('All done, exiting profiler', 'code-profiler')
592 );
593 $response['cp_profile'] = $microtime;
594 $response['status'] = 'success';
595 $response['message'] = 'success';
596
597 code_profiler_log_debug(
598 esc_html__('Leaving AJAX endpoint', 'code-profiler')
599 );
600
601 // AJAX action?
602 if ( defined('DOING_AJAX') && DOING_AJAX ) {
603 code_profiler_wp_send_json( $response );
604 }
605
606 return json_encode( $response );
607
608 }
609
610 // ===================================================================== 2023-11-17
611 // Rename a profile.
612
613 add_action('wp_ajax_codeprofiler_rename', 'codeprofiler_rename');
614
615 function codeprofiler_rename() {
616
617 $response = ['status' => 'error'];
618
619 code_profiler_hide_errors();
620
621 // Admin/Superadmin only
622 if (! is_super_admin() ) {
623 $response['message'] = esc_html__(
624 'You are not allowed to performed this action', 'code-profiler'
625 );
626 wp_send_json( $response );
627 }
628
629 // Verify the security nonce
630 if ( empty( $_POST['cp_nonce'] ) || ! wp_verify_nonce( $_POST['cp_nonce'], 'rename-profile') ) {
631 $response['message'] = esc_html__(
632 'Missing or wrong security nonce. Reload the page and try again', 'code-profiler'
633 );
634 wp_send_json( $response );
635 }
636
637 if ( empty( $_POST['new_name'] ) ) {
638 $response['message'] = esc_html__('Please enter a name for this profile.', 'code-profiler');
639 wp_send_json( $response );
640 }
641 $new_name = sanitize_file_name( $_POST['new_name'] );
642 if ( strlen( $new_name ) > 100 ) {
643 $new_name = substr( $new_name, 0, 100 );
644 }
645 if ( empty( $new_name ) ) {
646 $response['message'] = esc_html__('Please enter a name for this profile.', 'code-profiler');
647 wp_send_json( $response );
648 }
649
650 if ( empty( $_POST['profile'] ) || ! preg_match('/^\d{10}\.\d{4}$/', $_POST['profile'] ) ) {
651 $response['message'] = esc_html__('Missing profile identifier.', 'code-profiler');
652 wp_send_json( $response );
653 }
654 $profile = $_POST['profile'];
655
656 $glob = glob( CODE_PROFILER_UPLOAD_DIR ."/$profile*" );
657 if ( is_array( $glob ) ) {
658 foreach( $glob as $path ) {
659 // preg_quote is needed for Windows servers because ABSPATH will contain backslashes
660 if ( preg_match('`^'. preg_quote( CODE_PROFILER_UPLOAD_DIR ) .
661 '/(\d{10}\.\d{4})\..+?\.([a-z]+?\.profile)$`', $path, $match ) ) {
662
663 rename( $path, CODE_PROFILER_UPLOAD_DIR . "/{$match[1]}.$new_name.{$match[2]}" );
664 }
665 }
666 }
667
668 $response['status'] = 'success';
669 $response['newname'] = $new_name;
670 wp_send_json( $response );
671
672 }
673
674 // =====================================================================
675 // EOF
676