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