PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backup, Restore, Migration & Clone / 3.3.1
WP STAGING – WordPress Backup, Restore, Migration & Clone v3.3.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 / Backend / Optimizer / wp-staging-optimizer.php
wp-staging / Backend / Optimizer Last commit date
blank-theme 5 years ago Optimizer.php 2 years ago wp-staging-optimizer.php 2 years ago
wp-staging-optimizer.php
362 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.5.5
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.5.5');
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 // As a workaround for now we exclude all-in-one-wp-security-and-firewall AIOWPS plugin due
71 // to their salt postfix function which breaks WP STAGING completely.
72 //$excludedPlugins[] = 'all-in-one-wp-security-and-firewall';
73
74 // Check for custom excluded plugins
75 foreach ($excludedPlugins as $excludedPlugin) {
76 if (strpos($plugin, $excludedPlugin) !== false) {
77 return true;
78 }
79 }
80
81 return false;
82 }
83 }
84
85 if (!function_exists('wpstgExcludePlugins')) {
86 /**
87 * Remove all plugins except wp-staging and wp-staging-pro from blog-active plugins
88 *
89 * @param array $plugins numerically keyed array of plugin names (index=>name)
90 *
91 * @return array
92 */
93 function wpstgExcludePlugins($plugins)
94 {
95 if (!is_array($plugins) || empty($plugins)) {
96 return [];
97 }
98
99 if (!wpstgIsOptimizerRequest()) {
100 return $plugins;
101 }
102
103 foreach ($plugins as $key => $plugin) {
104 // Default filter. Must be at the beginning or wp staging plugin will be filtered and killed
105 if (strpos($plugin, 'wp-staging') !== false || wpstgIsExcludedPlugin($plugin)) {
106 continue;
107 }
108
109 unset($plugins[$key]);
110 }
111
112
113 return $plugins;
114 }
115
116 add_filter('option_active_plugins', 'wpstgExcludePlugins');
117 }
118
119 if (!function_exists('wpstgExcludeSitePlugins')) {
120 /**
121 * Remove all plugins except wp-staging and wp-staging-pro from network-active plugins
122 *
123 * @param array $plugins array of plugins keyed by name (name=>timestamp pairs)
124 *
125 * @return array
126 */
127 function wpstgExcludeSitePlugins($plugins)
128 {
129 if (!is_array($plugins) || empty($plugins)) {
130 return [];
131 }
132
133 if (!wpstgIsOptimizerRequest()) {
134 return $plugins;
135 }
136
137 foreach ($plugins as $plugin => $timestamp) {
138 // Default filter. Must be at the beginning or wp staging plugin will be filtered and killed
139 if (strpos($plugin, 'wp-staging') !== false || wpstgIsExcludedPlugin($plugin)) {
140 continue;
141 }
142
143 unset($plugins[$plugin]);
144 }
145
146 return $plugins;
147 }
148
149 if (is_multisite()) {
150 add_filter('site_option_active_sitewide_plugins', 'wpstgExcludeSitePlugins');
151 }
152 }
153
154 if (!function_exists('wpstgDisableTheme')) {
155 /**
156 *
157 * Disables the active theme during WP Staging AJAX requests
158 *
159 *
160 * @param string $dir
161 *
162 * @return string
163 */
164 function wpstgDisableTheme($dir)
165 {
166 $enableTheme = apply_filters('wpstg_optimizer_enable_theme', false);
167
168 if (wpstgIsOptimizerRequest() && $enableTheme === false) {
169 $wpstgRootPro = wpstgGetPluginsDir() . 'wp-staging-pro';
170 $wpstgRoot = wpstgGetPluginsDir() . 'wp-staging';
171
172 $file = DIRECTORY_SEPARATOR . 'Backend' . DIRECTORY_SEPARATOR . 'Optimizer' . DIRECTORY_SEPARATOR . 'blank-theme' . DIRECTORY_SEPARATOR . 'functions.php';
173 $theme = DIRECTORY_SEPARATOR . 'Backend' . DIRECTORY_SEPARATOR . 'Optimizer' . DIRECTORY_SEPARATOR . 'blank-theme';
174
175
176 if (file_exists($wpstgRoot . $file)) {
177 return $wpstgRoot . $theme;
178 } elseif (file_exists($wpstgRootPro . $file)) {
179 return $wpstgRootPro . $theme;
180 } else {
181 return '';
182 }
183 }
184
185 return $dir;
186 }
187
188 add_filter('stylesheet_directory', 'wpstgDisableTheme');
189 add_filter('template_directory', 'wpstgDisableTheme');
190 }
191
192 if (!function_exists('wpstgIsOptimizerRequest')) {
193 /**
194 * Should the current request be processed by optimizer?
195 *
196 * For WP STAGING requests that require other plugins to be active, use raw_wpstg_{actionName}
197 *
198 * @return bool
199 */
200 function wpstgIsOptimizerRequest(): bool
201 {
202 if (!wpstgIsEnabledOptimizer()) {
203 return false;
204 }
205
206 if (
207 defined('DOING_AJAX') &&
208 DOING_AJAX &&
209 isset($_REQUEST['action']) &&
210 strpos(sanitize_text_field($_REQUEST['action']), 'wpstg_send_report') === 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 $remove_function = false;
229
230 // run on wpstg page
231 if (isset($_GET['page']) && $_GET['page'] == 'wpstg_clone') {
232 $remove_function = 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 $remove_function = true;
238 }
239
240 if ($remove_function) {
241 global $wp_filter;
242 $admin_init_functions = $wp_filter['admin_init'];
243 foreach ($admin_init_functions as $priority => $functions) {
244 foreach ($functions as $key => $function) {
245 // searching for function this way as can't rely on the calling class being named TGM_Plugin_Activation
246 if (strpos($key, 'force_activation') !== false) {
247 unset($wp_filter['admin_init'][$priority][$key]);
248
249 return;
250 }
251 }
252 }
253 }
254 }
255
256 add_action('admin_init', 'wpstgTgmpaCompatibility', 1);
257 }
258
259 if (!function_exists('wpstgIsStaging')) {
260 /**
261 * @return bool True if it is staging site. False otherwise.
262 */
263 function wpstgIsStaging(): bool
264 {
265 if (defined('WPSTAGING_DEV_SITE') && WPSTAGING_DEV_SITE === true) {
266 return true;
267 }
268
269 if (get_option("wpstg_is_staging_site") === "true") {
270 return true;
271 }
272
273 if (file_exists(ABSPATH . '.wp-staging')) {
274 return true;
275 }
276
277 return false;
278 }
279 }
280
281 if (!function_exists('wpstgGetCloneSettings')) {
282 /**
283 * Get the value of the given option in clone settings,
284 * If no option given return all clone settings
285 *
286 * @param string|null $option
287 * @return mixed
288 */
289 function wpstgGetCloneSettings(string $option = null)
290 {
291 $settings = get_option('wpstg_clone_settings', null);
292
293 // Return settings if no options given
294 if ($option === null) {
295 return $settings;
296 }
297
298 // Early Bail: if settings is null or if settings isn't object
299 if ($settings === null || !is_object($settings)) {
300 return null;
301 }
302
303 // Early bail if given option not exists
304 if (!property_exists($settings, $option)) {
305 return null;
306 }
307
308 return $settings->{$option};
309 }
310 }
311
312 /**
313 * Disable all outgoing e-mails on Staging site
314 * Will check against both the old and new logic of storing emails disabled option
315 */
316 if (wpstgIsStaging() && (((bool)get_option("wpstg_emails_disabled") === true) || (wpstgGetCloneSettings('wpstg_emails_disabled')))) {
317 if (!function_exists('wp_mail')) {
318 /**
319 * @param array|string $to
320 * @param string $subject
321 * @param string $message
322 * @param array|string $headers
323 * @param array|string $attachments
324 *
325 * @return bool
326 */
327 function wp_mail($to, $subject, $message, $headers = '', $attachments = [])
328 {
329 if (defined('WPSTG_DEBUG') && WPSTG_DEBUG) {
330 // Safely cast everything to string
331 $to = is_string($to) ? $to : wp_json_encode($to);
332 $subject = is_string($subject) ? $subject : wp_json_encode($subject);
333 $message = is_string($message) ? $message : wp_json_encode($message);
334 $headers = is_string($headers) ? $headers : wp_json_encode($headers);
335 $attachments = is_string($attachments) ? $attachments : wp_json_encode($attachments);
336
337 $log_entry = <<<LOG_ENTRY
338 /***
339 * WPSTAGING - Mails are disabled for this Staging site. This e-mail was going to be sent, but was prevented:
340 ***
341 * To: $to
342 ***
343 * Subject: $subject
344 ***
345 * Message: $message
346 ***
347 * Headers: $headers
348 ***
349 * Attachments: $attachments
350 ***/
351 LOG_ENTRY;
352
353 error_log($log_entry);
354 }
355
356 return false;
357 }
358 } elseif (defined('WPSTG_DEBUG') && WPSTG_DEBUG) {
359 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.");
360 }
361 }
362