PluginProbe
Performance Lab / trunk
Performance Lab vtrunk
trunk 1.0.0 1.0.0-beta.1 1.0.0-beta.2 1.0.0-beta.3 1.0.0-rc.1 1.1.0 1.2.0 1.3.0 1.4.0 1.5.0 1.6.0 1.7.0 1.8.0 1.9.0 2.0.0 2.1.0 2.2.0 2.3.0 2.4.0 2.5.0 2.6.0 2.6.1 2.7.0 2.8.0 All 44 releases
performance-lab / includes / admin / server-timing.php

server-timing.php in Performance Lab trunk, at includes/admin/server-timing.php

273 lines 8.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Server-Timing API admin integration file.
4 *
5 * @package performance-lab
6 */
7
8 declare( strict_types = 1 );
9
10 // @codeCoverageIgnoreStart
11 if ( ! defined( 'ABSPATH' ) ) {
12 exit; // Exit if accessed directly.
13 }
14 // @codeCoverageIgnoreEnd
15
16 // Do not add any of the hooks if Server-Timing is disabled.
17 if ( defined( 'PERFLAB_DISABLE_SERVER_TIMING' ) && PERFLAB_DISABLE_SERVER_TIMING ) {
18 return;
19 }
20
21 /**
22 * Adds the Server-Timing page to the Tools menu.
23 *
24 * @since 2.6.0
25 */
26 function perflab_add_server_timing_page(): void {
27 $hook_suffix = add_management_page(
28 __( 'Server-Timing', 'performance-lab' ),
29 __( 'Server-Timing', 'performance-lab' ),
30 'manage_options',
31 PERFLAB_SERVER_TIMING_SCREEN,
32 'perflab_render_server_timing_page'
33 );
34
35 // Add the following hooks only if the screen was successfully added.
36 if ( false !== $hook_suffix ) {
37 add_action( "load-{$hook_suffix}", 'perflab_load_server_timing_page' );
38 }
39 }
40
41 add_action( 'admin_menu', 'perflab_add_server_timing_page' );
42
43 /**
44 * Initializes settings sections and fields for the Server-Timing page.
45 *
46 * @since 2.6.0
47 */
48 function perflab_load_server_timing_page(): void {
49 /*
50 * This settings section technically includes a field, however it is directly rendered as part of the section
51 * callback due to requiring custom markup.
52 */
53 add_settings_section(
54 'output-buffering',
55 __( 'Output Buffering', 'performance-lab' ),
56 'perflab_render_server_timing_page_output_buffering_section',
57 PERFLAB_SERVER_TIMING_SCREEN
58 );
59
60 // Minor style tweaks to improve appearance similar to other core settings screen instances.
61 add_action(
62 'admin_print_styles',
63 static function (): void {
64 ?>
65 <style>
66 .wrap p {
67 max-width: 800px;
68 }
69 .wrap .form-table .td-full {
70 padding-top: 0;
71 }
72 </style>
73 <?php
74 }
75 );
76
77 add_settings_section(
78 'benchmarking',
79 __( 'Benchmarking', 'performance-lab' ),
80 static function (): void {
81 ?>
82 <p>
83 <?php
84 echo wp_kses(
85 sprintf(
86 /* translators: %s: Server-Timing */
87 __( 'In this section, you can provide hook names to include measurements for them in the %s header.', 'performance-lab' ),
88 '<code>Server-Timing</code>'
89 ),
90 array( 'code' => array() )
91 );
92 echo ' ';
93 echo wp_kses(
94 __( 'For any hook name provided, the <strong>cumulative duration between all callbacks</strong> attached to the hook is measured, in milliseconds.', 'performance-lab' ),
95 array( 'strong' => array() )
96 );
97 ?>
98 </p>
99 <?php if ( ! perflab_server_timing_use_output_buffer() ) : ?>
100 <p>
101 <?php
102 echo wp_kses(
103 sprintf(
104 /* translators: 1: Server-Timing, 2: template_include, 3: anchor link */
105 __( 'Since the %1$s header is sent before the template is loaded, only hooks before the %2$s filter can be measured. Enable <a href="%3$s">Output Buffering</a> to measure hooks during template rendering.', 'performance-lab' ),
106 '<code>Server-Timing</code>',
107 '<code>template_include</code>',
108 esc_url( '#server_timing_output_buffering' )
109 ),
110 array(
111 'code' => array(),
112 'a' => array( 'href' => true ),
113 )
114 );
115 ?>
116 <?php endif; ?>
117 </p>
118 <?php
119 },
120 PERFLAB_SERVER_TIMING_SCREEN
121 );
122
123 /*
124 * For all settings fields, the field slug, option sub key, and label
125 * suffix have to match for the rendering in the callback to be
126 * semantically correct.
127 */
128 add_settings_field(
129 'benchmarking_actions',
130 __( 'Actions', 'performance-lab' ),
131 static function (): void {
132 perflab_render_server_timing_page_hooks_field( 'benchmarking_actions' );
133 },
134 PERFLAB_SERVER_TIMING_SCREEN,
135 'benchmarking',
136 array( 'label_for' => 'server_timing_benchmarking_actions' )
137 );
138 add_settings_field(
139 'benchmarking_filters',
140 __( 'Filters', 'performance-lab' ),
141 static function (): void {
142 perflab_render_server_timing_page_hooks_field( 'benchmarking_filters' );
143 },
144 PERFLAB_SERVER_TIMING_SCREEN,
145 'benchmarking',
146 array( 'label_for' => 'server_timing_benchmarking_filters' )
147 );
148 }
149
150 /**
151 * Renders the Server-Timing page.
152 *
153 * @since 2.6.0
154 */
155 function perflab_render_server_timing_page(): void {
156 ?>
157 <div class="wrap">
158 <?php settings_errors(); ?>
159 <h1>
160 <?php esc_html_e( 'Server-Timing', 'performance-lab' ); ?>
161 </h1>
162
163 <form action="options.php" method="post">
164 <?php settings_fields( PERFLAB_SERVER_TIMING_SCREEN ); ?>
165 <?php do_settings_sections( PERFLAB_SERVER_TIMING_SCREEN ); ?>
166 <?php submit_button(); ?>
167 </form>
168 </div>
169 <?php
170 }
171
172 /**
173 * Renders a hooks field for the given Server-Timing option.
174 *
175 * @since 2.6.0
176 *
177 * @param string $slug Slug of the field and sub-key in the Server-Timing option.
178 */
179 function perflab_render_server_timing_page_hooks_field( string $slug ): void {
180 $options = (array) get_option( PERFLAB_SERVER_TIMING_SETTING, array() );
181
182 // Value for the sub-key is an array of hook names.
183 $value = '';
184 if ( isset( $options[ $slug ] ) ) {
185 $value = implode( "\n", $options[ $slug ] );
186 }
187
188 $field_id = "server_timing_{$slug}";
189 $field_name = PERFLAB_SERVER_TIMING_SETTING . '[' . $slug . ']';
190 $description_id = "{$field_id}_description";
191
192 ?>
193 <textarea
194 id="<?php echo esc_attr( $field_id ); ?>"
195 name="<?php echo esc_attr( $field_name ); ?>"
196 aria-describedby="<?php echo esc_attr( $description_id ); ?>"
197 class="large-text code"
198 rows="8"
199 ><?php echo esc_textarea( $value ); ?></textarea>
200 <p id="<?php echo esc_attr( $description_id ); ?>" class="description">
201 <?php esc_html_e( 'Enter a single hook name per line.', 'performance-lab' ); ?>
202 </p>
203 <?php
204 }
205
206 /**
207 * Renders the section for enabling output buffering for Server-Timing.
208 *
209 * @since 2.6.0
210 */
211 function perflab_render_server_timing_page_output_buffering_section(): void {
212 $slug = 'output_buffering';
213 $field_id = "server_timing_{$slug}";
214 $field_name = PERFLAB_SERVER_TIMING_SETTING . '[' . $slug . ']';
215 $description_id = "{$field_id}_description";
216 $has_filter = has_filter( 'perflab_server_timing_use_output_buffer' );
217 $is_enabled = perflab_server_timing_use_output_buffer();
218
219 /*
220 * The hard-coded .form-table output here overall matches the WordPress core markup generated by
221 * `do_settings_sections()` and `do_settings_fields()`, however since it is impossible to modify the CSS classes on
222 * the `<td>` elements, it needs to be hard-coded to achieve the same appearance as e.g. the UI control for the
223 * `uploads_use_yearmonth_folders` option in the _Settings > Media_ screen, which is hard-coded as well.
224 */
225 ?>
226 <table class="form-table" role="presentation">
227 <tr>
228 <td class="td-full">
229 <label for="<?php echo esc_attr( $field_id ); ?>">
230 <input
231 type="checkbox"
232 id="<?php echo esc_attr( $field_id ); ?>"
233 name="<?php echo esc_attr( $field_name ); ?>"
234 aria-describedby="<?php echo esc_attr( $description_id ); ?>"
235 <?php disabled( $has_filter ); ?>
236 <?php checked( $is_enabled ); ?>
237 >
238 <?php esc_html_e( 'Enable output buffering of template rendering', 'performance-lab' ); ?>
239 </label>
240 <p id="<?php echo esc_attr( $description_id ); ?>" class="description">
241 <?php if ( $has_filter ) : ?>
242 <?php if ( $is_enabled ) : ?>
243 <?php
244 echo wp_kses(
245 sprintf(
246 /* translators: %s: perflab_server_timing_use_output_buffer */
247 __( 'Output buffering has been forcibly enabled via the %s filter.', 'performance-lab' ),
248 '<code>perflab_server_timing_use_output_buffer</code>'
249 ),
250 array( 'code' => array() )
251 );
252 ?>
253 <?php else : ?>
254 <?php
255 echo wp_kses(
256 sprintf(
257 /* translators: %s: perflab_server_timing_use_output_buffer */
258 __( 'Output buffering has been forcibly disabled via the %s filter.', 'performance-lab' ),
259 '<code>perflab_server_timing_use_output_buffer</code>'
260 ),
261 array( 'code' => array() )
262 );
263 ?>
264 <?php endif; ?>
265 <?php endif; ?>
266 <?php esc_html_e( 'Output buffering is needed to capture metrics after headers have been sent and while the template is being rendered. Note that output buffering may possibly cause an increase in TTFB if the response would be flushed multiple times.', 'performance-lab' ); ?>
267 </p>
268 </td>
269 </tr>
270 </table>
271 <?php
272 }
273