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/helper.php +374 -87 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') ) {
@@ -19,58 +19,99 @@
19 19 // Various constants
20 20
21 21 // The profiles directory can be defined in the wp-config.php script
22 22 if (! defined('CODE_PROFILER_UPLOAD_DIR') ) {
23 - $upload_dir = wp_upload_dir();
23 + // When running Code Profiler via WP CLI on a child site of a multisite installation,
24 + // we need to get the main site upload folder otherwise wp_upload_dir will return
25 + // the child site's
26 + if ( is_multisite() && ! ( is_main_network() && is_main_site() && defined('MULTISITE') ) ) {
27 + $upload_dir = code_profiler_upload_dir();
28 + } else {
29 + $upload_dir = wp_upload_dir();
30 + }
24 31 define('CODE_PROFILER_UPLOAD_DIR', $upload_dir['basedir'] .'/code-profiler');
25 32 }
26 33 define('CODE_PROFILER_LOG', CODE_PROFILER_UPLOAD_DIR .'/log.php');
27 34 define('CODE_PROFILER_TMP_IOSTATS_LOG', 'iostats.tmp');
28 35 define('CODE_PROFILER_TMP_SUMMARY_LOG', 'summary.tmp');
36 +define('CODE_PROFILER_TMP_RERUN_LOG', 'rerun.tmp');
29 37 define('CODE_PROFILER_TMP_CALLS_LOG', 'calls.tmp');
30 38 define('CODE_PROFILER_TMP_DISKIO_LOG', 'diskio.tmp');
31 39 define('CODE_PROFILER_TMP_CONNECTIONS_LOG', 'connections.tmp');
32 40 define('CODE_PROFILER_UPDATE_NOTICE', '<div class="updated notice is-dismissible"><p>%s</p></div>');
33 41 define('CODE_PROFILER_ERROR_NOTICE', '<div class="error notice is-dismissible"><p>%s</p></div>');
34 -global $wp_version;
35 -if (! defined('CODE_PROFILER_UA') ) { // UA signatures can be user-defined in the wp-config.php
36 - define ('CODE_PROFILER_UA', [
37 - esc_html__('Desktop', 'code-profiler') => [
38 - 'Firefox' => 'Mozilla/5.0 (Linux x86_64; rv:110.0) Gecko/20100101 Firefox/110.0',
39 - 'Chrome' => 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko)'.
40 - ' Chrome/111.0.0.0 Safari/537.36',
41 - 'Edge' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,'.
42 - ' like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/110.0.1587.63'
43 - ],
44 - esc_html__('Mobile', 'code-profiler') => [
45 - 'Android Phone' => 'Mozilla/5.0 (Android 13; Mobile; rv:68.0) Gecko/68.0 Firefox/110.0',
46 - 'Android Tablet' => 'Mozilla/5.0 (Linux; Android 13.0; SAMSUNG-SM-T377A Build/NMF26X)'.
47 - ' AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Mobile Safari/537.36',
48 - 'iPhone' => 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_3_1 like Mac OS X) AppleWebKit/605.1.15'.
49 - ' (KHTML, like Gecko) Version/16.3 Mobile/15E148 Safari/604.1',
50 - 'iPad' => 'Mozilla/5.0 (iPad; CPU OS 16_3_1 like Mac OS X) AppleWebKit/605.1.15'.
51 - ' (KHTML, like Gecko) GSA/213.0.449417121 Mobile/15E148 Safari/605.1.15'
52 - ],
53 - esc_html__('Bot', 'code-profiler') => [
54 - 'Google Bot' => 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)',
55 - 'WordPress' => 'Mozilla/5.0 (compatible; CodeProfiler for WordPress/'. $wp_version .
56 - '; https://code-profiler.com/)'
57 - ]
42 +define('CODE_PROFILER_WARNING_NOTICE', '<div class="notice notice-warning"><p>%s</p></div>');
43 +if (! defined('CODE_PROFILER_MUPLUGIN') ) {
44 + // MU plugin's name can be defined in the wp-config.php
45 + define('CODE_PROFILER_MUPLUGIN', '0----code-profiler.php');
46 +}
58 47
59 - ] );
48 +/**
49 + * Since WP 6.7, translation loading must not be triggered too early.
50 + */
51 +add_action('init', 'code_profiler_i18n_constants');
52 +function code_profiler_i18n_constants() {
53 +
54 + global $wp_version;
55 + if (! defined('CODE_PROFILER_UA') ) { // UA signatures can be user-defined in the wp-config.php
56 + define ('CODE_PROFILER_UA', [
57 + esc_html__('Desktop', 'code-profiler') => [
58 + 'Firefox' => 'Mozilla/5.0 (Linux x86_64; rv:149.0) Gecko/20100101 Firefox/149.0',
59 + 'Chrome' => 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML,'.
60 + ' like Gecko) Chrome/147.0.0.0 Safari/537.36',
61 + 'Edge' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,'.
62 + ' like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/Chrome/147.0.7727.50'
63 + ],
64 + esc_html__('Mobile', 'code-profiler') => [
65 + 'Android Phone' => 'Mozilla/5.0 (Android 16; Mobile; rv:68.0) Gecko/68.0 Firefox/149.0',
66 + 'Android Tablet' => 'Mozilla/5.0 (Linux; Android 16.0; SAMSUNG-SM-T377A Build/NMF26X)'.
67 + ' AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.7727.50 Mobile Safari/537.36',
68 + 'iPhone' => 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_7_7 like Mac OS X) AppleWebKit/605.1.15'.
69 + ' (KHTML, like Gecko) Version/26.0 Mobile/15E148 Safari/604.1',
70 + 'iPad' => 'Mozilla/5.0 (iPad; CPU OS 18_7_7 like Mac OS X) AppleWebKit/605.1.15'.
71 + ' (KHTML, like Gecko) GSA/213.0.449417121 Mobile/15E148 Safari/605.1.15'
72 + ],
73 + esc_html__('Bot', 'code-profiler') => [
74 + 'Google Bot' => 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)',
75 + 'WordPress' => 'Mozilla/5.0 (compatible; CodeProfiler for WordPress/'. $wp_version .
76 + '; https://nintechnet.com/codeprofiler/)'
77 + ]
78 +
79 + ] );
80 + }
81 + define('CODE_PROFILER_ACCURACY', [
82 + 1 => __('Highest', 'code-profiler'),
83 + 5 => __('High', 'code-profiler'),
84 + 10 => __('Moderate', 'code-profiler'),
85 + 15 => __('Low', 'code-profiler'),
86 + 20 => __('Lowest', 'code-profiler')
87 + ]);
60 88 }
61 89
62 -if (! defined('CODE_PROFILER_MUPLUGIN') ) {
63 - // MU plugin's name can be defined in the wp-config.php
64 - define('CODE_PROFILER_MUPLUGIN', '0----code-profiler.php');
90 +// =====================================================================
91 +// Find the main site upload dir on a multisite installation.
92 +// Used when running the profiler via WP CLI.
93 +// This code is based on the WP private _wp_upload_dir function.
94 +
95 +function code_profiler_upload_dir() {
96 +
97 + $upload_path = trim( get_option('upload_path') );
98 + if ( empty( $upload_path ) || 'wp-content/uploads' === $upload_path ) {
99 + $basedir = WP_CONTENT_DIR . '/uploads';
100 + } elseif ( strpos( $upload_path, ABSPATH ) !== 0 ) {
101 + // $basedir is absolute, $upload_path is (maybe) relative to ABSPATH.
102 + $basedir = path_join( ABSPATH, $upload_path );
103 + } else {
104 + $basedir = $upload_path;
105 + }
106 +
107 + if ( defined('UPLOADS') && ! ( is_multisite() && get_site_option('ms_files_rewriting') ) ) {
108 + $basedir = ABSPATH . UPLOADS;
109 + }
110 +
111 + return ['basedir' => $basedir];
65 112 }
66 -define('CODE_PROFILER_ACCURACY', [
67 - 1 => __('Highest', 'code-profiler'),
68 - 5 => __('High', 'code-profiler'),
69 - 10 => __('Moderate', 'code-profiler'),
70 - 15 => __('Low', 'code-profiler'),
71 - 20 => __('Lowest', 'code-profiler')
72 -]);
113 +
73 114 // =====================================================================
74 115 // Prevent cURL timeout if a plugin changes its timeout options.
75 116
76 117 function code_profiler_curl_timeout( $handle, $parsed_args, $url ) {
@@ -88,34 +129,123 @@
88 129 // Update version in the DB and check if options must be updated.
89 130
90 131 function code_profiler_init_update() {
91 132
92 - $cp_options = get_option('code-profiler');
93 - if ( empty( $cp_options['version'] ) ||
94 - version_compare( $cp_options['version'], CODE_PROFILER_VERSION, '<') ) {
133 + if ( ( $cp_options = get_option('code-profiler') ) == false ) {
134 + /**
135 + * "Automatic conversion of false to array is deprecated" since PHP 8.1
136 + */
137 + $cp_options = [];
138 + }
95 139
140 + if ( empty( $cp_options['version'] ) ) {
96 141 $cp_options['version'] = CODE_PROFILER_VERSION;
142 + update_option('code-profiler', $cp_options );
97 143
144 + } elseif ( version_compare( $cp_options['version'], CODE_PROFILER_VERSION, '<') ) {
145 +
98 146 // Version 1.1
99 - if (! isset( $cp_options['enable_wpcli'] ) ) {
100 - $cp_options['enable_wpcli'] = 1;
147 + if ( version_compare( $cp_options['version'], '1.1', '<' ) ) {
148 + if (! isset( $cp_options['enable_wpcli'] ) ) {
149 + $cp_options['enable_wpcli'] = 1;
150 + }
101 151 }
102 152
103 153 // Version 1.2
104 - if (! isset( $cp_options['disable_wpcron'] ) ) {
105 - $cp_options['disable_wpcron'] = 1;
154 + if ( version_compare( $cp_options['version'], '1.2', '<' ) ) {
155 + if (! isset( $cp_options['disable_wpcron'] ) ) {
156 + $cp_options['disable_wpcron'] = 1;
157 + }
106 158 }
107 159
108 160 // Version 1.3.1
109 - if (! isset( $cp_options['http_response'] ) ) {
110 - $cp_options['http_response'] = '^(?:3|4|5)\d{2}$';
161 + if ( version_compare( $cp_options['version'], '1.3.1', '<' ) ) {
162 + if (! isset( $cp_options['http_response'] ) ) {
163 + $cp_options['http_response'] = '^(?:3|4|5)\d{2}$';
164 + }
111 165 }
112 166
113 167 // Version 1.5
114 - if (! isset( $cp_options['accuracy'] ) ) {
115 - $cp_options['accuracy'] = 1;
168 + if ( version_compare( $cp_options['version'], '1.5', '<' ) ) {
169 + if (! isset( $cp_options['accuracy'] ) ) {
170 + $cp_options['accuracy'] = 1;
171 + }
116 172 }
117 173
174 + // Version 1.7.5
175 + if ( version_compare( $cp_options['version'], '1.7.5', '<' ) ) {
176 + if (! isset( $cp_options['php_error'] ) ) {
177 + $cp_options['php_error'] = 1;
178 + }
179 + }
180 +
181 + // Version 1.8
182 + if ( version_compare( $cp_options['version'], '1.8', '<' ) ) {
183 + if ( isset( $cp_options['mem_where'] ) ) {
184 + $cp_options['mem']['x_end'] = $cp_options['mem_where'];
185 + unset( $cp_options['mem_where'] );
186 + }
187 + if ( isset( $cp_options['mem_post'] ) ) {
188 + $cp_options['mem']['post'] = $cp_options['mem_post'];
189 + unset( $cp_options['mem_post'] );
190 + }
191 + if ( isset( $cp_options['mem_user'] ) ) {
192 + $cp_options['mem']['x_auth'] = $cp_options['mem_user'];
193 + unset( $cp_options['mem_user'] );
194 + }
195 + if ( isset( $cp_options['mem_username'] ) ) {
196 + $cp_options['mem']['username'] = $cp_options['mem_username'];
197 + unset( $cp_options['mem_username'] );
198 + }
199 + if ( isset( $cp_options['mem_method'] ) ) {
200 + $cp_options['mem']['method'] = $cp_options['mem_method'];
201 + unset( $cp_options['mem_method'] );
202 + }
203 + if ( isset( $cp_options['mem_theme'] ) ) {
204 + $cp_options['mem']['theme'] = $cp_options['mem_theme'];
205 + unset( $cp_options['mem_theme'] );
206 + }
207 + if ( isset( $cp_options['ua'] ) ) {
208 + $cp_options['mem']['user_agent'] = $cp_options['ua'];
209 + unset( $cp_options['ua'] );
210 + }
211 + if ( isset( $cp_options['cookies'] ) ) {
212 + $cp_options['mem']['cookies'] = $cp_options['cookies'];
213 + unset( $cp_options['cookies'] );
214 + }
215 + if ( isset( $cp_options['mem_content_type'] ) ) {
216 + $cp_options['mem']['content_type'] = $cp_options['mem_content_type'];
217 + unset( $cp_options['mem_content_type'] );
218 + }
219 + if ( isset( $cp_options['payload'] ) ) {
220 + $cp_options['mem']['payload'] = $cp_options['payload'];
221 + unset( $cp_options['payload'] );
222 + }
223 + if ( isset( $cp_options['custom_headers'] ) ) {
224 + $cp_options['mem']['custom_headers'] = $cp_options['custom_headers'];
225 + unset( $cp_options['custom_headers'] );
226 + }
227 + if ( isset( $cp_options['exclusions'] ) ) {
228 + $cp_options['mem']['exclusions'] = $cp_options['exclusions'];
229 + unset( $cp_options['exclusions'] );
230 + }
231 + }
232 +
233 + // Version 1.8.1
234 + if ( version_compare( $cp_options['version'], '1.8.1', '<' ) ) {
235 + CodeProfiler_WPCron::install();
236 + }
237 +
238 + /**
239 + * Version 1.9.2
240 + */
241 + if ( version_compare( $cp_options['version'], '1.9.2', '<' ) ) {
242 + unset( $cp_options['warn_composer'] );
243 + }
244 +
245 + // Adjust current version
246 + $cp_options['version'] = CODE_PROFILER_VERSION;
247 +
118 248 // Update version in the DB
119 249 update_option('code-profiler', $cp_options );
120 250 }
121 251
@@ -128,13 +258,17 @@
128 258
129 259 function code_profiler_check_uploadsdir() {
130 260
131 261 if (! file_exists( CODE_PROFILER_UPLOAD_DIR ) ) {
132 - mkdir( CODE_PROFILER_UPLOAD_DIR, 0755 );
262 + wp_mkdir_p( CODE_PROFILER_UPLOAD_DIR );
133 263 }
134 - if (! is_writable( CODE_PROFILER_UPLOAD_DIR ) ) {
135 - // PHP running as an Apache module?
136 - chmod( CODE_PROFILER_UPLOAD_DIR, 0777 );
264 + if (! is_writable( CODE_PROFILER_UPLOAD_DIR ) || ! is_dir( CODE_PROFILER_UPLOAD_DIR ) ) {
265 + wp_die(
266 + sprintf(
267 + __('Error: The %s folder cannot be created or is read only', 'code-profiler'),
268 + esc_html( CODE_PROFILER_UPLOAD_DIR ) .'/'
269 + )
270 + );
137 271 }
138 272 if (! file_exists( CODE_PROFILER_UPLOAD_DIR .'/index.html') ) {
139 273 touch( CODE_PROFILER_UPLOAD_DIR .'/index.html');
140 274 }
@@ -249,9 +383,8 @@
249 383 'chart_type' => 'x',
250 384 'chart_max_plugins' => 25,
251 385 'hide_empty_value' => 1,
252 386 'table_max_rows' => 30,
253 - 'warn_composer' => 1,
254 387 'enable_wpcli' => 1,
255 388 'disable_wpcron' => 1,
256 389 'http_response' => '^(?:3|4|5)\d{2}$',
257 390 'accuracy' => 1,
@@ -295,44 +428,64 @@
295 428
296 429 } catch ( Exception $e ) { }
297 430
298 431 $cp_options = get_option('code-profiler');
432 + /**
433 + * Disable WP-CRON.
434 + */
299 435 if (! empty( $cp_options['disable_wpcron'] ) ) {
300 436 if (! defined('DISABLE_WP_CRON') ) {
301 437 define('DISABLE_WP_CRON', true );
302 438 }
303 439 }
440 + /**
441 + * Enable PHP error logging.
442 + */
443 + if (! empty( $cp_options['php_error'] ) ) {
444 + ini_set('log_errors', 1 );
445 + $phplog = ini_get('error_log');
446 + if ( empty( $phplog ) || $phplog === false ) {
447 + ini_set('error_log', WP_CONTENT_DIR .'/debug.log');
448 + } else {
449 + ini_set('error_log', $phplog );
450 + }
451 + }
452 +}
304 453
305 -}
306 454 // =====================================================================
307 -// Verify the security key when running the profile.
455 +// Verify the security key when running the profiler.
308 456
309 457 function code_profiler_verify_key() {
310 458
311 459 $response = [
312 460 'status' => 'error',
313 - 'message' => __('Security keys do not match. Reload the page and try again (%s)', 'code-profiler')
461 + // We cannot load translation here.
462 + 'message' => 'Security keys do not match. Reload the page and try again (%s)'
314 463 ];
315 464
316 - $cp_options = get_option('code-profiler');
465 + if ( empty( $_REQUEST['profiler_key'] ) ) {
466 + $response['message'] = sprintf( $response['message'], '001');
317 467
318 - if ( empty( $cp_options['hash'] ) ) {
319 - $response['message'] = sprintf( $response['message'], '#1');
320 -
321 468 } else {
322 - if ( empty( $_REQUEST['profiler_key'] ) ) {
323 - $response['message'] = sprintf( $response['message'], '#2');
469 + $file = CODE_PROFILER_UPLOAD_DIR .'/key_'. sha1( $_REQUEST['profiler_key'] ) .'.tmp';
470 + if ( file_exists( $file ) ) {
471 + /**
472 + * We limit the TTL to max $expire seconds to match code_profiler_cleantmpfiles().
473 + */
474 + $now = time();
475 + $expire = 20; // seconds
476 + if ( filemtime( $file ) + $expire < $now ) {
477 + $response['message'] = sprintf( $response['message'], '003');
478 + wp_send_json( $response );
479 + }
324 480
325 - } else {
326 - if ( $cp_options['hash'] == sha1( $_REQUEST['profiler_key'] ) ) {
327 - return;
328 - } else {
329 - $response['message'] = sprintf( $response['message'], '#3');
330 - }
481 + // Delete it and accept the request
482 + unlink( $file );
483 + return;
331 484 }
485 + $response['message'] = sprintf( $response['message'], '002');
332 486 }
333 487 wp_send_json( $response );
334 -
335 488 }
336 489
337 490 // =====================================================================
338 491 // Write message to the log.
@@ -368,18 +521,37 @@
368 521 code_profiler_write2log( $string, 8, $create );
369 522 }
370 523
371 524 // =====================================================================
525 +// Retrieve and return matching files from a directory.
526 +
527 +function code_profiler_glob( $directory, $regex, $pathname = false ) {
528 +
529 + $list = [];
530 +
531 + foreach ( new DirectoryIterator( $directory ) as $finfo ) {
532 + if (! $finfo->isDot() && preg_match("`$regex`", $finfo->getFilename() ) ) {
533 + if ( $pathname ) {
534 + $list[] = $finfo->getPathname();
535 + } else {
536 + $list[] = $finfo->getFilename();
537 + }
538 + }
539 + }
540 + return $list;
541 +}
542 +
543 +// =====================================================================
372 544 // Verify if a profile exists and return its full path.
373 545
374 546 function code_profiler_get_profile_path( $id, $type = 'slugs') {
375 547
376 - $return = false;
548 + if (! empty( $id ) && preg_match('/^\d{10}\.\d+$/', $id ) ) {
377 549
378 - if (! empty( $id ) && preg_match('/^\d{10}\.\d+$/', $id ) ) {
379 - $glob = glob( CODE_PROFILER_UPLOAD_DIR ."/$id.*.$type.profile" );
550 + $glob = code_profiler_glob(CODE_PROFILER_UPLOAD_DIR, "$id\..+\.$type\.profile$", true);
551 +
380 552 if ( is_array( $glob ) && ! empty( $glob[0] ) ) {
381 - if ( preg_match( "`/$id\.(.+?).$type.profile$`", $glob[0], $match ) ) {
553 + if ( preg_match( "`$id\.(.+?).$type.profile$`", $glob[0], $match ) ) {
382 554
383 555 return CODE_PROFILER_UPLOAD_DIR. "/$id.{$match[1]}";
384 556 }
385 557 }
@@ -407,10 +579,17 @@
407 579 $buffer['error'] = $err;
408 580 return $buffer;
409 581 }
410 582
583 + /**
584 + * We don't use fgetcsv() as it requires the $escape parameter since PHP 8.4
585 + */
411 586 while (! feof( $fh ) ) {
412 - $buffer[] = fgetcsv( $fh, 1000, "\t" );
587 + $tmp = trim( fgets( $fh, 1000 ) );
588 + if (! $tmp ) {
589 + continue;
590 + }
591 + $buffer[] = explode( "\t", $tmp );
413 592 }
414 593
415 594 fclose( $fh );
416 595
@@ -540,29 +719,49 @@
540 719 return $string;
541 720 }
542 721
543 722 // =====================================================================
544 -// Remove *tmp files left after an HTTP error (4xx or 5xx).
723 +// Remove *tmp files left in the profiles folder.
545 724
546 725 function code_profiler_cleantmpfiles() {
547 726
548 - $glob = glob( CODE_PROFILER_UPLOAD_DIR .'/*.tmp');
727 + $glob = code_profiler_glob( CODE_PROFILER_UPLOAD_DIR, '\.tmp$', true );
728 +
549 729 if ( is_array( $glob ) ) {
550 - $count = 0;
730 +
731 + $now = time();
551 732 foreach( $glob as $file ) {
552 - $count++;
733 + /**
734 + * Temporary files deletion:
735 + * - +20 seconds for temp sessions (to match the TTL checked at runtime).
736 + * - +10 minutes for unmatched temp profiles.
737 + */
738 + if ( strpos( $file, CODE_PROFILER_UPLOAD_DIR .'/key_') === 0 ) {
739 + if ( filemtime( $file ) + 20 > $now ) {
740 + continue;
741 + }
742 + } else {
743 + if ( filemtime( $file ) + 60 * 10 > $now ) {
744 + continue;
745 + }
746 + }
747 + /**
748 + * Delete all temp files.
749 + */
553 750 unlink( $file );
554 751 }
555 - if ( $count ) {
556 - code_profiler_log_info( sprintf(
557 - __('Deleting %s temporary files found in the profiles folder', 'code-profiler'),
558 - (int) $count
559 - ) );
560 - }
561 752 }
562 753 }
563 754
564 755 // =====================================================================
756 +// Remove non-ASCII characters from a string.
757 +
758 +function code_profiler_ASCII_filter( $string ) {
759 +
760 + return preg_replace('/[\x00-\x1f\x7f-\xff]/', '', $string );
761 +}
762 +
763 +// =====================================================================
565 764 // Clear the log if it's bigger than 100KB.
566 765
567 766 function code_profiler_clearlog() {
568 767
@@ -591,21 +790,109 @@
591 790 esc_html(
592 791 'Thank you for using %sCode Profiler%s.',
593 792 'code-profiler'
594 793 ),
595 - '<a href="https://code-profiler.com" target="_blank">',
794 + '<a href="https://nintechnet.com/codeprofiler/" target="_blank">',
596 795 '</a>'
597 796 ).
598 797 '</span>';
599 798 }
600 799
800 +
601 801 // =====================================================================
602 -// Display/hide an element depending on some value
802 +// Hide/display an element depending on some value.
603 803
604 -function code_profiler_hide( $var, $val ) {
804 +function code_profiler_showhide( $var, $val ) {
605 805
606 806 if ( $var == $val ) {
807 + echo " style='display:block'";
808 + } else {
607 809 echo " style='display:none'";
810 + }
811 +}
812 +
813 +// =====================================================================
814 +// Retrieve all themes.
815 +
816 +function code_profiler_get_themes() {
817 +
818 + $list = [];
819 +
820 + // Make sure the function is loaded
821 + if (! function_exists('wp_get_themes') ) {
822 + require_once ABSPATH . 'wp-includes/theme.php';
823 + }
824 + $themes = wp_get_themes();
825 + foreach( $themes as $k => $v ) {
826 + if ( $v->Name ) {
827 + $list[ $k ] = [
828 + 'n' => $v->Name,
829 +
830 + 't' => $v->Template
831 + ];
832 + } else {
833 + $list[ $k ] = [
834 + 'n' => $k,
835 + 't' => $v->Template
836 + ];
837 + }
838 + }
839 + return $list;
840 +}
841 +
842 +// =====================================================================
843 +// Retrieve all available cron events.
844 +
845 +function code_profiler_get_crons() {
846 +
847 + $list = [];
848 +
849 + $wp_crons = _get_cron_array();
850 +
851 + if ( empty( $wp_crons ) ) {
852 + return $list;
853 + }
854 +
855 + foreach ( $wp_crons as $timestamp => $cronhooks ) {
856 + foreach ( $cronhooks as $hook => $keys ) {
857 + $list[] = $hook;
858 + }
859 + }
860 + sort( $list );
861 + return $list;
862 +}
863 +
864 +// =====================================================================
865 +// Create a file with the ABSPATH.
866 +
867 +function code_profiler_create_tmpfile() {
868 +
869 + $tmp_folder = dirname( __DIR__ ) .'/tmp';
870 + $tmp_file = "$tmp_folder/profiler.inc.php";
871 +
872 + if (! is_dir( $tmp_folder ) ) {
873 + $res = @ mkdir( $tmp_folder );
874 + if ( false === $res ) {
875 + return sprintf(
876 + __('Cannot create temporary folder: [%s]. Any attempt to profile a cron event will likely fail.', 'code-profiler'),
877 + $tmp_folder
878 + );
879 + }
880 + }
881 +
882 + if (! is_file( "$tmp_folder/index.html" ) ) {
883 + touch( "$tmp_folder/index.html" );
884 + }
885 +
886 + $res = @ file_put_contents(
887 + $tmp_file,
888 + "<?php\nconst ABSPATH = '". ABSPATH ."';\n"
889 + );
890 + if ( false === $res ) {
891 + return sprintf(
892 + __('Cannot create temporary file: [%s]. Any attempt to profile a cron event will likely fail.', 'code-profiler'),
893 + $tmp_file
894 + );
608 895 }
609 896 }
610 897
611 898 // =====================================================================