oont-contents/plugins/wp-staging/runtimeRequirements.php
2025-02-10 13:57:45 +01:00

404 lines
13 KiB
PHP

<?php
/**
* @var string $pluginFilePath The absolute path to the main file of this plugin.
*/
// TODO: refactor this and implement our own methods to get rid of hard loading wp core functions which is not recommended by WP.
require_once(trailingslashit(ABSPATH) . 'wp-admin/includes/plugin.php');
if (!defined('WPSTGPRO_MINIMUM_FREE_VERSION')) {
/** Expected version number of the free plugin in order to activate it at the same time with pro */
define('WPSTGPRO_MINIMUM_FREE_VERSION', '3.8.0');
}
if (!defined('WPSTG_FREE_VERSION_PLUGIN_FILE')) {
define('WPSTG_FREE_VERSION_PLUGIN_FILE', 'wp-staging.php');
}
if (!defined('WPSTG_PRO_VERSION_PLUGIN_FILE')) {
define('WPSTG_PRO_VERSION_PLUGIN_FILE', 'wp-staging-pro.php');
}
if (!function_exists('wpstgIsProPluginActive')) {
/**
* @return bool
*/
function wpstgIsProPluginActive(): bool
{
return wpstgIsPluginActivated(WPSTG_PRO_VERSION_PLUGIN_FILE);
}
}
if (!function_exists('wpstgIsProPluginActiveInNetwork')) {
/**
* @return bool
*/
function wpstgIsProPluginActiveInNetwork(): bool
{
return wpstgIsPluginActiveInNetwork(WPSTG_PRO_VERSION_PLUGIN_FILE);
}
}
if (!function_exists('wpstgIsFreeVersionRequiredForPro')) {
/**
* @return bool
*/
function wpstgIsFreeVersionRequiredForPro(): bool
{
return apply_filters('wpstg.free_required_by_pro', true);
}
}
if (!function_exists('wpstgIsProActiveInNetworkOrInCurrentSite')) {
/**
* @return bool
*/
function wpstgIsProActiveInNetworkOrInCurrentSite(): bool
{
return wpstgIsProPluginActiveInNetwork() || wpstgIsProPluginActive();
}
}
if (!function_exists('wpstgIsFreeVersionActive')) {
/**
* @return bool
*/
function wpstgIsFreeVersionActive(): bool
{
return wpstgIsPluginActivated(WPSTG_FREE_VERSION_PLUGIN_FILE);
}
}
if (!function_exists('wpstgIsFreeVersionActiveInNetwork')) {
/**
* @return bool
*/
function wpstgIsFreeVersionActiveInNetwork(): bool
{
return wpstgIsPluginActiveInNetwork(WPSTG_FREE_VERSION_PLUGIN_FILE);
}
}
if (!function_exists('wpstgIsFreeActiveInNetworkOrCurrentSite')) {
/**
* @return bool
*/
function wpstgIsFreeActiveInNetworkOrCurrentSite(): bool
{
return wpstgIsFreeVersionActiveInNetwork() || wpstgIsFreeVersionActive();
}
}
if (!function_exists('wpstgGetPluginSlug')) {
/**
* @param string $pluginFileName
*
* @return bool|string false if plugin is not installed otherwise return the plugin slug/basename.
*/
function wpstgGetPluginSlug(string $pluginFileName)
{
$allPlugins = get_plugins();
foreach ($allPlugins as $key => $value) {
if (strpos($key, $pluginFileName) !== false) {
return $key;
}
}
return false;
}
}
if (!function_exists('wpstgGetPluginData')) {
/**
* @param string $pluginFileName
*
* @return array
*/
function wpstgGetPluginData(string $pluginFileName): array
{
$allPlugins = get_plugins();
foreach ($allPlugins as $key => $value) {
if (strpos($key, $pluginFileName) !== false) {
return $value;
}
}
return [];
}
}
if (!function_exists('wpstgGetFreeVersionNumberIfInstalled')) {
/**
* @return string returns empty string if free is not installed.
*/
function wpstgGetFreeVersionNumberIfInstalled(): string
{
$freeData = wpstgGetPluginData(WPSTG_FREE_VERSION_PLUGIN_FILE);
$installedFreeVersionNumber = isset($freeData['Version']) ? $freeData['Version'] : '';
return $installedFreeVersionNumber;
}
}
if (!function_exists('wpstgGetProVersionNumberIfInstalled')) {
/**
* @return string returns empty string if pro is not installed.
*/
function wpstgGetProVersionNumberIfInstalled(): string
{
$freeData = wpstgGetPluginData(WPSTG_PRO_VERSION_PLUGIN_FILE);
$installedFreeVersionNumber = isset($freeData['Version']) ? $freeData['Version'] : '';
return $installedFreeVersionNumber;
}
}
if (!function_exists('wpstgIsFreeVersionCompatible')) {
/**
* @return bool
*/
function wpstgIsFreeVersionCompatible(): bool
{
return defined('WPSTGPRO_MINIMUM_FREE_VERSION') && version_compare(wpstgGetFreeVersionNumberIfInstalled(), WPSTGPRO_MINIMUM_FREE_VERSION, '>=');
}
}
if (!function_exists('wpstgIsFreeActiveButOutdated')) {
/**
* @return bool
*/
function wpstgIsFreeActiveButOutdated(): bool
{
if (wpstgIsFreeActiveInNetworkOrCurrentSite() && !wpstgIsFreeVersionCompatible()) {
return true;
}
return false;
}
}
if (!function_exists('wpstgDeactivatePlugin')) {
/**
* @param mixed $pluginFilePath
* @return void
*/
function wpstgDeactivatePlugin($pluginFilePath)
{
if (is_network_admin()) {
deactivate_plugins($pluginFilePath, false, true);
} else {
deactivate_plugins($pluginFilePath);
}
}
}
if (!function_exists('wpstgCanShowAnotherInstanceRunningNotice')) {
/**
* @param string $pluginFilePath
* @return bool
*/
function wpstgCanShowAnotherInstanceRunningNotice(string $pluginFilePath): bool
{
if (!current_user_can('activate_plugins')) {
return false;
}
if (strpos($pluginFilePath, 'wp-staging-pro.php') !== false && wpstgIsProActiveInNetworkOrInCurrentSite() && !wpstgIsFreeActiveInNetworkOrCurrentSite()) {
return true;
}
if (strpos($pluginFilePath, 'wp-staging.php') !== false && !wpstgIsProActiveInNetworkOrInCurrentSite() && wpstgIsFreeActiveInNetworkOrCurrentSite()) {
return true;
}
return false;
}
}
if (!function_exists('wpstgCanThrowAnotherInstanceLoadedException')) {
/**
* @param string $pluginFilePath
* @return bool
*/
function wpstgCanThrowAnotherInstanceLoadedException(string $pluginFilePath = ''): bool
{
if (defined('WPSTG_VERSION') && version_compare(WPSTG_VERSION, WPSTGPRO_MINIMUM_FREE_VERSION, '<')) {
return true;
}
if (defined('WPSTGPRO_VERSION') && version_compare(WPSTGPRO_VERSION, '5.1.0', '<')) {
return true;
}
if (!wpstgIsProActiveInNetworkOrInCurrentSite() && strpos($pluginFilePath, 'wp-staging-pro.php') === false) {
return true;
}
return false;
}
}
if (!function_exists('wpstgIsPluginActivated')) {
/**
* This function checks if a plugin is activated on single site.
*
* @param string $pluginFileName
*
* @return bool
*/
function wpstgIsPluginActivated(string $pluginFileName): bool
{
$activePlugins = wp_get_active_and_valid_plugins();
foreach ($activePlugins as $sitewidePlugin) {
if (strpos($sitewidePlugin, $pluginFileName) !== false) {
return true;
}
}
return false;
}
}
if (!function_exists('wpstgIsPluginActiveInNetwork')) {
/**
* @param string $pluginFileName
*
* @return bool
*/
function wpstgIsPluginActiveInNetwork(string $pluginFileName): bool
{
if (!is_multisite()) {
return false;
}
$activePlugins = wp_get_active_network_plugins();
foreach ($activePlugins as $sitewidePlugin) {
if (strpos($sitewidePlugin, $pluginFileName) !== false) {
return true;
}
}
return false;
}
}
if (!function_exists('wpstgDoLoadPluginAutoLoad')) {
/**
* @param string $pluginFilePath
* @return void
*/
function wpstgDoLoadPluginAutoLoad(string $pluginFilePath): bool
{
if (class_exists('\WPStaging\Core\WPStaging')) {
return false;
}
if (strpos($pluginFilePath, 'wp-staging.php') === false) {
return true;
}
if (strpos($pluginFilePath, 'wp-staging.php') !== false && (!is_network_admin() && !wpstgIsProPluginActive())) {
return true;
}
if (strpos($pluginFilePath, 'wp-staging.php') !== false && (is_network_admin() && !wpstgIsProPluginActiveInNetwork())) {
return true;
}
return false;
}
}
/**
* Early bail: Deactivate outdated free version.
*/
if (strpos($pluginFilePath, 'wp-staging-pro.php') !== false && wpstgIsFreeActiveButOutdated()) {
// Deactivate free plugin.
$pluginSlug = wpstgGetPluginSlug(WPSTG_FREE_VERSION_PLUGIN_FILE);
wpstgDeactivatePlugin($pluginSlug);
}
/**
* Early bail: Activating another WPSTAGING Plugin.
* This is the only scenario where the plugin would be included after "plugins_loaded",
* therefore we need to detect earlier, from the context of the request, whether this is going to happen,
* to disable this plugin early and bail the bootstrap process to not conflict with the one being activated.
*
* Covers both clicking on the "Activate" button and selecting the "Activate" bulk-action.
*/
if (isset($_REQUEST['action'])) {
switch ($_REQUEST['action']) :
case 'activate':
case 'error_scrape':
if (isset($_REQUEST['plugin'])) {
$plugin = (string)wp_unslash(sanitize_text_field($_REQUEST['plugin']));
$isActivatingWpStaging = strpos($plugin, 'wp-staging.php') || strpos($plugin, 'wp-staging-pro.php');
$isActivatingAnotherWpStaging = plugin_basename($plugin) !== plugin_basename($pluginFilePath);
if ($isActivatingWpStaging && $isActivatingAnotherWpStaging && wpstgCanThrowAnotherInstanceLoadedException($plugin) && current_user_can('deactivate_plugin', plugin_basename($pluginFilePath))) {
throw new Exception("Activating another WPSTAGING Plugin. Plugin that bailed bootstrapping: $pluginFilePath");
}
}
break;
case 'activate-selected':
case 'activate-multi':
if (isset($_REQUEST['checked'])) {
$plugins = array_map('sanitize_text_field', (array)wp_unslash($_REQUEST['checked']));
foreach ($plugins as $i => $plugin) {
$isActivatingWpStaging = strpos($plugin, 'wp-staging.php') || strpos($plugin, 'wp-staging-pro.php');
$isActivatingAnotherWpStaging = plugin_basename($plugin) !== plugin_basename($pluginFilePath);
if ($isActivatingWpStaging && $isActivatingAnotherWpStaging && wpstgCanThrowAnotherInstanceLoadedException($plugin) && current_user_can('deactivate_plugin', plugin_basename($pluginFilePath))) {
throw new Exception("Activating another WPSTAGING Plugin. Plugin that bailed bootstrapping: $pluginFilePath");
}
}
}
break;
endswitch;
}
/**
* Early bail: Another instance of WPSTAGING active.
*/
if (
// WPSTAGING <= 2.7.5
class_exists('\WPStaging\WPStaging') ||
// WPSTAGING >= 2.7.6
class_exists('\WPStaging\Core\WPStaging')
) {
if (wpstgCanShowAnotherInstanceRunningNotice($pluginFilePath)) {
add_action(is_network_admin() ? 'network_admin_notices' : 'admin_notices', function () { // phpcs:ignore WPStaging.Security.FirstArgNotAString, WPStaging.Security.AuthorizationChecked
echo '<div class="notice-warning notice is-dismissible another-wpstaging-active">';
echo '<p style="font-weight: bold;">' . esc_html__('WP STAGING Already Active', 'wp-staging') . '</p>';
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>';
echo '</div>';
});
}
if (!wpstgCanThrowAnotherInstanceLoadedException($pluginFilePath)) {
return;
}
throw new Exception("Another instance of WPSTAGING active. Plugin that bailed bootstrapping: $pluginFilePath");
}
/**
* Early bail: Unsupported WordPress version.
* We check on runtime instead of activation so we can display the notice.
*/
if (!version_compare($currentWordPressVersion = (string)get_bloginfo('version'), $minimumWordPressVersion = '4.4', '>=')) {
if (current_user_can('activate_plugins')) {
add_action(is_network_admin() ? 'network_admin_notices' : 'admin_notices', function () use ($currentWordPressVersion, $minimumWordPressVersion) { // phpcs:ignore WPStaging.Security.FirstArgNotAString, WPStaging.Security.AuthorizationChecked
echo '<div class="notice-warning notice is-dismissible">';
echo '<p style="font-weight: bold;">' . esc_html__('WP STAGING', 'wp-staging') . '</p>';
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>';
echo '</div>';
});
}
throw new Exception("Unsupported WordPress version. Plugin that bailed bootstrapping: $pluginFilePath");
}