PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backup, Restore, Migration & Clone / 4.9.2
WP STAGING – WordPress Backup, Restore, Migration & Clone v4.9.2
4.9.2 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 / Backend / Optimizer / wp-staging-optimizer.php
wp-staging / Backend / Optimizer Last commit date
Optimizer.php 2 months ago wp-staging-optimizer.php 1 year ago
wp-staging-optimizer.php
368 lines
1 <?php
2
3 /*
4 * Plugin Name: WP STAGING Optimizer
5 * Plugin URI: https://wp-staging.com
6 * Description: Prevents 3rd party plugins from being loaded during WP STAGING specific operations.
7 *
8 * This is a must-use standalone plugin -
9 * Do not use any of these methods in WP STAGING code base as this mu-plugin can be missing!
10 *
11 * Do not implement PHP type declarations into this file!
12 * This can lead to fatal errors due to mixed return results in the used wp core functions.
13 * See https://github.com/wp-staging/wp-staging-pro/issues/2830
14 *
15 * Author: WP STAGING
16 * Version: 1.6.0
17 * Author URI: https://wp-staging.com
18 * Text Domain: wp-staging
19 */
20
21 // Version number of this mu-plugin. Important for automatic updates
22 // Important: Update WPSTG_OPTIMIZER_MUVERSION in /bootstrap.php to the same version!
23
24 if (!defined('WPSTG_OPTIMIZER_VERSION')) {
25 define('WPSTG_OPTIMIZER_VERSION', '1.6.0');
26 }
27
28 if (!function_exists('wpstgGetPluginsDir')) {
29 /** @return string */
30 function wpstgGetPluginsDir(): string
31 {
32 $pluginsDir = '';
33 if (defined('WP_PLUGIN_DIR')) {
34 $pluginsDir = trailingslashit(WP_PLUGIN_DIR);
35 } elseif (defined('WP_CONTENT_DIR')) {
36 $pluginsDir = trailingslashit(WP_CONTENT_DIR) . 'plugins/';
37 }
38
39 return $pluginsDir;
40 }
41 }
42
43 if (!function_exists('wpstgIsEnabledOptimizer')) {
44 /**
45 * Check if optimizer is enabled
46 * @return bool
47 */
48 function wpstgIsEnabledOptimizer(): bool
49 {
50 $status = (object)get_option('wpstg_settings');
51
52 if ($status && isset($status->optimizer) && $status->optimizer == 1) {
53 return true;
54 }
55
56 return false;
57 }
58 }
59
60 if (!function_exists('wpstgIsExcludedPlugin')) {
61 /**
62 * Check if a plugin should be excluded from the optimizer and still running during wp staging requests
63 * @param string $plugin
64 * @return bool
65 */
66 function wpstgIsExcludedPlugin(string $plugin): bool
67 {
68 $excludedPlugins = get_option('wpstg_optimizer_excluded', []);
69
70 // Check for custom excluded plugins
71 foreach ($excludedPlugins as $excludedPlugin) {
72 if (strpos($plugin, $excludedPlugin) !== false) {
73 return true;
74 }
75 }
76
77 return false;
78 }
79 }
80
81 if (!function_exists('wpstgExcludePlugins')) {
82 /**
83 * Remove all plugins except wp-staging and wp-staging-pro from blog-active plugins
84 *
85 * @param array $plugins numerically keyed array of plugin names (index=>name)
86 *
87 * @return array
88 */
89 function wpstgExcludePlugins($plugins)
90 {
91 if (!is_array($plugins) || empty($plugins)) {
92 return [];
93 }
94
95 if (!wpstgIsOptimizerRequest()) {
96 return $plugins;
97 }
98
99 foreach ($plugins as $key => $plugin) {
100 // Default filter. Must be at the beginning or wp staging plugin will be filtered and killed
101 if (strpos($plugin, 'wp-staging') !== false || wpstgIsExcludedPlugin($plugin)) {
102 continue;
103 }
104
105 unset($plugins[$key]);
106 }
107
108
109 return $plugins;
110 }
111
112 add_filter('option_active_plugins', 'wpstgExcludePlugins');
113 }
114
115 if (!function_exists('wpstgExcludeSitePlugins')) {
116 /**
117 * Remove all plugins except wp-staging and wp-staging-pro from network-active plugins
118 *
119 * @param array $plugins array of plugins keyed by name (name=>timestamp pairs)
120 *
121 * @return array
122 */
123 function wpstgExcludeSitePlugins($plugins)
124 {
125 if (!is_array($plugins) || empty($plugins)) {
126 return [];
127 }
128
129 if (!wpstgIsOptimizerRequest()) {
130 return $plugins;
131 }
132
133 foreach ($plugins as $plugin => $timestamp) {
134 // Default filter. Must be at the beginning or wp staging plugin will be filtered and killed
135 if (strpos($plugin, 'wp-staging') !== false || wpstgIsExcludedPlugin($plugin)) {
136 continue;
137 }
138
139 unset($plugins[$plugin]);
140 }
141
142 return $plugins;
143 }
144
145 if (is_multisite()) {
146 add_filter('site_option_active_sitewide_plugins', 'wpstgExcludeSitePlugins');
147 }
148 }
149
150 if (!function_exists('wpstgDisableTheme')) {
151 /**
152 *
153 * Disables the active theme during WP Staging AJAX requests
154 *
155 *
156 * @param string $dir
157 *
158 * @return string
159 */
160 function wpstgDisableTheme($dir)
161 {
162 $enableTheme = apply_filters('wpstg_optimizer_enable_theme', false);
163
164 if (wpstgIsOptimizerRequest() && $enableTheme === false) {
165 $wpstgRootPro = wpstgGetPluginsDir() . 'wp-staging-pro';
166 $wpstgRoot = wpstgGetPluginsDir() . 'wp-staging';
167
168 $theme = '/resources/blank-theme';
169 $file = $theme . '/functions.php';
170
171 if (file_exists($wpstgRoot . $file)) {
172 return $wpstgRoot . $theme;
173 } elseif (file_exists($wpstgRootPro . $file)) {
174 return $wpstgRootPro . $theme;
175 } else {
176 return '';
177 }
178 }
179
180 return $dir;
181 }
182
183 add_filter('stylesheet_directory', 'wpstgDisableTheme');
184 add_filter('template_directory', 'wpstgDisableTheme');
185 }
186
187 if (!function_exists('wpstgIsOptimizerRequest')) {
188 /**
189 * Should the current request be processed by optimizer?
190 *
191 * For WP STAGING requests that require other plugins to be active, use raw_wpstg_{actionName}
192 *
193 * @return bool
194 */
195 function wpstgIsOptimizerRequest(): bool
196 {
197 if (!wpstgIsEnabledOptimizer()) {
198 return false;
199 }
200
201 if (isset($_POST['wpstg_action']) && sanitize_text_field($_POST['wpstg_action']) === 'bypass_optimizer') {
202 return false;
203 }
204
205 if (
206 defined('DOING_AJAX') &&
207 DOING_AJAX &&
208 isset($_REQUEST['action']) &&
209 strpos(sanitize_text_field($_REQUEST['action']), 'wpstg_send_report') === false &&
210 strpos(sanitize_text_field($_REQUEST['action']), 'wpstg--send--otp') === false &&
211 strpos(sanitize_text_field($_REQUEST['action']), 'wpstg') === 0
212 ) {
213 return true;
214 }
215
216 return false;
217 }
218 }
219
220 if (!function_exists('wpstgTgmpaCompatibility')) {
221 /**
222 * Remove TGM Plugin Activation 'force_activation' admin_init action hook if present.
223 *
224 * This is to stop excluded plugins being deactivated after a migration, when a theme uses TGMPA to require a plugin to be always active.
225 */
226 function wpstgTgmpaCompatibility()
227 {
228 $isFunctionRemoved = false;
229
230 // run on wpstg page
231 if (isset($_GET['page']) && $_GET['page'] == 'wpstg_clone') {
232 $isFunctionRemoved = true;
233 }
234
235 // run on wpstg ajax requests
236 if (defined('DOING_AJAX') && DOING_AJAX && isset($_POST['action']) && strpos(sanitize_text_field($_POST['action']), 'wpstg') !== false) {
237 $isFunctionRemoved = true;
238 }
239
240 if ($isFunctionRemoved) {
241 global $wp_filter;
242
243 $adminInitFunctions = $wp_filter['admin_init'];
244 foreach ($adminInitFunctions as $priority => $functions) {
245 if (!isset($wp_filter['admin_init'][$priority])) {
246 continue;
247 }
248
249 foreach ($functions as $key => $function) {
250 if (!isset($wp_filter['admin_init'][$priority][$key])) {
251 continue;
252 }
253
254 // searching for function this way as can't rely on the calling class being named TGM_Plugin_Activation
255 if (strpos($key, 'force_activation') !== false) {
256 unset($wp_filter['admin_init'][$priority][$key]);
257
258 return;
259 }
260 }
261 }
262 }
263 }
264
265 add_action('admin_init', 'wpstgTgmpaCompatibility', 1);
266 }
267
268 if (!function_exists('wpstgIsStaging')) {
269 /**
270 * @return bool True if it is staging site. False otherwise.
271 */
272 function wpstgIsStaging(): bool
273 {
274 if (defined('WPSTAGING_DEV_SITE') && constant('WPSTAGING_DEV_SITE') === true) {
275 return true;
276 }
277
278 if (get_option("wpstg_is_staging_site") === "true") {
279 return true;
280 }
281
282 if (file_exists(ABSPATH . '.wp-staging')) {
283 return true;
284 }
285
286 return false;
287 }
288 }
289
290 if (!function_exists('wpstgGetCloneSettings')) {
291 /**
292 * Get the value of the given option in clone settings,
293 * If no option given return all clone settings
294 *
295 * @param string|null $option
296 * @return mixed
297 */
298 function wpstgGetCloneSettings($option = null)
299 {
300 $settings = get_option('wpstg_clone_settings', null);
301
302 if (!is_string($option)) {
303 return $settings;
304 }
305
306 if (!is_object($settings)) {
307 return null;
308 }
309
310 if (!property_exists($settings, $option)) {
311 return null;
312 }
313
314 return $settings->{$option};
315 }
316 }
317
318 /**
319 * Disable all outgoing e-mails on Staging site
320 * Will check against both the old and new logic of storing emails disabled option
321 */
322 if (wpstgIsStaging() && (((bool)get_option("wpstg_emails_disabled") === true) || (wpstgGetCloneSettings('wpstg_emails_disabled')))) {
323 if (!function_exists('wp_mail')) {
324 /**
325 * @param array|string $to
326 * @param string $subject
327 * @param string $message
328 * @param array|string $headers
329 * @param array|string $attachments
330 *
331 * @return bool
332 */
333 function wp_mail($to, $subject, $message, $headers = '', $attachments = [])
334 {
335 if (defined('WPSTG_DEBUG') && WPSTG_DEBUG) {
336 // Safely cast everything to string
337 $to = is_string($to) ? $to : wp_json_encode($to);
338 $subject = is_string($subject) ? $subject : wp_json_encode($subject);
339 $message = is_string($message) ? $message : wp_json_encode($message);
340 $headers = is_string($headers) ? $headers : wp_json_encode($headers);
341 $attachments = is_string($attachments) ? $attachments : wp_json_encode($attachments);
342
343 $log_entry = <<<LOG_ENTRY
344 /***
345 * WPSTAGING - Mails are disabled for this Staging site. This e-mail was going to be sent, but was prevented:
346 ***
347 * To: $to
348 ***
349 * Subject: $subject
350 ***
351 * Message: $message
352 ***
353 * Headers: $headers
354 ***
355 * Attachments: $attachments
356 ***/
357 LOG_ENTRY;
358
359 error_log($log_entry);
360 }
361
362 return false;
363 }
364 } elseif (defined('WPSTG_DEBUG') && WPSTG_DEBUG) {
365 error_log("WP STAGING: Could not override the wp_mail() function to disable e-mails on staging site, as it was already defined before the optimizer mu-plugin was loaded.");
366 }
367 }
368