PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backup, Restore, Migration & Clone / 4.8.1
WP STAGING – WordPress Backup, Restore, Migration & Clone v4.8.1
4.9.1 4.9.0 4.8.1 trunk 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.10.0 3.2.0 3.3.1 3.3.2 3.3.3 3.4.1 3.4.3 3.5.0 3.6.0 3.7.1 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 3.8.7 3.9.0 3.9.1 3.9.2 3.9.3 3.9.4 4.0.0 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.7.2 4.7.3 4.8.0
wp-staging / opcacheBootstrap.php
wp-staging Last commit date
Backend 1 month ago Backup 1 month ago Basic 3 months ago Component 1 month ago Core 1 month ago Framework 1 month ago Frontend 5 months ago Notifications 8 months ago Staging 1 month ago assets 1 month ago languages 1 month ago resources 1 year ago vendor_wpstg 1 month ago views 1 month ago CONTRIBUTING.md 1 year ago Deactivate.php 8 months ago README.md 3 months ago SECURITY.md 2 years ago autoloader.php 1 month ago bootstrap.php 1 month ago commonBootstrap.php 1 month ago constantsFree.php 1 month ago freeBootstrap.php 1 month ago install.php 1 year ago opcacheBootstrap.php 1 month ago readme.txt 1 month ago runtimeRequirements.php 3 months ago uninstall.php 1 month ago wp-staging-error-handler.php 6 months ago wp-staging.php 1 month ago
opcacheBootstrap.php
114 lines
1 <?php
2
3 /**
4 * WordPress installations with OPCache enabled might bootstrap in an
5 * incoherent state from PHP and the Filesystem, causing fatal errors if
6 * upgrading to a newer version where a file has been removed.
7 *
8 * This file clears OPCache in this plugin if needed.
9 *
10 * WordPress 5.5+ handles OPCache invalidation depending on
11 * whether \WP_Upgrader::run is called with the "clear_destination"
12 * parameter set to true.
13 *
14 * @var string $pluginFilePath
15 * @var string $wp_version
16 */
17 global $wp_version, $pluginFilePath;
18
19 // Early bail: WordPress 5.5+ already handles OPCache invalidation on plugin updates.
20 if (version_compare($wp_version, '5.5', '>=')) {
21 return;
22 }
23
24 $filename = isset($_SERVER['SCRIPT_FILENAME']) ? sanitize_text_field($_SERVER['SCRIPT_FILENAME']) : '';
25
26 // Ported from WordPress 5.5 wp_opcache_invalidate
27 $canInvalidate = function_exists('opcache_invalidate')
28 && (!ini_get('opcache.restrict_api') || stripos(realpath($filename), ini_get('opcache.restrict_api')) === 0);
29
30 // Early bail: OPCache not enabled, or we can't clear it.
31 if (!$canInvalidate) {
32 if (defined('WPSTG_DEBUG') && WPSTG_DEBUG) {
33 error_log('WP STAGING: Can not clear OPCache.');
34 }
35
36 return;
37 }
38
39 /*
40 * When a site has OPCache enabled, it will cache the compiled "opcode" of this PHP file and all other PHP files.
41 *
42 * It doesn't cache, however, the result returned by the functions.
43 *
44 * We leverage this to run a runtime check between the version in this PHP file and
45 * the filesystem. The only possible scenario they can be different, on a regular
46 * distributed plugin, is if the variable in PHP is opcached to a different version
47 * from what's in the filesystem.
48 *
49 * We use the "Version" from the headers of the main file of the plugin to compare.
50 */
51 $runtimeVersionDifferentFromBuildVersion = get_file_data($pluginFilePath, ['Version' => 'Version'])['Version'] !== '4.8.1';
52 $lastCheckHappenedAfterInterval = current_time('timestamp') > (int)get_site_transient('wpstg.bootstrap.opcache.lastCleared') + 5 * MINUTE_IN_SECONDS;
53
54 $shouldClearOpCache = apply_filters('wpstg.bootstrap.opcache.shouldClear', $runtimeVersionDifferentFromBuildVersion && $lastCheckHappenedAfterInterval);
55
56 if ($shouldClearOpCache) {
57 set_site_transient('wpstg.bootstrap.opcache.lastCleared', current_time('timestamp'), 1 * HOUR_IN_SECONDS);
58
59 $start = microtime(true);
60
61 clearstatcache(true);
62
63 try {
64 $it = new RecursiveDirectoryIterator(dirname($pluginFilePath));
65 } catch (Exception $e) {
66 // DirectoryIterator will throw if this plugin folder is not readable.
67 if (defined('WPSTG_DEBUG') && WPSTG_DEBUG) {
68 error_log('WPSTG failed to clear OPCache because the folder does not exist or is not readable. Exception: ' . $e->getMessage());
69 }
70
71 return;
72 }
73
74 $it = new RecursiveIteratorIterator($it);
75
76 $success = 0;
77 $failures = 0;
78
79 /** @var SplFileInfo $fileInfo */
80 foreach ($it as $fileInfo) {
81 if (
82 $fileInfo->isFile()
83 && !$fileInfo->isLink()
84 && $fileInfo->getExtension() === 'php'
85 ) {
86 if (opcache_invalidate($fileInfo->getRealPath(), false)) {
87 $success++;
88 } else {
89 $failures++;
90 }
91 }
92 }
93
94 add_action('admin_notices', function () use ($pluginFilePath, $start) {
95 echo '<div class="notice-warning notice is-dismissible">';
96 echo '<p style="font-weight: bold;">' . esc_html__('WP STAGING OPCache', 'wp-staging') . '</p>';
97 echo '<p>' . wp_kses_post(
98 sprintf(
99 __('WP STAGING detected that the OPCache was outdated and automatically cleared the OPCache for the <strong>%s</strong> folder to prevent issues. This operation took %s seconds.', 'wp-staging'),
100 plugin_basename($pluginFilePath),
101 number_format(microtime(true) - $start, 4)
102 )
103 ) . '</p>';
104 echo '</div>';
105 });
106
107 if (defined('WPSTG_DEBUG') && WPSTG_DEBUG) {
108 error_log(sprintf('%s files were cleared from OPCache in %s seconds', $success, microtime(true) - $start));
109 if (!empty($failures)) {
110 error_log(sprintf('WP STAGING could not clear %s files from the OpCache cache upon activation. There may be inconsistencies.', $failures));
111 }
112 }
113 }
114