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