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