forked from WordPress/performance
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathload.php
334 lines (299 loc) · 11.2 KB
/
load.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
<?php
/**
* Plugin Name: Performance Lab
* Plugin URI: https://github.com/WordPress/performance
* Description: Performance plugin from the WordPress Performance Team, which is a collection of standalone performance features.
* Requires at least: 6.4
* Requires PHP: 7.2
* Version: 3.0.0
* Author: WordPress Performance Team
* Author URI: https://make.wordpress.org/performance/
* License: GPLv2 or later
* License URI: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* Text Domain: performance-lab
*
* @package performance-lab
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
define( 'PERFLAB_VERSION', '3.0.0' );
define( 'PERFLAB_MAIN_FILE', __FILE__ );
define( 'PERFLAB_PLUGIN_DIR_PATH', plugin_dir_path( PERFLAB_MAIN_FILE ) );
define( 'PERFLAB_SCREEN', 'performance-lab' );
// If the constant isn't defined yet, it means the Performance Lab object cache file is not loaded.
if ( ! defined( 'PERFLAB_OBJECT_CACHE_DROPIN_VERSION' ) ) {
define( 'PERFLAB_OBJECT_CACHE_DROPIN_VERSION', false );
}
define( 'PERFLAB_OBJECT_CACHE_DROPIN_LATEST_VERSION', 3 );
// Load server-timing API.
require_once PERFLAB_PLUGIN_DIR_PATH . 'includes/server-timing/class-perflab-server-timing-metric.php';
require_once PERFLAB_PLUGIN_DIR_PATH . 'includes/server-timing/class-perflab-server-timing.php';
require_once PERFLAB_PLUGIN_DIR_PATH . 'includes/server-timing/load.php';
require_once PERFLAB_PLUGIN_DIR_PATH . 'includes/server-timing/defaults.php';
// Load site health checks.
require_once PERFLAB_PLUGIN_DIR_PATH . 'includes/site-health/load.php';
/**
* Gets the content attribute for the generator tag for the Performance Lab plugin.
*
* This attribute is then used in {@see perflab_render_generator()}.
*
* @since 1.1.0
* @since 2.9.0 The generator tag now includes the active standalone plugin slugs.
* @since 3.0.0 The generator tag no longer includes module slugs.
*/
function perflab_get_generator_content() {
$active_plugins = array();
foreach ( perflab_get_standalone_plugin_version_constants() as $plugin_slug => $constant_name ) {
if ( defined( $constant_name ) && ! str_starts_with( constant( $constant_name ), 'Performance Lab ' ) ) {
$active_plugins[] = $plugin_slug;
}
}
return sprintf(
// Use the plugin slug as it is immutable.
'performance-lab %1$s; plugins: %2$s',
PERFLAB_VERSION,
implode( ', ', $active_plugins )
);
}
/**
* Displays the HTML generator tag for the Performance Lab plugin.
*
* See {@see 'wp_head'}.
*
* @since 1.1.0
*/
function perflab_render_generator() {
$content = perflab_get_generator_content();
echo '<meta name="generator" content="' . esc_attr( $content ) . '">' . "\n";
}
add_action( 'wp_head', 'perflab_render_generator' );
/**
* Gets the standalone plugins and their data.
*
* @since 3.0.0
*
* @return array<string, array{'constant': string, 'experimental'?: bool}> Associative array of $plugin_slug => $plugin_data pairs.
*/
function perflab_get_standalone_plugin_data() {
/*
* Alphabetically sorted list of plugin slugs and their data.
* Supported keys per plugin are:
* - 'constant' (string, required)
* - 'experimental' (boolean, optional)
*/
return array(
'auto-sizes' => array(
'constant' => 'IMAGE_AUTO_SIZES_VERSION',
'experimental' => true,
),
'dominant-color-images' => array(
'constant' => 'DOMINANT_COLOR_IMAGES_VERSION',
),
'embed-optimizer' => array(
'constant' => 'EMBED_OPTIMIZER_VERSION',
'experimental' => true,
),
// TODO: Add image loading optimization plugin, dependent of Optimization Detective, once ready for end users.
'performant-translations' => array(
'constant' => 'PERFORMANT_TRANSLATIONS_VERSION',
),
'speculation-rules' => array(
'constant' => 'SPECULATION_RULES_VERSION',
),
'webp-uploads' => array(
'constant' => 'WEBP_UPLOADS_VERSION',
),
);
}
/**
* Gets the standalone plugin constants used for each available standalone plugin.
*
* @since 2.9.0
* @since 3.0.0 The $source parameter was removed.
*
* @return array<string, string> Map of plugin slug and the version constant used.
*/
function perflab_get_standalone_plugin_version_constants() {
return wp_list_pluck( perflab_get_standalone_plugin_data(), 'constant' );
}
/**
* Places the Performance Lab's object cache drop-in in the drop-ins folder.
*
* This only runs in WP Admin to not have any potential performance impact on
* the frontend.
*
* This function will short-circuit if at least one of the constants
* 'PERFLAB_DISABLE_SERVER_TIMING' or 'PERFLAB_DISABLE_OBJECT_CACHE_DROPIN' is
* set as true.
*
* @since 1.8.0
* @since 2.1.0 No longer attempts to use two of the drop-ins together.
*
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
*/
function perflab_maybe_set_object_cache_dropin() {
global $wp_filesystem;
// Bail if Server-Timing is disabled entirely.
if ( defined( 'PERFLAB_DISABLE_SERVER_TIMING' ) && PERFLAB_DISABLE_SERVER_TIMING ) {
return;
}
// Bail if disabled via constant.
if ( defined( 'PERFLAB_DISABLE_OBJECT_CACHE_DROPIN' ) && PERFLAB_DISABLE_OBJECT_CACHE_DROPIN ) {
return;
}
/**
* Filters whether the Perflab server timing drop-in should be set.
*
* @since 2.0.0
*
* @param bool $disabled Whether to disable the server timing drop-in. Default false.
*/
if ( apply_filters( 'perflab_disable_object_cache_dropin', false ) ) {
return;
}
/**
* Filters the value of the `object-cache.php` drop-in constant.
*
* This filter should not be used outside of tests.
*
* @since 3.0.0
* @internal
*
* @param int|bool $current_dropin_version The drop-in version as defined by the
* `PERFLAB_OBJECT_CACHE_DROPIN_VERSION` constant.
*/
$current_dropin_version = apply_filters( 'perflab_object_cache_dropin_version', PERFLAB_OBJECT_CACHE_DROPIN_VERSION );
// Bail if already placed in the latest version or newer.
if ( $current_dropin_version && $current_dropin_version >= PERFLAB_OBJECT_CACHE_DROPIN_LATEST_VERSION ) {
return;
}
// Bail if already attempted before timeout has been completed.
// This is present in case placing the file fails for some reason, to avoid
// excessively retrying to place it on every request.
$timeout = get_transient( 'perflab_set_object_cache_dropin' );
if ( false !== $timeout ) {
return;
}
if ( $wp_filesystem || WP_Filesystem() ) {
$dropin_path = WP_CONTENT_DIR . '/object-cache.php';
/*
* If there is an actual object-cache.php file, it is most likely from
* a third party, or it may be an older version of the Performance Lab
* object-cache.php. If it's from a third party, do not replace it.
*
* Previous versions of the Performance Lab plugin were renaming the
* original object-cache.php file and then loading both. However, due
* to other plugins eagerly checking file headers, this caused too many
* problems across sites, so it was decided to remove this layer.
* Only placing the drop-in file if no other one exists yet is the
* safest solution.
*/
if ( $wp_filesystem->exists( $dropin_path ) ) {
// If this constant evaluates to `false`, the existing file is for sure from a third party.
if ( ! $current_dropin_version ) {
// Set timeout of 1 day before retrying again (only in case the file already exists).
set_transient( 'perflab_set_object_cache_dropin', true, DAY_IN_SECONDS );
return;
}
// Otherwise, verify that it's actually the Performance Lab drop-in.
$test_content = "<?php\n/**\n * Plugin Name: Performance Lab Server Timing Object Cache Drop-In\n";
if ( ! str_starts_with( $wp_filesystem->get_contents( $dropin_path ), $test_content ) ) {
// Set timeout of 1 day before retrying again (only in case the file already exists).
set_transient( 'perflab_set_object_cache_dropin', true, DAY_IN_SECONDS );
return;
}
/*
* If this logic is reached, the existing file is an older version
* of the Performance Lab drop-in, so it can be safely deleted, and
* then be replaced below.
*/
$wp_filesystem->delete( $dropin_path );
}
$wp_filesystem->copy( PERFLAB_PLUGIN_DIR_PATH . 'includes/server-timing/object-cache.copy.php', $dropin_path );
}
// Set timeout of 1 hour before retrying again (only relevant in case the above failed).
set_transient( 'perflab_set_object_cache_dropin', true, HOUR_IN_SECONDS );
}
add_action( 'admin_init', 'perflab_maybe_set_object_cache_dropin' );
/**
* Removes the Performance Lab's object cache drop-in from the drop-ins folder.
*
* This function should be run on plugin deactivation. For backward compatibility with
* an earlier implementation of `perflab_maybe_set_object_cache_dropin()`, this function
* checks whether there is an object-cache-plst-orig.php file, and if so restores it.
*
* This function will short-circuit if the constant
* 'PERFLAB_DISABLE_OBJECT_CACHE_DROPIN' is set as true.
*
* @since 1.8.0
*
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
*/
function perflab_maybe_remove_object_cache_dropin() {
global $wp_filesystem;
// Bail if disabled via constant.
if ( defined( 'PERFLAB_DISABLE_OBJECT_CACHE_DROPIN' ) && PERFLAB_DISABLE_OBJECT_CACHE_DROPIN ) {
return;
}
// Bail if custom drop-in not present anyway.
if ( ! PERFLAB_OBJECT_CACHE_DROPIN_VERSION ) {
return;
}
if ( $wp_filesystem || WP_Filesystem() ) {
$dropin_path = WP_CONTENT_DIR . '/object-cache.php';
$dropin_backup_path = WP_CONTENT_DIR . '/object-cache-plst-orig.php';
/**
* If there is an object-cache-plst-orig.php file, restore it and
* override the Performance Lab file. This is only relevant for
* backward-compatibility with previous Performance Lab versions
* which were backing up the file and then loading both.
* Otherwise, just delete the Performance Lab file.
*/
if ( $wp_filesystem->exists( $dropin_backup_path ) ) {
$wp_filesystem->move( $dropin_backup_path, $dropin_path, true );
} else {
$wp_filesystem->delete( $dropin_path );
}
}
// Delete transient for drop-in check in case the plugin is reactivated shortly after.
delete_transient( 'perflab_set_object_cache_dropin' );
}
register_deactivation_hook( __FILE__, 'perflab_maybe_remove_object_cache_dropin' );
/**
* Redirects legacy module page to the performance feature page.
*
* @since 3.0.0
*
* @global $plugin_page
*/
function perflab_no_access_redirect_module_to_performance_feature_page() {
global $plugin_page;
if ( 'perflab-modules' !== $plugin_page ) {
return;
}
if (
current_user_can( 'manage_options' ) &&
wp_safe_redirect( add_query_arg( 'page', PERFLAB_SCREEN ) )
) {
exit;
}
}
add_action( 'admin_page_access_denied', 'perflab_no_access_redirect_module_to_performance_feature_page' );
/**
* Cleanup function to delete legacy 'perflab_modules_settings' option if present.
*
* @since 3.0.0
*/
function perflab_cleanup_option() {
if ( current_user_can( 'manage_options' ) ) {
delete_option( 'perflab_modules_settings' );
}
}
add_action( 'admin_init', 'perflab_cleanup_option' );
// Only load admin integration when in admin.
if ( is_admin() ) {
require_once PERFLAB_PLUGIN_DIR_PATH . 'includes/admin/load.php';
require_once PERFLAB_PLUGIN_DIR_PATH . 'includes/admin/server-timing.php';
require_once PERFLAB_PLUGIN_DIR_PATH . 'includes/admin/plugins.php';
}