| Current File : /home/digitaw/www/wp-content/plugins/astra-sites/inc/lib/ai-builder/inc/traits/helper.php |
<?php
/**
* Trait.
*
* @package {{package}}
* @since 0.0.1
*/
namespace AiBuilder\Inc\Traits;
use AiBuilder\Inc\Classes\Ai_Builder_Importer_Log;
use AiBuilder\Inc\Classes\Importer\Ai_Builder_Error_Handler;
use STImporter\Importer\ST_Importer;
use STImporter\Importer\ST_Importer_File_System;
use STImporter\Resetter\ST_Resetter;
/**
* Trait Instance.
*/
class Helper {
use Instance;
/**
* Get an option from the database.
*
* @param string $key The option key.
* @param mixed $default The option default value if option is not available.
* @param bool $network_override Whether to allow the network admin setting to be overridden on subsites.
* @since 1.0.0
* @return mixed The option value.
*/
public static function get_admin_settings_option( $key, $default = false, $network_override = false ) {
// Get the site-wide option if we're in the network admin.
return $network_override && is_multisite() ? get_site_option( $key, $default ) : get_option( $key, $default );
}
/**
* Delete an option from the database for.
*
* @param string $key The option key.
* @param bool $network_override Whether to allow the network admin setting to be overridden on subsites.
* @since 1.0.0
* @return void
*/
public static function delete_admin_settings_option( $key, $network_override = false ) {
// Delete the site-wide option if we're in the network admin.
if ( $network_override && is_multisite() ) {
delete_site_option( $key );
} else {
delete_option( $key );
}
}
/**
* Get image placeholder array.
*
* @since 4.0.9
* @return array<int, array<string, string>>
*/
public static function get_image_placeholders() {
return array(
array(
'auther_name' => 'Placeholder',
'auther_url' => '#',
'id' => 'placeholder-landscape',
'orientation' => 'landscape',
'optimized_url' => 'https://websitedemos.net/wp-content/uploads/2024/02/placeholder-landscape.png',
'url' => 'https://websitedemos.net/wp-content/uploads/2024/02/placeholder-landscape.png',
'engine' => 'placeholder',
'engine_url' => '#',
),
array(
'auther_name' => 'Placeholder',
'auther_url' => '#',
'id' => 'placeholder-portrait',
'orientation' => 'portrait',
'optimized_url' => 'https://websitedemos.net/wp-content/uploads/2024/02/placeholder-portrait.png',
'url' => 'https://websitedemos.net/wp-content/uploads/2024/02/placeholder-portrait.png',
'engine' => 'placeholder',
'engine_url' => '#',
),
);
}
/**
* Get Saved Token.
*
* @since 4.0.0
* @return string
*/
public static function get_token() {
$token_details = get_option(
'zip_ai_settings',
array(
'auth_token' => '',
'zip_token' => '',
'email' => '',
)
);
return is_array( $token_details ) && isset( $token_details['zip_token'] ) ? self::decrypt( $token_details['zip_token'] ) : '';
}
/**
* Decrypt data using base64.
*
* @param string $input The input string which needs to be decrypted.
* @since 4.0.0
* @return string The decrypted string.
*/
public static function decrypt( $input ) {
// If the input is empty or not a string, then abandon ship.
if ( empty( $input ) || ! is_string( $input ) ) {
return '';
}
// Decrypt the input and return it.
$base_64 = $input . str_repeat( '=', strlen( $input ) % 4 );
return base64_decode( $base_64 ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode
}
/**
* Get installed PHP version.
*
* @return string PHP version.
* @since 3.0.16
*/
public static function get_php_version() {
if ( defined( 'PHP_MAJOR_VERSION' ) && defined( 'PHP_MINOR_VERSION' ) && defined( 'PHP_RELEASE_VERSION' ) ) { // phpcs:ignore
return PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION . '.' . PHP_RELEASE_VERSION;
}
return phpversion();
}
/**
* Check whether WooCommerce plugin is installed and active.
*
* @since 1.2.43
*
* @return bool True if WooCommerce is active, false otherwise.
*/
public static function is_woocommerce_active() {
return class_exists( 'WooCommerce' ) || is_plugin_active( 'woocommerce/woocommerce.php' );
}
/**
* Determine if a plugin requires WooCommerce to function.
*
* @since 1.2.43
*
* @param string $plugin Plugin slug or init file.
* @return bool True if plugin depends on WooCommerce.
*/
public static function plugin_requires_woocommerce( $plugin ) {
$wc_plugins = array(
'woocommerce-payments',
'woocommerce-payments/woocommerce-payments.php',
'cartflows',
'cartflows/cartflows.php',
'woo-cart-abandonment-recovery',
'woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php',
'modern-cart',
'modern-cart/modern-cart.php',
);
return in_array( $plugin, $wc_plugins, true );
}
/**
* Has Pro Version Support?
* And
* Is Pro Version Installed?
*
* Check Pro plugin version exist of requested plugin lite version.
*
* Eg. If plugin 'BB Lite Version' required to import demo. Then we check the 'BB Agency Version' is exist?
* If yes then we only 'Activate' Agency Version. [We couldn't install agency version.]
* Else we 'Activate' or 'Install' Lite Version.
*
* @since 1.0.1
*
* @param string $lite_version Lite version init file.
* @return mixed Return false if not installed or not supported by us
* else return 'Pro' version details.
*/
public static function pro_plugin_exist( $lite_version = '' ) {
// Lite init => Pro init.
$plugins = apply_filters(
'astra_sites_pro_plugin_exist',
array(
'beaver-builder-lite-version/fl-builder.php' => array(
'slug' => 'bb-plugin',
'init' => 'bb-plugin/fl-builder.php',
'name' => 'Beaver Builder Plugin',
),
'ultimate-addons-for-beaver-builder-lite/bb-ultimate-addon.php' => array(
'slug' => 'bb-ultimate-addon',
'init' => 'bb-ultimate-addon/bb-ultimate-addon.php',
'name' => 'Ultimate Addon for Beaver Builder',
),
'wpforms-lite/wpforms.php' => array(
'slug' => 'wpforms',
'init' => 'wpforms/wpforms.php',
'name' => 'WPForms',
),
),
$lite_version
);
if ( isset( $plugins[ $lite_version ] ) ) {
// Pro plugin directory exist?
if ( file_exists( WP_PLUGIN_DIR . '/' . $plugins[ $lite_version ]['init'] ) ) {
return $plugins[ $lite_version ];
}
}
return false;
}
/**
* Get the status of file system permission of "/wp-content/uploads" directory.
*
* @return void
*/
public static function filesystem_permission() {
if ( ! defined( 'WP_CLI' ) && wp_doing_ajax() ) {
check_ajax_referer( 'astra-sites', '_ajax_nonce' );
if ( ! current_user_can( 'customize' ) ) {
wp_send_json_error( __( 'You do not have permission to perform this action.', 'astra-sites' ) );
}
}
$wp_upload_path = wp_upload_dir();
$permissions = array(
'is_readable' => false,
'is_writable' => false,
);
foreach ( $permissions as $file_permission => $value ) {
$permissions[ $file_permission ] = $file_permission( $wp_upload_path['basedir'] );
}
$permissions['is_wp_filesystem'] = true;
if ( ! WP_Filesystem() ) {
$permissions['is_wp_filesystem'] = false;
}
if ( defined( 'WP_CLI' ) ) {
if ( ! $permissions['is_readable'] || ! $permissions['is_writable'] || ! $permissions['is_wp_filesystem'] ) {
self::error_response( esc_html__( 'Please contact the hosting service provider to help you update the permissions so that you can successfully import a complete template.', 'astra-sites' ) );
return;
}
}
self::success_response(
array(
'permissions' => $permissions,
'directory' => $wp_upload_path['basedir'],
)
);
}
/**
* Required Plugins
*
* @since 2.0.0
*
* @param array<int, array<string, string>> $required_plugins Required Plugins.
* @param array<string, mixed> $options Site Options.
* @param array<string, mixed> $enabled_extensions Enabled Extensions.
* @return mixed
*/
public static function required_plugins( $required_plugins = array(), $options = array(), $enabled_extensions = array() ) {
// Verify Nonce.
if ( ! defined( 'WP_CLI' ) && wp_doing_ajax() ) {
check_ajax_referer( 'astra-sites', '_ajax_nonce' );
if ( ! current_user_can( 'edit_posts' ) ) {
wp_send_json_error(
array(
'error' => __( 'Permission Denied!', 'astra-sites' ),
)
);
}
}
$response = array(
'active' => array(),
'inactive' => array(),
'notinstalled' => array(),
);
$id = isset( $_POST['id'] ) ? absint( $_POST['id'] ) : '';
$screen = isset( $_POST['screen'] ) ? sanitize_text_field( $_POST['screen'] ) : '';
if ( ! isset( $_POST['ai_plugin_permission'] ) ) {
if ( 'elementor' === $screen ) {
$imported_demo_data = get_option( 'astra_sites_import_elementor_data_' . $id, array() );
if ( isset( $imported_demo_data['type'] ) && 'astra-blocks' === $imported_demo_data['type'] ) { // @phpstan-ignore-line
// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_unserialize
$plugins = unserialize( $imported_demo_data['post-meta']['astra-blocks-required-plugins'] ); // @phpstan-ignore-line
$required_plugins = false !== $plugins ? $plugins : array();
} else {
$required_plugins = isset( $imported_demo_data['site-pages-required-plugins'] ) ? $imported_demo_data['site-pages-required-plugins'] : array(); // @phpstan-ignore-line
}
} else {
$required_plugins = astra_get_site_data( 'required-plugins' );
}
}
if ( ! empty( $_POST['feature_plugins'] ) ) {
$feature_plugins = is_string( $_POST['feature_plugins'] ) ? json_decode( wp_unslash( $_POST['feature_plugins'] ), true ) : array();
$required_plugins = '' === $required_plugins ? [] : $required_plugins;
if ( is_array( $feature_plugins ) && is_array( $required_plugins ) ) {
// Create a set of existing plugin slugs.
$existing_slugs = array_column( $required_plugins, 'slug' );
// Merge only the new feature plugins that aren't already in the required plugins.
foreach ( $feature_plugins as $feature_plugin ) {
if ( isset( $feature_plugin['slug'] ) && ! in_array( $feature_plugin['slug'], $existing_slugs, true ) ) {
$required_plugins[] = $feature_plugin;
$existing_slugs[] = $feature_plugin['slug']; // Keep the slug list updated.
}
}
}
}
$data = self::get_required_plugins_data( $response, $required_plugins ); // @phpstan-ignore-line
self::success_response( $data );
return $data;
}
/**
* Retrieves the required plugins data based on the response and required plugin list.
*
* @param array<string, array<string, mixed>> $response The response containing the plugin data.
* @param array<int, array<string, string>> $required_plugins The list of required plugins.
* @since 3.2.5
* @return array<string, mixed>|null The array of required plugins data or null on error.
*/
public static function get_required_plugins_data( $response, $required_plugins ) {
$learndash_course_grid = 'https://www.learndash.com/add-on/course-grid/';
$learndash_woocommerce = 'https://www.learndash.com/add-on/woocommerce/';
if ( is_plugin_active( 'sfwd-lms/sfwd_lms.php' ) ) {
$learndash_addons_url = admin_url( 'admin.php?page=learndash_lms_addons' );
$learndash_course_grid = $learndash_addons_url;
$learndash_woocommerce = $learndash_addons_url;
}
$third_party_required_plugins = array();
$third_party_plugins = array(
'sfwd-lms' => array(
'init' => 'sfwd-lms/sfwd_lms.php',
'name' => 'LearnDash LMS',
'link' => 'https://www.learndash.com/',
),
'learndash-course-grid' => array(
'init' => 'learndash-course-grid/learndash_course_grid.php',
'name' => 'LearnDash Course Grid',
'link' => $learndash_course_grid,
),
'learndash-woocommerce' => array(
'init' => 'learndash-woocommerce/learndash_woocommerce.php',
'name' => 'LearnDash WooCommerce Integration',
'link' => $learndash_woocommerce,
),
);
$plugin_updates = get_plugin_updates();
$update_avilable_plugins = array();
$incompatible_plugins = array();
if ( ! empty( $required_plugins ) ) {
$php_version = Helper::get_php_version();
foreach ( $required_plugins as $key => $plugin ) {
$plugin = (array) $plugin;
if ( 'woocommerce' === $plugin['slug'] && version_compare( $php_version, '7.0', '<' ) ) {
$plugin['min_php_version'] = '7.0';
$incompatible_plugins[] = $plugin;
}
if ( 'presto-player' === $plugin['slug'] && version_compare( $php_version, '7.3', '<' ) ) {
$plugin['min_php_version'] = '7.3';
$incompatible_plugins[] = $plugin;
}
/**
* Has Pro Version Support?
* And
* Is Pro Version Installed?
*/
$plugin_pro = Helper::pro_plugin_exist( $plugin['init'] );
if ( is_array( $plugin_pro ) ) {
if ( array_key_exists( $plugin_pro['init'], $plugin_updates ) ) {
$update_avilable_plugins[] = $plugin_pro;
}
if ( ! is_array( $response ) ) {
$response = array();
}
// Pro - Active.
if ( is_plugin_active( $plugin_pro['init'] ) ) {
$response['active'][] = $plugin_pro;
self::after_plugin_activate( $plugin['init'], array(), array(), $plugin['slug'], true );
// Pro - Inactive.
} else {
$response['inactive'][] = $plugin_pro;
}
} else {
if ( array_key_exists( $plugin['init'], $plugin_updates ) ) {
$update_avilable_plugins[] = $plugin;
}
// Lite - Installed but Inactive.
if ( file_exists( WP_PLUGIN_DIR . '/' . $plugin['init'] ) && is_plugin_inactive( $plugin['init'] ) ) {
$link = wp_nonce_url(
add_query_arg(
array(
'action' => 'activate',
'plugin' => $plugin['init'],
),
admin_url( 'plugins.php' )
),
'activate-plugin_' . $plugin['init']
);
$link = str_replace( '&', '&', $link );
$plugin['action'] = $link;
$response['inactive'][] = $plugin;
// Lite - Not Installed.
} elseif ( ! file_exists( WP_PLUGIN_DIR . '/' . $plugin['init'] ) ) {
// Added premium plugins which need to install first.
if ( array_key_exists( $plugin['slug'], $third_party_plugins ) ) {
$third_party_required_plugins[] = $third_party_plugins[ $plugin['slug'] ];
} else {
$link = wp_nonce_url(
add_query_arg(
array(
'action' => 'install-plugin',
'plugin' => $plugin['slug'],
),
admin_url( 'update.php' )
),
'install-plugin_' . $plugin['slug']
);
$link = str_replace( '&', '&', $link );
$plugin['action'] = $link;
$response['notinstalled'][] = $plugin;
}
// Lite - Active.
} else {
$response['active'][] = $plugin;
self::after_plugin_activate( $plugin['init'], array(), array(), $plugin['slug'], true );
}
}
}
}
// Checking the `install_plugins` and `activate_plugins` capability for the current user.
// To perform plugin installation process.
$has_notinstalled = ! empty( $response['notinstalled'] );
$has_inactive = ! empty( $response['inactive'] );
$can_install = current_user_can( 'install_plugins' );
$can_activate = current_user_can( 'activate_plugins' );
if ( is_multisite() ) {
/**
* For multisite: Super admins can handle both, subsite admins need activation capability.
* Determine if there is a permission error based on plugin installation/activation needs and user capabilities.
* Scenarios:
* 1. User has no permissions (can't install or activate) and plugins need to be installed or activated.
* 2. User can activate but not install:
* - If plugins need installation -> error.
* - If plugins only need activation -> no error.
* 3. User can install but not activate:
* - If plugins need activation -> error.
* - If plugins only need installation -> no error.
* 4. User has both permissions -> no error.
*/
$is_error = false;
if ( $has_notinstalled && ! $can_install ) {
$is_error = true;
} elseif ( $has_inactive && ! $can_activate ) {
$is_error = true;
}
} else {
// For single site: Check install and activate permissions separately.
$is_error = ( ! $can_install && $has_notinstalled ) || ( ! $can_activate && $has_inactive );
}
if (
( ! defined( 'WP_CLI' ) && wp_doing_ajax() ) && $is_error ) {
$message = __( 'Insufficient Permission. Please contact your Super Admin to allow the install required plugin permissions.', 'astra-sites' );
$required_plugins_list = array_merge( $response['notinstalled'], $response['inactive'] );
// Show only not installed plugins if user can activate plugins.
if ( $can_activate ) {
$required_plugins_list = $response['notinstalled'];
}
$markup = $message;
$markup .= '<ul>';
foreach ( $required_plugins_list as $key => $required_plugin ) {
$markup .= '<li>' . esc_html( $required_plugin['name'] ) . '</li>';
}
$markup .= '</ul>';
$data = array(
'markup' => $markup,
'required_plugins' => $response,
'third_party_required_plugins' => $third_party_required_plugins,
'update_avilable_plugins' => $update_avilable_plugins,
'incompatible_plugins' => $incompatible_plugins,
'error' => $is_error,
);
self::error_response( $data );
return null;
}
return array(
'required_plugins' => $response,
'third_party_required_plugins' => $third_party_required_plugins,
'update_avilable_plugins' => $update_avilable_plugins,
'incompatible_plugins' => $incompatible_plugins,
'error' => $is_error,
);
}
/**
* After Plugin Activate
*
* @since 2.0.0
*
* @param string $plugin_init Plugin Init File.
* @param array<string, mixed> $options Site Options.
* @param array<string, mixed> $enabled_extensions Enabled Extensions.
* @param string $plugin_slug Plugin slug.
* @param bool $was_plugin_active Flag indicating if the plugin was already active.
* @return void
*/
public static function after_plugin_activate( $plugin_init = '', $options = array(), $enabled_extensions = array(), $plugin_slug = '', $was_plugin_active = false ) {
$data = array(
'astra_site_options' => $options,
'enabled_extensions' => $enabled_extensions,
'plugin_slug' => $plugin_slug,
'was_plugin_active' => $was_plugin_active,
);
do_action( 'astra_sites_after_plugin_activation', $plugin_init, $data );
}
/**
* Required Plugin Activate
*
* @since 2.0.0 Added parameters $init, $options & $enabled_extensions to add the WP CLI support.
* @since 1.0.0
* @param string $init Plugin init file.
* @param array<string, mixed> $options Site options.
* @param array<string, mixed> $enabled_extensions Enabled extensions.
* @return void
*/
public static function required_plugin_activate( $init = '', $options = array(), $enabled_extensions = array() ) {
if ( ! defined( 'WP_CLI' ) && wp_doing_ajax() ) {
check_ajax_referer( 'astra-sites', '_ajax_nonce' );
if ( ! current_user_can( 'activate_plugins' ) || ! isset( $_POST['init'] ) || ! sanitize_text_field( $_POST['init'] ) ) {
wp_send_json_error(
array(
'success' => false,
'message' => __( "Error: You don't have the required permissions to activate plugins.", 'astra-sites' ),
)
);
}
}
Ai_Builder_Error_Handler::Instance()->start_error_handler();
$plugin_init = isset( $_POST['init'] ) ? esc_attr( sanitize_text_field( $_POST['init'] ) ) : $init;
$plugin_slug = isset( $_POST['slug'] ) ? esc_attr( sanitize_text_field( $_POST['slug'] ) ) : '';
// Check if plugin requires WooCommerce but WooCommerce is not active.
if ( self::plugin_requires_woocommerce( $plugin_slug ) || self::plugin_requires_woocommerce( $plugin_init ) ) {
if ( ! self::is_woocommerce_active() ) {
$message = __( 'This plugin requires WooCommerce to be installed and activated first.', 'astra-sites' );
if ( defined( 'WP_CLI' ) ) {
self::error_response( $message );
} elseif ( wp_doing_ajax() ) {
// Send deprioritize response instead of error.
self::success_response(
array(
'success' => false,
'status' => 'deprioritize',
'action' => 'defer',
'message' => $message,
'reason' => 'missing_woocommerce',
'dependency' => 'woocommerce',
'plugin_slug' => $plugin_slug,
'plugin_init' => $plugin_init,
'retry_after' => 'woocommerce_activation',
)
);
}
return;
}
}
/**
* Disabled redirection to plugin page after activation.
* Silecing the callback for WP Live Chat plugin.
*/
add_filter( 'wp_redirect', '__return_false' );
$silent = 'wp-live-chat-support/wp-live-chat-support.php' === $plugin_init ? true : false;
$was_plugin_active = is_plugin_active( $plugin_init );
$activate = activate_plugin( $plugin_init, '', false, $silent );
Ai_Builder_Error_Handler::Instance()->stop_error_handler();
if ( is_wp_error( $activate ) ) {
self::error_response(
defined( 'WP_CLI' )
? sprintf(
// translators: 1: Error message.
__( 'Plugin Activation Error: %s', 'astra-sites' ),
$activate->get_error_message()
)
: $activate->get_error_message()
);
return;
}
$options = astra_get_site_data( 'astra-site-options-data' );
$enabled_extensions = astra_get_site_data( 'astra-enabled-extensions' );
$options = is_array( $options ) ? $options : array();
$enabled_extensions = is_array( $enabled_extensions ) ? $enabled_extensions : array();
self::after_plugin_activate( $plugin_init, $options, $enabled_extensions, $plugin_slug, $was_plugin_active );
$success_data = array(
'success' => true,
'status' => 'activated',
'message' => __( 'Plugin Activated', 'astra-sites' ),
);
self::success_response( $success_data );
}
/**
* Backup our existing settings.
*
* @return void
*/
public static function backup_settings() {
if ( ! defined( 'WP_CLI' ) && wp_doing_ajax() ) {
check_ajax_referer( 'astra-sites', '_ajax_nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( __( 'User does not have permission!', 'astra-sites' ) );
}
}
if ( ! class_exists( 'STImporter\Resetter\ST_Resetter' ) ) {
self::error_response( __( 'Required class not found.', 'astra-sites' ) );
return;
}
$log_file_path = ST_Resetter::backup_settings();
// translators: %s: Log file path.
self::success_response( sprintf( __( 'File generated at %s', 'astra-sites' ), $log_file_path ) );
}
/**
* Import Options.
*
* @since 1.0.14
* @since 1.4.0 The `$options_data` was added.
*
* @param array<string, mixed> $options_data Site Options.
* @return void
*/
public static function import_options( $options_data = array() ) {
if ( ! defined( 'WP_CLI' ) && wp_doing_ajax() ) {
// Verify Nonce.
check_ajax_referer( 'astra-sites', '_ajax_nonce' );
if ( ! current_user_can( 'customize' ) ) {
wp_send_json_error( __( 'You are not allowed to perform this action', 'astra-sites' ) );
}
}
if ( empty( $options_data ) ) {
$options_data = astra_get_site_data( 'astra-site-options-data' );
}
if ( ! class_exists( 'STImporter\Importer\ST_Importer' ) || ! class_exists( 'STImporter\Importer\ST_Option_Importer' ) ) {
self::error_response( __( 'Required class not found.', 'astra-sites' ) );
return;
}
$result = ST_Importer::import_options( $options_data );
if ( false === $result['status'] ) {
self::error_response( $result['error'] );
return;
}
self::success_response( __( 'Site options Imported!', 'astra-sites' ) );
}
/**
* Import Widgets.
*
* @since 1.0.14
* @since 1.4.0 The `$widgets_data` was added.
*
* @param string $widgets_data Widgets Data.
* @return void
*/
public static function import_widgets( $widgets_data = '' ) {
if ( ! defined( 'WP_CLI' ) && wp_doing_ajax() ) {
// Verify Nonce.
check_ajax_referer( 'astra-sites', '_ajax_nonce' );
if ( ! current_user_can( 'customize' ) ) {
wp_send_json_error( __( 'You are not allowed to perform this action', 'astra-sites' ) );
}
}
$data = astra_get_site_data( 'astra-site-widgets-data' );
if ( defined( 'WP_CLI' ) ) {
$data = $widgets_data;
}
if ( ! class_exists( 'STImporter\Importer\ST_Importer' ) ) {
self::error_response( __( 'Required class not found.', 'astra-sites' ) );
return;
}
$result = ST_Importer::import_widgets( $widgets_data, $data );
if ( false === $result['status'] ) {
self::error_response( $result['error'] );
return;
}
self::success_response( __( 'Widget Imported!', 'astra-sites' ) );
}
/**
* Import End.
*
* @since 1.0.14
* @return void
*/
public static function import_end() {
if ( ! defined( 'WP_CLI' ) && wp_doing_ajax() ) {
// Verify Nonce.
check_ajax_referer( 'astra-sites', '_ajax_nonce' );
if ( ! current_user_can( 'customize' ) ) {
wp_send_json_error( __( "Permission denied: You don't have sufficient permissions to import. Please contact your site administrator.", 'astra-sites' ) );
}
}
if ( ! class_exists( 'STImporter\Importer\ST_Importer_File_System' ) ) {
self::error_response( __( 'Import failed: ST_Importer_File_System class not found. Please ensure the importer is properly loaded.', 'astra-sites' ) );
return;
}
// Handle demo content retrieval with specific error handling.
try {
$demo_data = ST_Importer_File_System::get_instance()->get_demo_content();
if ( is_null( $demo_data ) ) {
$demo_data = array(); // Fallback to prevent null errors.
}
} catch ( \Exception $e ) {
astra_sites_error_log( 'Import End: Exception getting demo content - ' . $e->getMessage() );
// translators: %s: Error message.
self::error_response( sprintf( __( 'Import failed: Unexpected error - %s', 'astra-sites' ), $e->getMessage() ) );
return;
} catch ( \Error $e ) {
// translators: %s: Error message.
self::error_response( sprintf( __( 'Import failed: Fatal error - %s', 'astra-sites' ), $e->getMessage() ) );
return;
}
// Set permalink structure to use post name.
update_option( 'permalink_structure', '/%postname%/' );
update_option( 'astra-site-permalink-update-status', 'no' );
// Safely execute import complete action.
try {
do_action( 'astra_sites_import_complete', $demo_data );
} catch ( \Exception $e ) {
astra_sites_error_log( 'Import End: Exception in import_complete action - ' . $e->getMessage() );
// Continue execution - don't fail the entire import for hook issues.
}
self::success_response( __( 'Import completed successfully!', 'astra-sites' ) );
}
/**
* Reset customizer data
*
* @since 1.3.0
* @return void
*/
public static function reset_customizer_data() {
if ( ! defined( 'WP_CLI' ) && wp_doing_ajax() ) {
// Verify Nonce.
check_ajax_referer( 'astra-sites', '_ajax_nonce' );
if ( ! current_user_can( 'customize' ) ) {
wp_send_json_error( __( 'You are not allowed to perform this action', 'astra-sites' ) );
}
}
Ai_Builder_Importer_Log::add( 'Deleted customizer Settings ' . wp_json_encode( get_option( 'astra-settings', array() ) ) );
if ( ! class_exists( 'STImporter\Resetter\ST_Resetter' ) ) {
self::error_response( __( 'Required class not found.', 'astra-sites' ) );
return;
}
ST_Resetter::reset_customizer_data();
self::success_response( __( 'Deleted Customizer Settings!', 'astra-sites' ) );
}
/**
* Reset site options
*
* @since 1.3.0
* @return void
*/
public static function reset_site_options() {
if ( ! defined( 'WP_CLI' ) && wp_doing_ajax() ) {
// Verify Nonce.
check_ajax_referer( 'astra-sites', '_ajax_nonce' );
if ( ! current_user_can( 'customize' ) ) {
wp_send_json_error( __( 'You are not allowed to perform this action', 'astra-sites' ) );
}
}
$options = get_option( '_astra_sites_old_site_options', array() );
Ai_Builder_Importer_Log::add( 'Deleted - Site Options ' . wp_json_encode( $options ) );
if ( ! class_exists( 'STImporter\Resetter\ST_Resetter' ) ) {
self::error_response( __( 'Required class not found.', 'astra-sites' ) );
return;
}
ST_Resetter::reset_site_options( $options );
self::success_response( __( 'Deleted Site Options!', 'astra-sites' ) );
}
/**
* Reset widgets data
*
* @since 1.3.0
* @return void
*/
public static function reset_widgets_data() {
if ( ! defined( 'WP_CLI' ) && wp_doing_ajax() ) {
// Verify Nonce.
check_ajax_referer( 'astra-sites', '_ajax_nonce' );
if ( ! current_user_can( 'customize' ) ) {
wp_send_json_error( __( 'You are not allowed to perform this action', 'astra-sites' ) );
}
}
// Get all old widget ids.
$old_widgets_data = (array) get_option( '_astra_sites_old_widgets_data', array() );
if ( ! class_exists( 'STImporter\Resetter\ST_Resetter' ) ) {
self::error_response( __( 'Required class not found.', 'astra-sites' ) );
return;
}
ST_Resetter::reset_widgets_data( $old_widgets_data );
self::success_response( __( 'Deleted Widgets!', 'astra-sites' ) );
}
/**
* Import Customizer Settings.
*
* @since 1.0.14
* @since 1.4.0 The `$customizer_data` was added.
*
* @param array<string, mixed> $customizer_data Customizer Data.
* @return void
*/
public static function import_customizer_settings( $customizer_data = array() ) {
if ( ! defined( 'WP_CLI' ) && wp_doing_ajax() ) {
// Verify Nonce.
check_ajax_referer( 'astra-sites', '_ajax_nonce' );
if ( ! current_user_can( 'customize' ) ) {
wp_send_json_error( __( 'You are not allowed to perform this action', 'astra-sites' ) );
}
}
if ( empty( $customizer_data ) ) {
$customizer_data = astra_get_site_data( 'astra-site-customizer-data' );
}
if ( empty( $customizer_data ) ) {
self::error_response( __( 'Customizer data is empty!', 'astra-sites' ) );
return;
}
if ( ! class_exists( 'STImporter\Importer\ST_Importer' ) ) {
self::error_response( __( 'Required class not found.', 'astra-sites' ) );
return;
}
$result = ST_Importer::import_customizer_settings( $customizer_data );
if ( false === $result['status'] ) {
self::error_response( $result['error'] );
return;
}
self::success_response();
}
/**
* Send error response for both WP_CLI and AJAX contexts.
*
* @param string|array<string, mixed>|mixed|null $data Error message or data to display.
*
* @since 1.2.63
* @return void
*/
public static function error_response( $data = null ) {
if ( defined( 'WP_CLI' ) ) {
$error = is_array( $data ) && isset( $data['error'] ) ? $data['error'] : $data;
$error = is_array( $error ) ? wp_json_encode( $error ) : $error;
\WP_CLI::error( $error );
} elseif ( wp_doing_ajax() ) {
wp_send_json_error( $data );
}
}
/**
* Send success response for both WP_CLI and AJAX contexts.
*
* @param string|array<string|int, mixed>|null $data Success message or data to send.
*
* @since 1.2.63
* @return void
*/
public static function success_response( $data = null ) {
if ( defined( 'WP_CLI' ) ) {
$message = is_array( $data ) && isset( $data['message'] ) ? $data['message'] : $data;
$message = is_array( $message ) ? wp_json_encode( $message ) : $message;
\WP_CLI::line( $message );
return;
}
if ( wp_doing_ajax() ) {
$response = empty( $data ) ? array() : $data;
wp_send_json_success( $response );
}
}
/**
* Get the server's country code using its public IP.
*
* @param string $provider Optional. GeoIP provider: 'ipwhois', 'ipapi', or 'ipinfo'. Default 'ipwhois'.
* @param string $token Optional. API token (only needed for ipapi/ipinfo).
*
* @since 1.2.59
* @return string Two-letter ISO country code (e.g., 'RU', 'US'), or 'unknown' on failure.
*/
public static function get_server_country_code( $provider = 'ipwhois', $token = '' ) {
// Step 1: Get server's public IP.
$response = wp_remote_get( 'https://api.ipify.org' );
if ( is_wp_error( $response ) ) {
return 'unknown';
}
$ip = wp_remote_retrieve_body( $response );
if ( empty( $ip ) ) {
return 'unknown';
}
// Step 2: Select provider endpoint.
switch ( strtolower( $provider ) ) {
case 'ipapi':
// Requires token for higher limits.
$url = "https://ipapi.co/{$ip}/country/";
if ( ! empty( $token ) ) {
$url = "https://ipapi.co/{$ip}/country/?key={$token}";
}
break;
case 'ipinfo':
$url = "https://ipinfo.io/{$ip}/country";
if ( ! empty( $token ) ) {
$url .= "?token={$token}";
}
break;
case 'ipwhois':
default:
// Default: ipwho.is (no token needed).
$url = "https://ipwho.is/{$ip}";
break;
}
// Step 3: Make request.
$response = wp_remote_get( $url );
if ( is_wp_error( $response ) ) {
return 'unknown';
}
$body = wp_remote_retrieve_body( $response );
// Step 4: Parse response based on provider.
if ( 'ipwhois' === $provider ) {
$data = json_decode( $body, true );
if ( is_array( $data ) && isset( $data['country_code'] ) && is_string( $data['country_code'] ) ) {
return $data['country_code'];
}
return 'unknown';
}
// ipapi and ipinfo return plain text country code.
$country = trim( $body );
return ! empty( $country ) ? $country : 'unknown';
}
/**
* Get Images Engine
*
* @since 1.2.59
* @return string Image Engine.
*/
public static function get_images_engine() {
$country_code = get_transient( 'zipwp_images_server_country_code' );
if ( false === $country_code ) {
$country_code = self::get_server_country_code();
set_transient( 'zipwp_images_server_country_code', $country_code, MONTH_IN_SECONDS );
}
// Use Unsplash for Russia as Pexels is blocked there.
if ( 'RU' === $country_code ) {
return 'unsplash';
}
// Default to Pexels.
return 'pexels';
}
}