diff --git a/admin/server-timing.php b/admin/server-timing.php new file mode 100644 index 0000000000..8dd412b2eb --- /dev/null +++ b/admin/server-timing.php @@ -0,0 +1,131 @@ + +

+ +

+ 'server_timing_benchmarking_actions' ) + ); + add_settings_field( + 'benchmarking_filters', + __( 'Filters', 'performance-lab' ), + static function() { + perflab_render_server_timing_page_field( 'benchmarking_filters' ); + }, + PERFLAB_SERVER_TIMING_SCREEN, + 'benchmarking', + array( 'label_for' => 'server_timing_benchmarking_filters' ) + ); +} + +/** + * Renders the Server-Timing page. + * + * @since n.e.x.t + */ +function perflab_render_server_timing_page() { + ?> +
+ +

+ +

+ +
+ + + +
+
+ + +

+ +

+ Server-Timing" screen. + * + * @since n.e.x.t + */ +function perflab_register_additional_server_timing_metrics_from_setting() { + $options = (array) get_option( PERFLAB_SERVER_TIMING_SETTING, array() ); + + if ( isset( $options['benchmarking_actions'] ) ) { + foreach ( $options['benchmarking_actions'] as $action ) { + $metric_slug = 'action-' . $action; + + $measure_callback = function( $metric ) use ( $action ) { + $metric->measure_before(); + add_action( $action, array( $metric, 'measure_after' ), PHP_INT_MAX, 0 ); + }; + + add_action( + $action, + static function() use ( $metric_slug, $measure_callback ) { + perflab_server_timing_register_metric( + $metric_slug, + array( + 'measure_callback' => $measure_callback, + 'access_cap' => 'exist', + ) + ); + }, + defined( 'PHP_INT_MIN' ) ? PHP_INT_MIN : -9999 + ); + } + } + + if ( isset( $options['benchmarking_filters'] ) ) { + foreach ( $options['benchmarking_filters'] as $filter ) { + $metric_slug = 'filter-' . $filter; + + $measure_callback = function( $metric ) use ( $filter ) { + $metric->measure_before(); + add_filter( + $filter, + static function( $passthrough ) use ( $metric ) { + $metric->measure_after(); + return $passthrough; + }, + PHP_INT_MAX + ); + }; + + add_filter( + $filter, + static function( $passthrough ) use ( $metric_slug, $measure_callback ) { + perflab_server_timing_register_metric( + $metric_slug, + array( + 'measure_callback' => $measure_callback, + 'access_cap' => 'exist', + ) + ); + return $passthrough; + }, + defined( 'PHP_INT_MIN' ) ? PHP_INT_MIN : -9999 + ); + } + } +} + +/* + * If this file is loaded from the Server-Timing logic in the object-cache.php + * drop-in, it must not call this function right away since otherwise the cache + * will not be loaded yet. + */ +if ( ! did_action( 'muplugins_loaded' ) ) { + add_action( 'muplugins_loaded', 'perflab_register_additional_server_timing_metrics_from_setting' ); +} else { + perflab_register_additional_server_timing_metrics_from_setting(); +} diff --git a/server-timing/load.php b/server-timing/load.php index 10ea912b72..1c0292917a 100644 --- a/server-timing/load.php +++ b/server-timing/load.php @@ -6,6 +6,54 @@ * @since 1.8.0 */ +define( 'PERFLAB_SERVER_TIMING_SETTING', 'perflab_server_timing_settings' ); +define( 'PERFLAB_SERVER_TIMING_SCREEN', 'perflab-server-timing' ); + +/** + * Registers the Server-Timing setting. + * + * @since n.e.x.t + */ +function perflab_register_server_timing_setting() { + register_setting( + PERFLAB_SERVER_TIMING_SCREEN, + PERFLAB_SERVER_TIMING_SETTING, + array( + 'type' => 'object', + 'sanitize_callback' => 'perflab_sanitize_server_timing_setting', + 'default' => array(), + ) + ); +} +add_action( 'init', 'perflab_register_server_timing_setting' ); + +/** + * Sanitizes the Server-Timing setting. + * + * @since n.e.x.t + * + * @param mixed $value Server-Timing setting value. + * @return array Sanitized Server-Timing setting value. + */ +function perflab_sanitize_server_timing_setting( $value ) { + if ( ! is_array( $value ) ) { + return array(); + } + + // Ensure that every element is an indexed array of hook names. + return array_filter( + array_map( + static function( $hooks ) { + if ( ! is_array( $hooks ) ) { + $hooks = explode( "\n", $hooks ); + } + return array_filter( array_map( 'sanitize_key', $hooks ) ); + }, + $value + ) + ); +} + /** * Provides access the Server-Timing API. *