PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backup, Restore, Migration & Clone / 4.9.0
WP STAGING – WordPress Backup, Restore, Migration & Clone v4.9.0
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 / Framework / Filesystem / OPcache.php
wp-staging / Framework / Filesystem Last commit date
Filters 6 months ago Scanning 5 years ago AbstractFileObject.php 1 year ago AbstractFilesystemScanner.php 2 months ago DebugLogReader.php 2 years ago DirectoryListing.php 5 months ago DiskWriteCheck.php 5 months ago FileObject.php 1 year ago Filesystem.php 6 months ago FilesystemExceptions.php 5 years ago FilesystemScanner.php 1 week ago FilesystemScannerDto.php 1 week ago FilterableDirectoryIterator.php 1 year ago LegacyFileRulesTrait.php 1 week ago LogCleanup.php 5 months ago LogFiles.php 1 year ago MissingFileException.php 3 years ago OPcache.php 5 months ago PartIdentifier.php 8 months ago PathChecker.php 2 years ago PathIdentifier.php 6 months ago Permissions.php 5 months ago WpUploadsFolderSymlinker.php 1 week ago
OPcache.php
195 lines
1 <?php
2
3 namespace WPStaging\Framework\Filesystem;
4
5 use WPStaging\Core\WPStaging;
6 use WPStaging\Framework\Utils\ServerVars;
7 use WPStaging\Framework\Facades\Hooks;
8
9 use function WPStaging\functions\debug_log;
10
11 class OPcache
12 {
13 /**
14 * @var string
15 */
16 const FILTER_OPCACHE_MAYBE_INVALIDATE = 'wpstg.opcache.maybe_invalidate';
17
18 /**
19 * @var ServerVars
20 */
21 private $serverVars;
22
23 public function __construct()
24 {
25 $this->serverVars = WPStaging::make(ServerVars::class);
26 }
27
28 /**
29 * Check if OPcache API is accessible (not restricted by opcache.restrict_api)
30 * @return bool
31 */
32 private function isOpCacheApiAccessible(): bool
33 {
34 $restrictApi = ini_get('opcache.restrict_api');
35 if (empty($restrictApi)) {
36 return true;
37 }
38
39 if (empty($_SERVER['SCRIPT_FILENAME'])) {
40 return false;
41 }
42
43 $scriptPath = realpath($_SERVER['SCRIPT_FILENAME']); // phpcs:ignore
44 if ($scriptPath === false) {
45 return false;
46 }
47
48 return stripos($scriptPath, $restrictApi) === 0;
49 }
50
51 public function reset(): bool
52 {
53 if (!function_exists('opcache_reset') || $this->serverVars->isFunctionDisabled('opcache_reset')) {
54 return false;
55 }
56
57 if (!$this->isOpCacheApiAccessible()) {
58 return false;
59 }
60
61 return @opcache_reset();
62 }
63
64 /**
65 * @see https://developer.wordpress.org/reference/functions/wp_opcache_invalidate/
66 * @param string $filePath
67 * @param bool $force
68 * @return bool
69 */
70 public function invalidateFile(string $filePath, bool $force = false): bool
71 {
72 static $canInvalidate = null;
73 if (
74 $canInvalidate === null
75 && function_exists('opcache_invalidate')
76 && (
77 !ini_get('opcache.restrict_api')
78 || !empty($_SERVER['SCRIPT_FILENAME']) && stripos(realpath($_SERVER['SCRIPT_FILENAME']), ini_get('opcache.restrict_api')) === 0 // phpcs:ignore
79 )
80 ) {
81 $canInvalidate = true;
82 }
83
84 if (!$canInvalidate || strtolower(substr($filePath, -4)) !== '.php') {
85 return false;
86 }
87
88 if (!$this->isOpCacheApiAccessible()) {
89 return false;
90 }
91
92 return @opcache_invalidate($filePath, $force);
93 }
94
95 /**
96 * @param string $dirPath
97 * @return void
98 */
99 public function invalidateDirectory(string $dirPath)
100 {
101 if (!is_dir($dirPath)) {
102 return;
103 }
104
105 $dirIterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dirPath));
106 foreach ($dirIterator as $fileInfo) {
107 if (!$fileInfo->isFile() || $fileInfo->isLink() || $fileInfo->getExtension() !== 'php') {
108 continue;
109 }
110
111 $this->invalidateFile($fileInfo->getRealPath(), true);
112 }
113 }
114
115 /** @return void */
116 public function maybeInvalidate()
117 {
118 if (!Hooks::applyFilters(self::FILTER_OPCACHE_MAYBE_INVALIDATE, true)) {
119 debug_log('opcache invalidate disabled.', 'info', false);
120 return;
121 }
122
123 // If can use opcache_reset
124 if ($this->reset()) {
125 debug_log('opcache_reset executed.', 'info', false);
126 return;
127 }
128
129 // Abort if opcache_invalidate not available
130 if (!function_exists('opcache_invalidate') || $this->serverVars->isFunctionDisabled('opcache_invalidate')) {
131 return;
132 }
133
134 debug_log('Trigger opcache invalidate.', 'info', false);
135
136 // If can use opcache_get_status
137 if (function_exists('opcache_get_status') && !$this->serverVars->isFunctionDisabled('opcache_get_status') && $this->isOpCacheApiAccessible()) {
138 $opcacheStatus = @opcache_get_status();
139 if (!empty($opcacheStatus['scripts'])) {
140 foreach ($opcacheStatus['scripts'] as $file => $data) {
141 $this->invalidateFile($file, true);
142 }
143 }
144
145 return;
146 }
147
148 // Invalidate wp core files
149 $wpCoreFiles = [
150 'index.php',
151 'wp-activate.php',
152 'wp-blog-header.php',
153 'wp-comments-post.php',
154 'wp-config-sample.php',
155 'wp-config.php',
156 'wp-cron.php',
157 'wp-links-opml.php',
158 'wp-load.php',
159 'wp-login.php',
160 'wp-mail.php',
161 'wp-settings.php',
162 'wp-signup.php',
163 'wp-trackback.php',
164 'xmlrpc.php',
165 ];
166
167 foreach ($wpCoreFiles as $file) {
168 $this->invalidateFile(ABSPATH . $file);
169
170 $parentFile = dirname(ABSPATH) . '/' . $file;
171 if (file_exists($parentFile)) {
172 $this->invalidateFile($parentFile);
173 }
174 }
175
176 // Invalidate directory
177 $wpCoreDirs = [
178 'wp-admin/',
179 'wp-includes/',
180 'wp-content/plugins/',
181 'wp-content/mu-plugins/',
182 'wp-content/themes/',
183 ];
184
185 foreach ($wpCoreDirs as $dir) {
186 $this->invalidateDirectory(ABSPATH . $dir);
187
188 $parentDir = dirname(ABSPATH) . '/' . $dir;
189 if (is_dir($parentDir)) {
190 $this->invalidateDirectory($parentDir);
191 }
192 }
193 }
194 }
195