PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backup, Restore, Migration & Clone / 4.0.0
WP STAGING – WordPress Backup, Restore, Migration & Clone v4.0.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 / runtimeRequirements.php
wp-staging Last commit date
Backend 1 year ago Backup 1 year ago Basic 1 year ago Core 1 year ago Framework 1 year ago Frontend 1 year ago Notifications 1 year ago Staging 1 year ago assets 1 year ago languages 1 year ago resources 1 year ago vendor_wpstg 1 year ago views 1 year ago CONTRIBUTING.md 1 year ago Deactivate.php 2 years ago README.md 1 year ago SECURITY.md 2 years ago autoloader.php 3 years ago bootstrap.php 1 year ago constantsFree.php 1 year ago freeBootstrap.php 2 years ago install.php 1 year ago opcacheBootstrap.php 1 year ago readme.txt 1 year ago runtimeRequirements.php 1 year ago uninstall.php 1 year ago wp-staging-error-handler.php 1 year ago wp-staging.php 1 year ago
runtimeRequirements.php
405 lines
1 <?php
2
3 /**
4 * @var string $pluginFilePath The absolute path to the main file of this plugin.
5 */
6 // TODO: refactor this and implement our own methods to get rid of hard loading wp core functions which is not recommended by WP.
7 require_once(trailingslashit(ABSPATH) . 'wp-admin/includes/plugin.php');
8
9 if (!defined('WPSTGPRO_MINIMUM_FREE_VERSION')) {
10 /** Expected version number of the free plugin in order to activate it at the same time with pro */
11 define('WPSTGPRO_MINIMUM_FREE_VERSION', '3.8.0');
12 }
13
14 if (!defined('WPSTG_FREE_VERSION_PLUGIN_FILE')) {
15 define('WPSTG_FREE_VERSION_PLUGIN_FILE', 'wp-staging.php');
16 }
17
18 if (!defined('WPSTG_PRO_VERSION_PLUGIN_FILE')) {
19 define('WPSTG_PRO_VERSION_PLUGIN_FILE', 'wp-staging-pro.php');
20 }
21
22 if (!function_exists('wpstgIsProPluginActive')) {
23 /**
24 * @return bool
25 */
26 function wpstgIsProPluginActive(): bool
27 {
28 return wpstgIsPluginActivated(WPSTG_PRO_VERSION_PLUGIN_FILE);
29 }
30 }
31
32 if (!function_exists('wpstgIsProPluginActiveInNetwork')) {
33 /**
34 * @return bool
35 */
36 function wpstgIsProPluginActiveInNetwork(): bool
37 {
38 return wpstgIsPluginActiveInNetwork(WPSTG_PRO_VERSION_PLUGIN_FILE);
39 }
40 }
41
42 if (!function_exists('wpstgIsFreeVersionRequiredForPro')) {
43 /**
44 * @return bool
45 */
46 function wpstgIsFreeVersionRequiredForPro(): bool
47 {
48 return apply_filters('wpstg.free_required_by_pro', true);
49 }
50 }
51
52 if (!function_exists('wpstgIsProActiveInNetworkOrInCurrentSite')) {
53 /**
54 * @return bool
55 */
56 function wpstgIsProActiveInNetworkOrInCurrentSite(): bool
57 {
58 return wpstgIsProPluginActiveInNetwork() || wpstgIsProPluginActive();
59 }
60 }
61
62 if (!function_exists('wpstgIsFreeVersionActive')) {
63 /**
64 * @return bool
65 */
66 function wpstgIsFreeVersionActive(): bool
67 {
68 return wpstgIsPluginActivated(WPSTG_FREE_VERSION_PLUGIN_FILE);
69 }
70 }
71
72 if (!function_exists('wpstgIsFreeVersionActiveInNetwork')) {
73 /**
74 * @return bool
75 */
76 function wpstgIsFreeVersionActiveInNetwork(): bool
77 {
78 return wpstgIsPluginActiveInNetwork(WPSTG_FREE_VERSION_PLUGIN_FILE);
79 }
80 }
81
82 if (!function_exists('wpstgIsFreeActiveInNetworkOrCurrentSite')) {
83 /**
84 * @return bool
85 */
86 function wpstgIsFreeActiveInNetworkOrCurrentSite(): bool
87 {
88 return wpstgIsFreeVersionActiveInNetwork() || wpstgIsFreeVersionActive();
89 }
90 }
91
92 if (!function_exists('wpstgGetPluginSlug')) {
93 /**
94 * @param string $pluginFileName
95 *
96 * @return bool|string false if plugin is not installed otherwise return the plugin slug/basename.
97 */
98 function wpstgGetPluginSlug(string $pluginFileName)
99 {
100 $allPlugins = get_plugins();
101 foreach ($allPlugins as $key => $value) {
102 if (strpos($key, $pluginFileName) !== false) {
103 return $key;
104 }
105 }
106
107 return false;
108 }
109 }
110
111 if (!function_exists('wpstgGetPluginData')) {
112 /**
113 * @param string $pluginFileName
114 *
115 * @return array
116 */
117 function wpstgGetPluginData(string $pluginFileName): array
118 {
119 $allPlugins = get_plugins();
120 foreach ($allPlugins as $key => $value) {
121 if (strpos($key, $pluginFileName) !== false) {
122 return $value;
123 }
124 }
125
126 return [];
127 }
128 }
129
130 if (!function_exists('wpstgGetFreeVersionNumberIfInstalled')) {
131 /**
132 * @return string returns empty string if free is not installed.
133 */
134 function wpstgGetFreeVersionNumberIfInstalled(): string
135 {
136 $freeData = wpstgGetPluginData(WPSTG_FREE_VERSION_PLUGIN_FILE);
137 $installedFreeVersionNumber = isset($freeData['Version']) ? $freeData['Version'] : '';
138
139 return $installedFreeVersionNumber;
140 }
141 }
142
143 if (!function_exists('wpstgGetProVersionNumberIfInstalled')) {
144 /**
145 * @return string returns empty string if pro is not installed.
146 */
147 function wpstgGetProVersionNumberIfInstalled(): string
148 {
149 $freeData = wpstgGetPluginData(WPSTG_PRO_VERSION_PLUGIN_FILE);
150 $installedFreeVersionNumber = isset($freeData['Version']) ? $freeData['Version'] : '';
151
152 return $installedFreeVersionNumber;
153 }
154 }
155
156 if (!function_exists('wpstgIsFreeVersionCompatible')) {
157 /**
158 * @return bool
159 */
160 function wpstgIsFreeVersionCompatible(): bool
161 {
162 return defined('WPSTGPRO_MINIMUM_FREE_VERSION') && version_compare(wpstgGetFreeVersionNumberIfInstalled(), WPSTGPRO_MINIMUM_FREE_VERSION, '>=');
163 }
164 }
165
166 if (!function_exists('wpstgIsFreeActiveButOutdated')) {
167 /**
168 * @return bool
169 */
170 function wpstgIsFreeActiveButOutdated(): bool
171 {
172 if (wpstgIsFreeActiveInNetworkOrCurrentSite() && !wpstgIsFreeVersionCompatible()) {
173 return true;
174 }
175
176 return false;
177 }
178 }
179
180 if (!function_exists('wpstgDeactivatePlugin')) {
181 /**
182 * @param mixed $pluginFilePath
183 * @return void
184 */
185 function wpstgDeactivatePlugin($pluginFilePath)
186 {
187 if (is_network_admin()) {
188 deactivate_plugins($pluginFilePath, false, true);
189 } else {
190 deactivate_plugins($pluginFilePath);
191 }
192 }
193 }
194
195 if (!function_exists('wpstgCanShowAnotherInstanceRunningNotice')) {
196 /**
197 * @param string $pluginFilePath
198 * @return bool
199 */
200 function wpstgCanShowAnotherInstanceRunningNotice(string $pluginFilePath): bool
201 {
202 if (!current_user_can('activate_plugins')) {
203 return false;
204 }
205
206 if (strpos($pluginFilePath, 'wp-staging-pro.php') !== false && wpstgIsProActiveInNetworkOrInCurrentSite() && !wpstgIsFreeActiveInNetworkOrCurrentSite()) {
207 return true;
208 }
209
210 if (strpos($pluginFilePath, 'wp-staging.php') !== false && !wpstgIsProActiveInNetworkOrInCurrentSite() && wpstgIsFreeActiveInNetworkOrCurrentSite()) {
211 return true;
212 }
213
214 return false;
215 }
216 }
217
218 if (!function_exists('wpstgCanThrowAnotherInstanceLoadedException')) {
219 /**
220 * @param string $pluginFilePath
221 * @return bool
222 */
223 function wpstgCanThrowAnotherInstanceLoadedException(string $pluginFilePath = ''): bool
224 {
225 if (defined('WPSTG_VERSION') && version_compare(WPSTG_VERSION, WPSTGPRO_MINIMUM_FREE_VERSION, '<')) {
226 return true;
227 }
228
229 if (defined('WPSTGPRO_VERSION') && version_compare(WPSTGPRO_VERSION, '5.1.0', '<')) {
230 return true;
231 }
232
233 if (!wpstgIsProActiveInNetworkOrInCurrentSite() && strpos($pluginFilePath, 'wp-staging-pro.php') === false) {
234 return true;
235 }
236
237 return false;
238 }
239 }
240
241 if (!function_exists('wpstgIsPluginActivated')) {
242 /**
243 * This function checks if a plugin is activated on single site.
244 *
245 * @param string $pluginFileName
246 *
247 * @return bool
248 */
249 function wpstgIsPluginActivated(string $pluginFileName): bool
250 {
251 $activePlugins = wp_get_active_and_valid_plugins();
252 foreach ($activePlugins as $sitewidePlugin) {
253 if (strpos($sitewidePlugin, $pluginFileName) !== false) {
254 return true;
255 }
256 }
257
258 return false;
259 }
260 }
261
262 if (!function_exists('wpstgIsPluginActiveInNetwork')) {
263 /**
264 * @param string $pluginFileName
265 *
266 * @return bool
267 */
268 function wpstgIsPluginActiveInNetwork(string $pluginFileName): bool
269 {
270 if (!is_multisite()) {
271 return false;
272 }
273
274 $activePlugins = wp_get_active_network_plugins();
275 foreach ($activePlugins as $sitewidePlugin) {
276 if (strpos($sitewidePlugin, $pluginFileName) !== false) {
277 return true;
278 }
279 }
280
281 return false;
282 }
283 }
284
285 if (!function_exists('wpstgDoLoadPluginAutoLoad')) {
286 /**
287 * @param string $pluginFilePath
288 * @return void
289 */
290 function wpstgDoLoadPluginAutoLoad(string $pluginFilePath): bool
291 {
292 if (class_exists('\WPStaging\Core\WPStaging')) {
293 return false;
294 }
295
296 if (strpos($pluginFilePath, 'wp-staging.php') === false) {
297 return true;
298 }
299
300 if (strpos($pluginFilePath, 'wp-staging.php') !== false && (!is_network_admin() && !wpstgIsProPluginActive())) {
301 return true;
302 }
303
304 if (strpos($pluginFilePath, 'wp-staging.php') !== false && (is_network_admin() && !wpstgIsProPluginActiveInNetwork())) {
305 return true;
306 }
307
308 return false;
309 }
310 }
311
312 /**
313 * Early bail: Deactivate outdated free version.
314 */
315 if (strpos($pluginFilePath, 'wp-staging-pro.php') !== false && wpstgIsFreeActiveButOutdated()) {
316 // Deactivate free plugin.
317 $pluginSlug = wpstgGetPluginSlug(WPSTG_FREE_VERSION_PLUGIN_FILE);
318 wpstgDeactivatePlugin($pluginSlug);
319 }
320
321 /**
322 * Early bail: Activating another WPSTAGING Plugin.
323 * This is the only scenario where the plugin would be included after "plugins_loaded",
324 * therefore we need to detect earlier, from the context of the request, whether this is going to happen,
325 * to disable this plugin early and bail the bootstrap process to not conflict with the one being activated.
326 *
327 * Covers both clicking on the "Activate" button and selecting the "Activate" bulk-action.
328 */
329 if (isset($_REQUEST['action'])) {
330 switch ($_REQUEST['action']) :
331 case 'activate':
332 case 'error_scrape':
333 if (isset($_REQUEST['plugin'])) {
334 $plugin = (string)wp_unslash(sanitize_text_field($_REQUEST['plugin']));
335
336 $isActivatingWpStaging = strpos($plugin, 'wp-staging.php') || strpos($plugin, 'wp-staging-pro.php');
337 $isActivatingAnotherWpStaging = plugin_basename($plugin) !== plugin_basename($pluginFilePath);
338
339 if ($isActivatingWpStaging && $isActivatingAnotherWpStaging && wpstgCanThrowAnotherInstanceLoadedException($plugin) && current_user_can('deactivate_plugin', plugin_basename($pluginFilePath))) {
340 throw new Exception("Activating another WPSTAGING Plugin. Plugin that bailed bootstrapping: $pluginFilePath");
341 }
342 }
343
344 break;
345 case 'activate-selected':
346 case 'activate-multi':
347 if (isset($_REQUEST['checked'])) {
348 $plugins = array_map('sanitize_text_field', (array)wp_unslash($_REQUEST['checked']));
349
350 foreach ($plugins as $i => $plugin) {
351 $isActivatingWpStaging = strpos($plugin, 'wp-staging.php') || strpos($plugin, 'wp-staging-pro.php');
352 $isActivatingAnotherWpStaging = plugin_basename($plugin) !== plugin_basename($pluginFilePath);
353
354 if ($isActivatingWpStaging && $isActivatingAnotherWpStaging && wpstgCanThrowAnotherInstanceLoadedException($plugin) && current_user_can('deactivate_plugin', plugin_basename($pluginFilePath))) {
355 throw new Exception("Activating another WPSTAGING Plugin. Plugin that bailed bootstrapping: $pluginFilePath");
356 }
357 }
358 }
359
360 break;
361 endswitch;
362 }
363
364 /**
365 * Early bail: Another instance of WPSTAGING active.
366 */
367 if (
368 // WPSTAGING <= 2.7.5
369 class_exists('\WPStaging\WPStaging') ||
370 // WPSTAGING >= 2.7.6
371 class_exists('\WPStaging\Core\WPStaging')
372 ) {
373 if (wpstgCanShowAnotherInstanceRunningNotice($pluginFilePath)) {
374 add_action(is_network_admin() ? 'network_admin_notices' : 'admin_notices', function () { // phpcs:ignore WPStaging.Security.FirstArgNotAString, WPStaging.Security.AuthorizationChecked
375 echo '<div class="notice-warning notice is-dismissible another-wpstaging-active">';
376 echo '<p style="font-weight: bold;">' . esc_html__('WP STAGING Already Active', 'wp-staging') . '</p>';
377 echo '<p>' . esc_html__('Another WP STAGING is already activated, please leave only one instance of the WP STAGING plugin active at the same time.', 'wp-staging') . '</p>';
378 echo '</div>';
379 });
380 }
381
382 if (!wpstgCanThrowAnotherInstanceLoadedException($pluginFilePath)) {
383 return;
384 }
385
386 throw new Exception("Another instance of WPSTAGING active. Plugin that bailed bootstrapping: $pluginFilePath");
387 }
388
389 /**
390 * Early bail: Unsupported WordPress version.
391 * We check on runtime instead of activation so we can display the notice.
392 */
393 if (!version_compare($currentWordPressVersion = (string)get_bloginfo('version'), $minimumWordPressVersion = '4.4', '>=')) {
394 if (current_user_can('activate_plugins')) {
395 add_action(is_network_admin() ? 'network_admin_notices' : 'admin_notices', function () use ($currentWordPressVersion, $minimumWordPressVersion) { // phpcs:ignore WPStaging.Security.FirstArgNotAString, WPStaging.Security.AuthorizationChecked
396 echo '<div class="notice-warning notice is-dismissible">';
397 echo '<p style="font-weight: bold;">' . esc_html__('WP STAGING', 'wp-staging') . '</p>';
398 echo '<p>' . sprintf(esc_html__('WP STAGING requires at least WordPress %s to run. You have WordPress %s.', 'wp-staging'), esc_html($minimumWordPressVersion), esc_html($currentWordPressVersion)) . '</p>';
399 echo '</div>';
400 });
401 }
402
403 throw new Exception("Unsupported WordPress version. Plugin that bailed bootstrapping: $pluginFilePath");
404 }
405