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/menu_profiler.php +391 -151 1.4.31.9.6 View file →
@@ -6,13 +6,13 @@
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') ) { die('Forbidden'); }
15 15
16 16 // =====================================================================
17 17 // Display Summary tab.
18 18
@@ -33,135 +33,270 @@
33 33 printf( CODE_PROFILER_ERROR_NOTICE, sprintf(
34 34 esc_html__('Your PHP configuration is missing the "%s" function. Code Profiler cannot run without it. Please contact your server administrator about this error.', 'code-profiler'), $error )
35 35 );
36 36 }
37 +if (! is_writable( CODE_PROFILER_UPLOAD_DIR ) ) {
38 + printf( CODE_PROFILER_ERROR_NOTICE, sprintf(
39 + esc_html__('The following folder is not writable: %s. Please change its permissions or ownership so that Code Profiler can write to it.', 'code-profiler'), CODE_PROFILER_UPLOAD_DIR )
40 + );
41 +}
37 42
38 -$home = home_url( '/' );
43 +/**
44 + * Check and warn if the Xdebug extension is loaded.
45 + */
46 +if ( extension_loaded('xdebug') ) {
47 + printf( CODE_PROFILER_WARNING_NOTICE,
48 + esc_html__('Warning: the PHP Xdebug extension is loaded. Consider disabling it as it can drastically impact the performance and results of Code Profiler.', 'code-profiler')
49 + );
50 +}
51 +
52 +// Clear the log if it's too big
53 +code_profiler_clearlog();
54 +
55 +// Clean-up temp files left in the profiles folder
56 +code_profiler_cleantmpfiles();
57 +
58 +/**
59 + * Create temporary folder and file used to profile cron events.
60 + */
61 +$error = code_profiler_create_tmpfile();
62 +if ( $error ) {
63 + printf( CODE_PROFILER_ERROR_NOTICE, esc_html( $error ) );
64 +}
65 +
66 +$home = home_url('/'); // Frontend
67 +$site = site_url('/'); // Backend
68 +
39 69 // Get user login name
40 70 $current_user = wp_get_current_user();
71 +
72 +$cp_options = get_option('code-profiler');
73 +/**
74 + * Check if we've been asked to re-run a profile.
75 + */
76 +if (! empty( $_REQUEST['action'] ) && $_REQUEST['action'] == 'rerun' &&
77 + ! empty( $_REQUEST['profiles'][0] ) ) {
78 + /**
79 + * Make sure the profile exists and get its full path.
80 + */
81 + $profile_path = code_profiler_get_profile_path( $_REQUEST['profiles'][0] );
82 + if ( $profile_path !== false ) {
83 +
84 + $cp_data = json_decode( file_get_contents("$profile_path.summary.profile"), true );
85 + if (! empty( $cp_data['rerun'] ) ) {
86 + $cp_options['mem'] = $cp_data['rerun'];
87 + $rerun = true;
88 + }
89 + }else {
90 + // Display why we don't want to run.
91 + wp_die( esc_html__('Missing profile ID.', 'code-profiler') );
92 + }
93 +}
41 94 // Profile's name
42 -$profile = code_profiler_profile_name();
43 -
44 -$cp_options = get_option( 'code-profiler' );
45 -// Memorized options
46 -if ( empty( $cp_options['mem_where'] ) ) {
47 - $cp_options['mem_where'] = 'frontend';
95 +if (! empty( $cp_options['mem']['profile'] ) ) {
96 + $profile = $cp_options['mem']['profile'];
97 +} else {
98 + $profile = code_profiler_profile_name();
48 99 }
49 -if ( empty( $cp_options['mem_post'] ) ) {
50 - $cp_options['mem_post'] = '';
100 +/**
101 + * Memorized options from last run.
102 + */
103 +if ( empty( $cp_options['mem']['x_end'] ) ) {
104 + $cp_options['mem']['x_end'] = 'frontend';
51 105 }
52 -if ( empty( $cp_options['mem_user'] ) ) {
53 - $cp_options['mem_user'] = 'unauthenticated';
106 +if ( empty( $cp_options['mem']['post'] ) ) {
107 + $cp_options['mem']['post'] = '';
54 108 }
55 -if ( $cp_options['mem_where'] == 'backend' ) {
56 - $cp_options['mem_user'] = 'authenticated';
109 +if ( empty( $cp_options['mem']['x_auth'] ) ) {
110 + $cp_options['mem']['x_auth'] = 'unauthenticated';
57 111 }
58 -if ( empty( $cp_options['mem_method'] ) ) {
59 - $cp_options['mem_method'] = 'get';
112 +if ( $cp_options['mem']['x_end'] == 'backend') {
113 + $cp_options['mem']['x_auth'] = 'authenticated';
60 114 }
61 -if ( empty( $cp_options['ua'] ) ) {
62 - $cp_options['ua'] = 'Firefox';
115 +if ( empty( $cp_options['mem']['method'] ) ) {
116 + $cp_options['mem']['method'] = 'get';
63 117 }
64 -$cookies = '';
65 -$payload = '';
66 -if ( isset( $cp_options['cookies'] ) ) {
67 - $cookies = trim( json_decode( $cp_options['cookies'] ) );
118 +$default_theme = get_option('stylesheet');
119 +if ( empty( $cp_options['mem']['theme'] ) ) {
120 + $cp_options['mem']['theme'] = $default_theme;
68 121 }
69 -if ( isset( $cp_options['payload'] ) ) {
70 - $payload = trim( json_decode( $cp_options['payload'] ) );
122 +if ( empty( $cp_options['mem']['user_agent'] ) ) {
123 + $cp_options['mem']['user_agent'] = 'Firefox';
71 124 }
125 +if ( isset( $cp_options['mem']['cookies'] ) ) {
126 + // stripslashes is only needed for cookies
127 + $cookies = trim( stripslashes( json_decode( $cp_options['mem']['cookies'] ) ) );
128 +} else {
129 + $cookies = '';
130 +}
131 +if ( empty( $cp_options['mem']['content_type'] ) ||
132 + ! in_array( $cp_options['mem']['content_type'], [ 1, 2, 3 ] ) ) {
133 +
134 + $cp_options['mem']['content_type'] = 1;
135 +}
136 +if ( isset( $cp_options['mem']['payload'] ) ) {
137 + $payload = trim( json_decode( $cp_options['mem']['payload'] ) );
138 +} else {
139 + $payload = '';
140 +}
141 +if ( isset( $cp_options['mem']['custom_headers'] ) ) {
142 + $custom_headers = trim( json_decode( $cp_options['mem']['custom_headers'] ) );
143 +} else {
144 + $custom_headers = '';
145 +}
146 +if ( isset( $cp_options['mem']['exclusions'] ) ) {
147 + $exclusions = json_decode( $cp_options['mem']['exclusions'] );
148 +} else {
149 + $exclusions = [];
150 +}
151 +
72 152 ?>
73 -<table class="form-table">
153 +
154 +<table style="width:100%">
74 155 <tr>
75 - <th scope="row"><?php esc_html_e('Page to profile', 'code-profiler') ?> <span class="code-profiler-tip" data-tip="<?php esc_attr_e('Select the page you want the profiler to analyze. It can be in the frontend of the site, in the admin backend or a custom URL.', 'code-profiler' ) ?>"></span></th>
76 156 <td>
77 - <p><label><input type="radio" name="where" value="frontend" onclick="cpjs_front_or_backend(1);"<?php checked( $cp_options['mem_where'], 'frontend' ) ?> /> <?php esc_html_e('Website frontend', 'code-profiler') ?></label>
78 - &nbsp;&nbsp;&nbsp;&nbsp;
79 - <label><input type="radio" name="where" value="custom" onclick="cpjs_front_or_backend(3);"<?php checked( $cp_options['mem_where'], 'custom' ) ?> /> <?php esc_html_e('Custom post/URL', 'code-profiler') ?></label>
80 - &nbsp;&nbsp;&nbsp;&nbsp;
81 - <label><input type="radio" name="where" value="backend" onclick="cpjs_front_or_backend(2);"<?php checked( $cp_options['mem_where'], 'backend' ) ?> /> <?php esc_html_e('Admin backend', 'code-profiler') ?></label>
82 - </p>
83 - <br />
84 - <?php
85 - if ( $cp_options['mem_where'] == 'frontend' ) {
86 - echo '<p id="p-frontend">';
87 - } else {
88 - echo '<p id="p-frontend" style="display:none">';
89 - }
90 - ?>
91 - <?php esc_html_e('Select a page:', 'code-profiler') ?>
92 - <select name="frontend" id="id-frontend">
93 - <?php echo code_profiler_fetch_pages( $home, $cp_options ); ?>
94 - </select>
95 - </p>
96 - <?php
97 - if ( $cp_options['mem_where'] == 'custom' ) {
98 - $value = $cp_options['mem_post'];
99 - echo '<p id="p-custom">';
100 - } else {
101 - $value = '';
102 - echo '<p id="p-custom" style="display:none">';
103 - }
104 - ?>
105 - <input name="custom" id="id-custom" type="text" value="<?php echo esc_attr( $value ) ?>" size="70" placeholder="<?php
106 - echo esc_attr(
107 - sprintf(
108 - __('e.g., %s', 'code-profiler'),
109 - "{$home}foo/bar/"
110 - )
111 - ) ?>" />
112 - </p>
113 - <?php
114 - if ( $cp_options['mem_where'] == 'backend' ) {
115 - echo '<p id="p-backend">';
116 - } else {
117 - echo '<p id="p-backend" style="display:none">';
118 - }
119 - if (! empty( $cp_options['mem_username'] ) ) {
120 - $username = $cp_options['mem_username'];
121 - } else {
122 - $username = $current_user->user_login;
123 - }
124 - ?>
125 - <?php esc_html_e('Select a page:', 'code-profiler') ?>
126 - <select name="backend" id="id-backend"><?php echo code_profiler_fetch_admin_pages( $home, $cp_options ) ?></select>
127 - </p>
157 + <table class="form-table">
158 + <tr>
159 + <th scope="row"><?php esc_html_e('Page to profile', 'code-profiler') ?> <span class="code-profiler-tip" data-tip="<?php esc_attr_e('Select the page you want the profiler to analyze. It can be in the frontend of the site, in the admin backend, a custom URL or a cron event. Note that in case of a cron event, the "HTTP Method" option will be ignored by Code Profiler as it will always send a POST request with an empty payload.', 'code-profiler') ?>"></span></th>
160 + <td>
161 + <p><label><input type="radio" name="x_end" value="frontend" onclick="cpjs_front_or_backend(this.value);"<?php checked( $cp_options['mem']['x_end'], 'frontend') ?> /> <?php esc_html_e('Website frontend', 'code-profiler') ?></label>
162 + &nbsp;&nbsp;&nbsp;&nbsp;
163 + <label><input type="radio" name="x_end" value="custom" onclick="cpjs_front_or_backend(this.value);"<?php checked( $cp_options['mem']['x_end'], 'custom') ?> /> <?php esc_html_e('Custom post/URL', 'code-profiler') ?></label>
164 + &nbsp;&nbsp;&nbsp;&nbsp;
165 + <label><input type="radio" name="x_end" value="backend" onclick="cpjs_front_or_backend(this.value);"<?php checked( $cp_options['mem']['x_end'], 'backend') ?> /> <?php esc_html_e('Admin backend', 'code-profiler') ?></label>
166 + &nbsp;&nbsp;&nbsp;&nbsp;
167 + <label><input type="radio" name="x_end" value="wpcron" onclick="cpjs_front_or_backend(this.value);"<?php checked( $cp_options['mem']['x_end'], 'wpcron') ?> /> <?php esc_html_e('WP-Cron', 'code-profiler') ?></label>
168 + </p>
169 + <br />
170 + <?php
171 + if ( $cp_options['mem']['x_end'] == 'frontend') {
172 + echo '<p id="p-frontend">';
173 + } else {
174 + echo '<p id="p-frontend" style="display:none">';
175 + }
176 + ?>
177 + <?php esc_html_e('Select a page:', 'code-profiler') ?>
178 + <select name="frontend" id="id-frontend">
179 + <?php echo code_profiler_fetch_pages( $home, $cp_options ); ?>
180 + </select>
181 + </p>
182 + <?php
183 + if ( $cp_options['mem']['x_end'] == 'custom') {
184 + $value = $cp_options['mem']['post'];
185 + echo '<p id="p-custom">';
186 + } else {
187 + $value = '';
188 + echo '<p id="p-custom" style="display:none">';
189 + }
190 + ?>
191 + <input name="custom" id="id-custom" type="text" value="<?php echo esc_attr( $value ) ?>" size="70" placeholder="<?php
192 + echo esc_attr(
193 + sprintf(
194 + __('e.g., %s', 'code-profiler'),
195 + "{$home}foo/bar/"
196 + )
197 + ) ?>" />
198 + </p>
199 + <?php
200 + if ( $cp_options['mem']['x_end'] == 'backend') {
201 + echo '<p id="p-backend">';
202 + } else {
203 + echo '<p id="p-backend" style="display:none">';
204 + }
205 + if (! empty( $cp_options['mem']['username'] ) ) {
206 + $username = $cp_options['mem']['username'];
207 + } else {
208 + $username = $current_user->user_login;
209 + }
210 + ?>
211 + <?php esc_html_e('Select a page:', 'code-profiler') ?>
212 + <select name="backend" id="id-backend"><?php echo code_profiler_fetch_admin_pages( $site, $cp_options ) ?></select>
213 + </p>
214 + <?php
215 + /**
216 + * Cron tasks.
217 + */
218 + if ( $cp_options['mem']['x_end'] == 'wpcron') {
219 + echo '<p id="p-wpcron">';
220 + } else {
221 + echo '<p id="p-wpcron" style="display:none">';
222 + }
223 + ?>
224 + <?php esc_html_e('Select a cron event:', 'code-profiler') ?>
225 + <select name="wpcron" id="id-wpcron">
226 + <?php echo code_profiler_fetch_crontasks( $cp_options['mem']['post'] ); ?>
227 + </select>
228 + </p>
229 + </td>
230 + </tr>
231 + <tr>
232 + <th scope="row"><?php esc_html_e('Run profiler as', 'code-profiler') ?> <span class="code-profiler-tip" data-tip="<?php esc_attr_e('The profiler can access the requested page as an unauthenticated user (frontend only) or as an authenticated user (frontend and backend). You can enter the login name of any registered user, but make sure that the user has the required capability to access the page you are going to profile, otherwise Code Profiler will return an error if the user isn\'t allowed to access it.', 'code-profiler') ?>"></span></th>
233 + <td>
234 + <p><label><input type="radio" onclick="cpjs_authenticated(0);" name="x_auth" value="unauthenticated" id="user-unauthenticated"<?php checked( $cp_options['mem']['x_auth'], 'unauthenticated'); disabled( $cp_options['mem']['x_end'], 'backend'); ?> /> <?php esc_html_e('Unauthenticated user', 'code-profiler') ?></label></p>
235 + <p><label><input type="radio" onclick="cpjs_authenticated(1);" name="x_auth" value="authenticated" id="user-authenticated"<?php checked( $cp_options['mem']['x_auth'], 'authenticated') ?> /> <?php esc_html_e('Authenticated user', 'code-profiler') ?></label></p>
236 + <p><label><?php esc_html_e('User:', 'code-profiler') ?> <input type="text" name="username" id="user-name" value ="<?php esc_attr_e( $username ) ?>"<?php disabled( $cp_options['mem']['x_auth'], 'unauthenticated') ?> /></label></p>
237 + </td>
238 + </tr>
239 + <tr>
240 + <th scope="row"><?php esc_html_e('Theme', 'code-profiler') ?> <span class="code-profiler-tip" data-tip="<?php esc_attr_e('If you want to profile different themes, you can use this option so that you don\'t need to modify your WordPress settings. The change will not affect your visitors, but only the profiler when it is running.', 'code-profiler') ?>"></span></th>
241 + <td>
242 + <select name="theme" id="id-theme">
243 + <?php
244 + $themes = code_profiler_get_themes();
245 + foreach( $themes as $slug => $name ) {
246 + if ( $slug == $default_theme ) {
247 + echo '<option value=""'. selected( $cp_options['mem']['theme'], $slug, false ) .'>'.
248 + esc_html( $name['n'] ) .' '. __('(active theme)', 'code-profiler') .'</option>';
249 + } else {
250 + echo '<option value="'. esc_attr( $slug ) .'"'. selected( $cp_options['mem']['theme'], $slug, false ) .'>'.
251 + esc_html( $name['n'] ) .'</option>';
252 + }
253 + }
254 + ?>
255 + </select>
256 + </td>
257 + </tr>
258 + <tr>
259 + <th scope="row"><?php esc_html_e('User agent', 'code-profiler') ?> <span class="code-profiler-tip" data-tip="<?php esc_attr_e('Some themes and plugins may execute different code depending on the type of device used to visit the website (e.g., a desktop computer, a mobile phone, a search engine bot etc). This option lets you change the User-Agent request header used by Code Profiler.', 'code-profiler') ?>"></span></th>
260 + <td>
261 + <select name="user_agent" id="ua-id">
262 + <?php
263 + foreach( CODE_PROFILER_UA as $types => $types_array ) {
264 + echo '<optgroup label="'. esc_attr( $types ) .'">';
265 + foreach( $types_array as $name => $value ) {
266 + echo '<option value="'. esc_attr( $name ) .'"'. selected( $cp_options['mem']['user_agent'], $name, false ) .'>'. esc_html( $name ) .'</option>';
267 + }
268 + echo '</optgroup>';
269 + }
270 + ?>
271 + </select>
272 + </td>
273 + </tr>
274 + <tr>
275 + <th scope="row"><?php esc_html_e('Name of the profile', 'code-profiler') ?> <span class="code-profiler-tip" data-tip="<?php esc_attr_e('Enter the name for this profile. It will be saved to the "Profiles List" page, with all other profiles.', 'code-profiler') ?>"></span></th>
276 + <td>
277 + <p><label><input type="text" class="regular-text" name="profile" maxlength="100" value="<?php echo esc_attr( $profile ) ?>" id="profile-name" /></label></p>
278 + <p class="description"><?php esc_html_e('Max 100 characters', 'code-profiler') ?></p>
279 + </td>
280 + </tr>
281 + </table>
128 282 </td>
129 - </tr>
130 - <tr>
131 - <th scope="row"><?php esc_html_e('Run profiler as', 'code-profiler') ?> <span class="code-profiler-tip" data-tip="<?php esc_attr_e('The profiler can access the requested page as an unauthenticated user (frontend only) or as an authenticated user (frontend and backend). You can enter the login name of any registered user, but make sure that the user has the required capability to access the page you are going to profile (e.g. an admin page in the backend), otherwise Code Profiler will return an error if the user isn\'t allowed to access it.', 'code-profiler' ) ?>"></span></th>
132 - <td>
133 - <p><label><input type="radio" onclick="cpjs_authenticated(0);" name="user" value="unauthenticated" id="user-unauthenticated"<?php checked( $cp_options['mem_user'], 'unauthenticated'); disabled( $cp_options['mem_where'], 'backend'); ?> /> <?php esc_html_e('Unauthenticated user', 'code-profiler') ?></label></p>
134 - <p><label><input type="radio" onclick="cpjs_authenticated(1);" name="user" value="authenticated" id="user-authenticated"<?php checked( $cp_options['mem_user'], 'authenticated') ?> /> <?php esc_html_e('Authenticated user', 'code-profiler') ?></label></p>
135 - <p><label><?php esc_html_e('User:', 'code-profiler') ?> <input type="text" name="username" id="user-name" value ="<?php esc_attr_e( $username ) ?>"<?php disabled( $cp_options['mem_user'], 'unauthenticated') ?> /></label></p>
283 + <td style="vertical-align:top;text-align: center">
284 + <?php
285 + /**
286 + * Display any available discount coupon.
287 + */
288 + CodeProfiler_WPCron::display_coupon();
289 + ?>
136 290 </td>
137 291 </tr>
138 - <tr>
139 - <th scope="row"><?php esc_html_e('User agent', 'code-profiler') ?> <span class="code-profiler-tip" data-tip="<?php esc_attr_e('Some themes and plugins may execute different code depending on the type of device used to visit the website (e.g., a desktop computer, a mobile phone, a search engine bot etc). This option lets you change the User-Agent request header used by Code Profiler.', 'code-profiler' ) ?>"></span></th>
140 - <td>
141 - <select name="ua" id="ua-id">
142 - <?php
143 - foreach( CODE_PROFILER_UA as $types => $types_array ) {
144 - echo '<optgroup label="'. esc_attr( $types ) .'">';
145 - foreach( $types_array as $name => $value ) {
146 - echo '<option value="'. esc_attr( $name ) .'"'. selected( $cp_options['ua'], $name ) .'>'. esc_html( $name ) .'</option>';
147 - }
148 - echo '</optgroup>';
149 - }
150 - ?>
151 - </select>
152 - </td>
153 - </tr>
154 - <tr>
155 - <th scope="row"><?php esc_html_e('Name of the profile', 'code-profiler') ?> <span class="code-profiler-tip" data-tip="<?php esc_attr_e('Enter the name for this profile. It will be saved to the "Profiles List" page, with all other profiles.', 'code-profiler' ) ?>"></span></th>
156 - <td>
157 - <p><label><input type="text" class="regular-text" name="profile" maxlength="100" value="<?php echo esc_attr( $profile ) ?>" id="profile-name" /></label></p>
158 - <p class="description"><?php esc_html_e('Max 100 characters', 'code-profiler') ?></p>
159 - </td>
160 - </tr>
161 292 </table>
162 293 <?php
163 -if (! empty( $cookies ) || $cp_options['mem_method'] == 'post' ) {
294 +if ( (! empty( $cookies ) || ! empty( $custom_headers ) ||
295 + $cp_options['mem']['method'] == 'post' || ! empty( $exclusions ) ) &&
296 + // We don't display the advanced section if the last profile was a cron event.
297 + $cp_options['mem']['x_end'] != 'wpcron' ) {
298 +
164 299 echo '<div id="cp-advanced-settings">';
165 300 $disabled_button = ' disabled';
166 301 } else {
167 302 echo '<div id="cp-advanced-settings" style="display:none">';
@@ -169,39 +304,89 @@
169 304 }
170 305 ?>
171 306 <table class="form-table">
172 307 <tr>
173 - <th scope="row"><?php esc_html_e('HTTP Method', 'code-profiler') ?> <span class="code-profiler-tip" data-tip="<?php esc_attr_e('You can select which HTTP method will be used by the profiler: GET or POST. If you select POST, you can also send an optional payload.', 'code-profiler' ) ?>"></span></th>
308 + <th scope="row"><?php esc_html_e('HTTP Method', 'code-profiler') ?> <span class="code-profiler-tip" data-tip="<?php esc_attr_e('You can select which HTTP method will be used by the profiler: GET or POST. If you select POST, you can also send an optional payload.', 'code-profiler') ?>"></span></th>
174 309 <td>
175 - <p><label><input onclick="cpjs_get_post(0);" type="radio" name="method" value="get" id="get-method"<?php checked( $cp_options['mem_method'], 'get' ) ?> /> <?php esc_html_e('GET (default)', 'code-profiler') ?></label></p>
176 - <p><label><input onclick="cpjs_get_post(1);" type="radio" name="method" value="post" id="post-method"<?php checked( $cp_options['mem_method'], 'post' ) ?> /> POST</label></p>
177 - <p><textarea name="post-value" id="post-value" class="regular-text code"<?php disabled( $cp_options['mem_method'], 'get' ) ?> maxlength="4000" rows="6"><?php echo esc_textarea( $payload ) ?></textarea></p>
178 - <p class="description"><?php printf( esc_html__('Optional POST payload in %s format, one item per line.', 'code-profiler'), '<code>key=value</code>') ?> <?php printf( esc_html__('%sView example%s', 'code-profiler'), '<a href="'. plugins_url( '/static/help/http_method.png', dirname( __FILE__ ) ) .'" target="_blank" rel="noopener noreferrer">', '</a>') ?> </p>
310 + <p>
311 + <label>
312 + <input onclick="cpjs_get_post(0);" type="radio" name="method" value="get" id="get-method"<?php checked( $cp_options['mem']['method'], 'get') ?> /> GET(<?php esc_html_e('default', 'code-profiler') ?>)
313 + </label>
314 + </p>
315 + <p>
316 + <label>
317 + <input onclick="cpjs_get_post(1);" type="radio" name="method" value="post" id="post-method"<?php checked( $cp_options['mem']['method'], 'post') ?> /> POST
318 + </label>
319 + </p>
320 + <p>
321 + <?php esc_html_e('Content-type:', 'code-profiler') ?>
322 + <select name="cp-content-type" id="id-content-type"<?php disabled( $cp_options['mem']['method'], 'get') ?> onChange="cpjs_content_type(this.value);">
323 + <option value="1"<?php selected( $cp_options['mem']['content_type'], 1 )?>>application/x-www-form-urlencoded (<?php esc_html_e('formatted', 'code-profiler') ?>)</option>
324 + <option value="3"<?php selected( $cp_options['mem']['content_type'], 3 )?>>application/x-www-form-urlencoded (<?php esc_html_e('raw', 'code-profiler') ?>)</option>
325 + <option value="2"<?php selected( $cp_options['mem']['content_type'], 2 )?>>application/json</option>
326 + </select>
327 + </p>
328 + <p>
329 + <textarea name="post-value" id="post-value" class="regular-text code"<?php disabled( $cp_options['mem']['method'], 'get') ?> maxlength="4000" rows="6"><?php echo esc_textarea( $payload ) ?></textarea>
330 + </p>
331 + <p class="description" id="ct-1"<?php echo code_profiler_showhide( $cp_options['mem']['content_type'], 1 ) ?>>
332 + <?php printf( esc_html__('Optional POST payload in %s format, one item per line.', 'code-profiler'), '<code>name=value</code>') ?> <?php printf( esc_html__('%sView example%s', 'code-profiler'), '<a href="'. plugins_url('/static/help/http_method-1.png', dirname( __FILE__ ) ) .'" target="_blank" rel="noopener noreferrer">', '</a>') ?>
333 + </p>
334 + <p class="description" id="ct-3"<?php echo code_profiler_showhide( $cp_options['mem']['content_type'], 3 ) ?>>
335 + <?php printf( esc_html__('Optional raw POST payload, on a single line.', 'code-profiler'), '<code>name=value</code>') ?> <?php printf( esc_html__('%sView example%s', 'code-profiler'), '<a href="'. plugins_url('/static/help/http_method-3.png', dirname( __FILE__ ) ) .'" target="_blank" rel="noopener noreferrer">', '</a>') ?>
336 + </p>
337 + <p class="description" id="ct-2"<?php echo code_profiler_showhide( $cp_options['mem']['content_type'], 2 ) ?>>
338 + <?php printf( esc_html__('Optional JSON-encoded payload, on a single line.', 'code-profiler'), '<code>name=value</code>') ?> <?php printf( esc_html__('%sView example%s', 'code-profiler'), '<a href="'. plugins_url('/static/help/http_method-2.png', dirname( __FILE__ ) ) .'" target="_blank" rel="noopener noreferrer">', '</a>') ?>
339 + </p>
179 340 </td>
180 341 </tr>
181 342 <tr>
182 - <th scope="row"><?php esc_html_e('Cookie', 'code-profiler') ?> <span class="code-profiler-tip" data-tip="<?php esc_attr_e('Some websites may execute different code if the user has one or more specific cookies. You can use this field for that purpose.', 'code-profiler' ) ?>"></span></th>
343 + <th scope="row"><?php esc_html_e('Cookie', 'code-profiler') ?> <span class="code-profiler-tip" data-tip="<?php esc_attr_e('Some websites may execute different code if the user has one or more specific cookies. You can use this field for that purpose.', 'code-profiler') ?>"></span></th>
183 344 <td>
184 345 <p><textarea name="cp-cookies" id="cp-cookies" class="regular-text code" maxlength="4000" rows="6"><?php echo esc_textarea( $cookies ) ?></textarea></p>
185 - <p class="description"><?php printf( esc_html__('Optional cookie in %s format, one item per line.', 'code-profiler'), '<code>name=value</code>') ?> <?php printf( esc_html__('%sView example%s', 'code-profiler'), '<a href="'. plugins_url( '/static/help/cookies.png', dirname( __FILE__ ) ) .'" target="_blank" rel="noopener noreferrer">', '</a>') ?></p>
346 + <p class="description"><?php printf( esc_html__('Optional cookie in %s format, one item per line.', 'code-profiler'), '<code>name=value</code>') ?> <?php printf( esc_html__('%sView example%s', 'code-profiler'), '<a href="'. plugins_url('/static/help/cookies.png', dirname( __FILE__ ) ) .'" target="_blank" rel="noopener noreferrer">', '</a>') ?></p>
186 347 </td>
187 348 </tr>
349 + <tr>
350 + <th scope="row" class="row-med"><?php esc_html_e('HTTP headers', 'code-profiler'); ?> <span class="code-profiler-tip" data-tip="<?php esc_attr_e('You can use this field to add custom HTTP headers or even override existing ones (e.g., host, user-agent, accept-language etc). HTTP header names are case-insensitive and Code Profiler will automatically convert them to lowercase. HTTP header values are case-sensitive and only ASCII printable characters are allowed.', 'code-profiler') ?>"></span></th>
351 + <td>
352 + <textarea autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" id="custom-headers" name="custom_headers" class="regular-text code" rows="6"><?php echo esc_textarea( $custom_headers ) ?></textarea>
353 + <p class="description"><?php printf( esc_html__('Optional HTTP header in %s format, one item per line.', 'code-profiler'), '<code>name: value</code>') ?> <?php printf( esc_html__('%sView example%s', 'code-profiler'), '<a href="'. plugins_url('/static/help/custom_headers.png', dirname( __FILE__ ) ) .'" target="_blank" rel="noopener noreferrer">', '</a>') ?></p>
354 + </td>
355 + </tr>
356 + <tr>
357 + <th scope="row" class="row-med"><?php esc_html_e('File and folder exclusions', 'code-profiler'); ?> <span class="code-profiler-tip" data-tip="<?php esc_attr_e('This option lets you exclude files and folders from the profiling process. It can be a full path, a file or a folder name, or any part of them (substring). Values are case-sensitive and only ASCII printable characters are allowed.', 'code-profiler') ?>"></span></th>
358 + <td>
359 + <textarea autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" id="exclusions" name="exclusions" class="regular-text code" rows="6"><?php
360 + foreach( $exclusions as $item ) {
361 + echo esc_textarea( $item ) ."\n";
362 + }
363 + ?></textarea>
364 + <p class="description"><?php esc_html_e('One item per line.', 'code-profiler') ?> <?php printf( esc_html__('%sView example%s', 'code-profiler'), '<a href="'. plugins_url('/static/help/exclusions.png', dirname( __FILE__ ) ) .'" target="_blank" rel="noopener noreferrer">', '</a>') ?></p>
365 + </td>
366 + </tr>
188 367 </table>
189 368 </div>
190 369 <?php wp_nonce_field('start_profiler_nonce', 'cp_nonce', 0); ?>
191 370 <br />
192 371 <div>
193 - <input type="button" class="button-secondary" id="button-adv-settings" name="adv-settings" value="<?php esc_attr_e('Advanced Options', 'code-profiler') ?>" onclick="cpjs_show_adv_settings();"<?php echo $disabled_button ?> />
372 + <input type="button" class="button button-secondary" id="button-adv-settings" name="adv-settings" value="<?php esc_attr_e('Advanced Options', 'code-profiler') ?>" onclick="cpjs_show_adv_settings();"<?php echo $disabled_button ?> />
194 373 &nbsp;&nbsp;&nbsp;
195 - <input type="button" class="button-primary" id="start-profile" name="start-profile" onClick="cpjs_start_profiler();" value="<?php esc_attr_e('Start Profiling', 'code-profiler') ?> »" title="<?php esc_attr_e('Click to start profiling your code.', 'code-profiler') ?>" />
374 + <input type="button" class="button button-primary" id="start-profile" name="start-profile" onClick="cpjs_start_profiler();" value="<?php esc_attr_e('Start Profiling', 'code-profiler') ?> »" title="<?php esc_attr_e('Click to start profiling your code.', 'code-profiler') ?>" />
196 375 </div>
197 376 <div id="cp-progress-div" style="display:none">
198 377 <br />
199 378 <div class="cp-progress-bar"><span id="cp-span-progress" style="width:0%"></span></div>
200 - <img style="vertical-align:middle;display:none" id="progress-gif" src="<?php echo plugins_url('/static/progress.gif', dirname (__FILE__ ) ) ?>" />&nbsp;&nbsp;<font id="progress-text" style="display:none"><?php esc_html_e('Starting profiler...', 'code-profiler') ?></font>
379 + <img style="vertical-align:middle;display:none" id="progress-gif" src="<?php echo plugins_url('/static/progress.gif', dirname (__FILE__ ) ) ?>" />&nbsp;&nbsp;<font id="progress-text" style="display:none"><?php esc_html_e('Starting the profiler...', 'code-profiler') ?></font>
201 380 </div>
381 +<?php
202 382
203 -<?php
383 +/**
384 + * Re-run a profile.
385 + */
386 +if (! empty( $rerun ) ) {
387 + echo '<script>window.addEventListener("load", cpjs_start_profiler);</script>';
388 +}
204 389
205 390 // =====================================================================
206 391 // Fetch pages and posts.
207 392
@@ -208,26 +393,32 @@
208 393 function code_profiler_fetch_pages( $home, $cp_options ) {
209 394
210 395 $posts = '';
211 396
212 - if ( empty( $cp_options['mem_post'] ) ) {
213 - $cp_options['mem_post'] = $home;
397 + if ( empty( $cp_options['mem']['post'] ) ) {
398 + $cp_options['mem']['post'] = $home;
214 399 }
215 400
216 - if ( $cp_options['mem_post'] == $home ) {
217 - $pages = '<option value="'. esc_attr( $home ) .'" title="'. esc_attr( $home ) .'" selected>'.
218 - esc_html__('Homepage', 'code-profiler') .'</option>';
401 + if ( $cp_options['mem']['post'] == $home ) {
402 + $pages = sprintf(
403 + '<option value="%1$s" title="%1$s" selected>%2$s</option>',
404 + esc_attr( $home ),
405 + esc_html__('Homepage', 'code-profiler')
406 + );
219 407 } else {
220 - $pages = '<option value="'. esc_attr( $home ) .'" title="'. esc_attr( $home ) .'">'.
221 - esc_html__('Homepage', 'code-profiler') .'</option>';
408 + $pages = sprintf(
409 + '<option value="%1$s" title="%1$s">%2$s</option>',
410 + esc_attr( $home ),
411 + esc_html__('Homepage', 'code-profiler')
412 + );
222 413 }
223 - $args = array(
414 + $args = [
224 415 'posts_per_page' => -1,
225 - 'post_type' => array( 'page' ),
416 + 'post_type' => ['page'],
226 417 'post_status' => 'publish',
227 418 'orderby' => 'post_name',
228 - 'order' => 'ASC',
229 - );
419 + 'order' => 'ASC'
420 + ];
230 421 $query = new WP_Query( $args );
231 422
232 423 if ( $query ) {
233 424 $items = $query->posts;
@@ -236,19 +427,25 @@
236 427 $item->post_title = __('Untitled');
237 428 }
238 429 $permalink = get_permalink( $item->ID );
239 430
240 - if ( $cp_options['mem_post'] == $permalink ) {
241 - $pages .= '<option value="'. esc_attr( $permalink ).'" title="'.
242 - esc_attr( $permalink ) .'" selected>'. esc_html( $item->post_title ) .'</option>';
431 + if ( $cp_options['mem']['post'] == $permalink ) {
432 + $pages .= sprintf(
433 + '<option value="%1$s" title="%1$s" selected>%2$s</option>',
434 + esc_attr( $permalink ),
435 + esc_html( $item->post_title )
436 + );
243 437 } else {
244 - $pages .= '<option value="'. esc_attr( $permalink ).'" title="'.
245 - esc_attr( $permalink ) .'">'. esc_html( $item->post_title ) .'</option>';
438 + $pages .= sprintf(
439 + '<option value="%1$s" title="%1$s">%2$s</option>',
440 + esc_attr( $permalink ),
441 + esc_html( $item->post_title )
442 + );
246 443 }
247 444 }
248 445 }
249 446
250 - return sprintf( '<optgroup label="%s">%s</optgroup>',
447 + return sprintf('<optgroup label="%s">%s</optgroup>',
251 448 esc_attr__('Pages', 'code-profiler'),
252 449 $pages
253 450 );
254 451 }
@@ -259,36 +456,79 @@
259 456 function code_profiler_fetch_admin_pages( $home, $cp_options ) {
260 457
261 458 $backend = '';
262 459
263 - if ( empty( $cp_options['mem_post'] ) ) {
264 - $cp_options['mem_post'] = $home;
460 + if ( empty( $cp_options['mem']['post'] ) ) {
461 + $cp_options['mem']['post'] = $home;
265 462 }
266 463
267 464 if (! empty( $GLOBALS[ 'menu' ] ) ) {
268 465 foreach( $GLOBALS[ 'menu' ] as $menu => $value ) {
269 - if (! empty( $value[0] ) && substr( $value[2], -4 ) == '.php' ) {
466 + if (! empty( $value[0] ) && substr( $value[2], -4 ) == '.php') {
270 467 // E.g., "Comments", "Plugins" etc
271 - $value[0] = trim( preg_replace( '/\s+<.+$/', '', $value[0] ) );
468 + $value[0] = trim( preg_replace('/\s*<.+$/', '', $value[0] ) );
272 469
273 - if ( $cp_options['mem_post'] == "{$home}wp-admin/{$value[2]}" ) {
274 - $backend .= '<option value="'. esc_attr( "{$home}wp-admin/{$value[2]}" ) .'" title="'.
275 - esc_attr( "{$home}wp-admin/{$value[2]}" ) .'" selected>'.
276 - esc_html( $value[0] ) .'</option>';
470 + if ( $cp_options['mem']['post'] == "{$home}wp-admin/{$value[2]}" ) {
471 + $backend .= sprintf(
472 + '<option value="%1$s" title="%1$s" selected>%2$s</option>',
473 + esc_attr("{$home}wp-admin/{$value[2]}"),
474 + esc_html( $value[0] )
475 + );
277 476 } else {
278 - $backend .= '<option value="'. esc_attr( "{$home}wp-admin/{$value[2]}" ) .'" title="'.
279 - esc_attr( "{$home}wp-admin/{$value[2]}" ) .'">'.
280 - esc_html( $value[0] ) .'</option>';
477 + $backend .= sprintf(
478 + '<option value="%1$s" title="%1$s">%2$s</option>',
479 + esc_attr("{$home}wp-admin/{$value[2]}"),
480 + esc_html( $value[0] )
481 + );
281 482 }
282 483 }
283 484 }
284 485 }
285 486 if ( empty( $backend ) ) {
286 - $backend = '<option value="'. esc_attr( $home ) .'wp-admin/" title="'. esc_attr( $home ) .'wp-admin/">'.
287 - esc_html__( 'Dashboard', 'code-profiler' ) .'</option>';
487 + $backend = sprintf(
488 + '<option value="%1$swp-admin/" title="%1$swp-admin/">%2$s</option>',
489 + esc_attr( $home ),
490 + esc_html__('Dashboard', 'code-profiler')
491 + );
492 +
288 493 }
494 + return $backend;
495 +}
289 496
290 - return $backend;
497 +// =====================================================================
498 +// Fetch scheduled tasks.
499 +
500 +function code_profiler_fetch_crontasks( $mem ) {
501 +
502 + $cron_list = '';
503 +
504 + $wp_crons = code_profiler_get_crons();
505 +
506 + if ( empty( $wp_crons ) ) {
507 + $cron_list = sprintf(
508 + '<option value="0">%s</option>',
509 + esc_html__('No cron tasks found.', 'code-profiler')
510 + );
511 + return $cron_list;
512 + }
513 +
514 + foreach( $wp_crons as $cron ) {
515 +
516 + if ( $mem == $cron ) {
517 + $selected = ' selected';
518 + } else {
519 + $selected = '';
520 + }
521 +
522 + $cron_list .= sprintf(
523 + "<option value='%s'%s>%s</option>",
524 + esc_attr( $cron ),
525 + $selected,
526 + esc_html( $cron )
527 + );
528 + }
529 +
530 + return $cron_list;
291 531 }
292 532
293 533 // =====================================================================
294 534 // EOF