is_divi_enabled() ) ) {
require_once CARTFLOWS_DIR . 'classes/importer/batch-process/class-cartflows-importer-divi.php';
require_once CARTFLOWS_DIR . 'classes/importer/batch-process/class-cartflows-importer-divi-batch.php';
self::$batch_instance_divi = new Cartflows_Importer_Divi_Batch();
}
// Gutenberg.
if ( ( 'gutenberg' === $default_page_builder ) ) {
require_once CARTFLOWS_DIR . 'classes/importer/batch-process/class-cartflows-importer-gutenberg.php';
require_once CARTFLOWS_DIR . 'classes/importer/batch-process/class-cartflows-importer-gutenberg-batch.php';
self::$batch_instance_gb = new Cartflows_Importer_Gutenberg_Batch();
}
require_once CARTFLOWS_DIR . 'classes/importer/batch-process/class-cartflows-batch-processing-sync-library.php';
require_once CARTFLOWS_DIR . 'classes/importer/batch-process/helpers/class-wp-background-process-cartflows-sync-library.php';
self::$process_site_importer = new WP_Background_Process_Cartflows_Sync_Library();
// Start image importing after site import complete.
add_action( 'cartflows_after_template_import', array( $this, 'start_batch_process' ) );
add_action( 'cartflows_import_complete', array( $this, 'complete_batch_import' ) );
add_filter( 'upload_mimes', array( $this, 'custom_upload_mimes' ) ); //phpcs:ignore WordPressVIPMinimum.Hooks.RestrictedHooks.upload_mimes
add_filter( 'wp_prepare_attachment_for_js', array( $this, 'add_svg_image_support' ), 10, 3 );
add_action( 'cartflows_before_elementor_import_single_template', array( $this, 'enable_unfiltered_upload_elementor' ) );
add_action( 'admin_head', array( $this, 'start_importer' ) );
}
/**
* Start Importer
*
* @since 1.6.15
* @return void
*/
public function start_importer() {
$is_fresh_site = get_site_option( 'cartflows-fresh-site', '' );
// Process initially for the fresh user.
if ( isset( $_GET['reset'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
// Process import.
$this->process_batch();
} elseif ( empty( $is_fresh_site ) ) {
// First time user save the data of sites, pages, categories etc from the JSON file.
$dir = CARTFLOWS_DIR . 'admin-core/assets/importer-data';
$list_files = list_files( $dir );
if ( ! empty( $list_files ) ) {
$list_files = array_map( 'basename', $list_files );
foreach ( $list_files as $key => $file_name ) {
$data = file_get_contents( $dir . '/' . $file_name );
if ( ! empty( $data ) ) {
$option_name = str_replace( '.json', '', $file_name );
update_site_option( $option_name, json_decode( $data, true ) );
}
}
}
// Also, Trigger the batch to get latest data.
// If batch failed then user have at least the data from the JSON file.
$this->process_batch();
update_site_option( 'cartflows-fresh-site', 'yes', 'no' );
// If not fresh user then trigger batch import on the transient and option
// Only on the Astra Sites page.
} else {
$current_screen = get_current_screen();
// Bail if not on Astra Sites screen.
if ( ! is_object( $current_screen ) && null === $current_screen ) {
return;
}
if ( 'cartflows_page_cartflows_settings' === $current_screen->id ) {
// Process import.
$this->process_batch();
}
}
}
/**
* Update Latest Checksums
*
* Store latest checksum after batch complete.
*
* @param string $templates templates category to fetch.
* @since 1.6.15
* @return void
*/
public function update_latest_checksums( $templates = '' ) {
$suffix = 'store-checkout' === $templates ? 'store-checkout-' : '';
wcf()->logger->sync_log( 'Checkusms updated' );
$latest_checksums = get_site_option( 'cartflows-' . $suffix . 'last-export-checksums-latest', '' );
update_site_option( 'cartflows-' . $suffix . 'last-export-checksums', $latest_checksums, 'no' );
}
/**
* Added .svg files as supported format in the uploader.
*
* @since 1.1.4
*
* @param array $mimes Already supported mime types.
*/
public function custom_upload_mimes( $mimes ) {
// Allow SVG files.
$mimes['svg'] = 'image/svg+xml';
$mimes['svgz'] = 'image/svg+xml';
// Allow XML files.
$mimes['xml'] = 'text/xml';
return $mimes;
}
/**
* Add SVG image support
*
* @since 1.1.4
*
* @param array $response Attachment response.
* @param object $attachment Attachment object.
* @param array $meta Attachment meta data.
*/
public function add_svg_image_support( $response, $attachment, $meta ) {
if ( ! function_exists( 'simplexml_load_file' ) ) {
return $response;
}
if ( ! empty( $response['sizes'] ) ) {
return $response;
}
if ( 'image/svg+xml' !== $response['mime'] ) {
return $response;
}
$svg_path = get_attached_file( $attachment->ID );
$dimensions = self::get_svg_dimensions( $svg_path );
$response['sizes'] = array(
'full' => array(
'url' => $response['url'],
'width' => $dimensions->width,
'height' => $dimensions->height,
'orientation' => $dimensions->width > $dimensions->height ? 'landscape' : 'portrait',
),
);
return $response;
}
/**
* Get SVG Dimensions
*
* @since 1.1.4.
*
* @param string $svg SVG file path.
* @return array Return SVG file height & width for valid SVG file.
*/
public static function get_svg_dimensions( $svg ) {
$svg = simplexml_load_file( $svg );
if ( false === $svg ) {
$width = '0';
$height = '0';
} else {
$attributes = $svg->attributes();
$width = (string) $attributes->width;
$height = (string) $attributes->height;
}
return (object) array(
'width' => $width,
'height' => $height,
);
}
/**
* Batch Process Complete.
*
* @return void
*/
public function complete_batch_import() {
wcf()->logger->import_log( '(✓) BATCH Process Complete!' );
}
/**
* Start Image Import
*
* @param integer $post_id Post Id.
*
* @return void
*/
public function start_batch_process( $post_id = '' ) {
$default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
wcf()->logger->import_log( '(✓) BATCH Started!' );
wcf()->logger->import_log( '(✓) Step ID ' . $post_id );
// Add "elementor" in import [queue].
if ( 'beaver-builder' === $default_page_builder && self::$batch_instance_bb ) {
// Add to queue.
self::$batch_instance_bb->push_to_queue( $post_id );
// Dispatch Queue.
self::$batch_instance_bb->save()->dispatch();
wcf()->logger->import_log( '(✓) Dispatch "Beaver Builder" Request..' );
} elseif ( 'elementor' === $default_page_builder && self::$batch_instance_elementor ) {
// Add to queue.
self::$batch_instance_elementor->push_to_queue( $post_id );
// Dispatch Queue.
self::$batch_instance_elementor->save()->dispatch();
wcf()->logger->import_log( '(✓) Dispatch "Elementor" Request..' );
} elseif ( 'divi' === $default_page_builder && self::$batch_instance_divi ) {
// Add to queue.
self::$batch_instance_divi->push_to_queue( $post_id );
// Dispatch Queue.
self::$batch_instance_divi->save()->dispatch();
wcf()->logger->import_log( '(✓) Dispatch "Divi" Request..' );
} elseif ( 'gutenberg' === $default_page_builder && self::$batch_instance_gb ) {
// Add to queue.
self::$batch_instance_gb->push_to_queue( $post_id );
// Dispatch Queue.
self::$batch_instance_gb->save()->dispatch();
wcf()->logger->import_log( '(✓) Dispatch "Gutenberg" Request..' );
} else {
wcf()->logger->import_log( '(✕) Could not import image due to allow_url_fopen() is disabled!' );
}
}
/**
* Set Last Exported Checksum
*
* @param string $templates templates category to fetch.
* @since 1.6.15
* @return string Checksums Status.
*/
public function set_last_export_checksums( $templates = '' ) {
if ( ! empty( $this->last_export_checksums ) ) {
return $this->last_export_checksums;
}
$api_args = array(
'timeout' => 60, //phpcs:ignore WordPressVIPMinimum.Performance.RemoteRequestTimeout.timeout_timeout
);
wcf()->logger->sync_log( wcf()->get_site_url() . 'wp-json/cartflows-server/v1/get-last-export-checksums' );
$response = wp_remote_get( wcf()->get_site_url() . 'wp-json/cartflows-server/v1/get-last-export-checksums', $api_args );
if ( ! is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) === 200 ) {
$result = json_decode( wp_remote_retrieve_body( $response ), true );
// Set last export checksums.
if ( ! empty( $result['last_export_checksums'] ) ) {
$suffix = 'store-checkout' === $templates ? 'store-checkout-' : '';
update_site_option( 'cartflows-' . $suffix . 'last-export-checksums-latest', $result['last_export_checksums'], 'no' );
$this->last_export_checksums = $result['last_export_checksums'];
}
}
return $this->last_export_checksums;
}
/**
* Get Last Exported Checksum Status
*
* @param string $templates templates category to fetch.
* @since 1.6.15
* @return string Checksums Status.
*/
public function get_last_export_checksums( $templates = '' ) {
$suffix = 'store-checkout' === $templates ? 'store-checkout-' : '';
$old_last_export_checksums = get_site_option( 'cartflows-' . $suffix . 'last-export-checksums', '' );
$new_last_export_checksums = $this->set_last_export_checksums( $templates );
$checksums_status = 'no';
if ( empty( $old_last_export_checksums ) ) {
$checksums_status = 'yes';
}
if ( $new_last_export_checksums != $old_last_export_checksums ) {
$checksums_status = 'yes';
}
return apply_filters( 'cartflows_checksums_status', $checksums_status );
}
/**
* Check Cron Status
*
* Gets the current cron status by performing a test spawn. Cached for one hour when all is well.
*
* @since 1.6.15
*
* @param bool $cache Whether to use the cached result from previous calls.
* @return true|WP_Error Boolean true if the cron spawner is working as expected, or a WP_Error object if not.
*/
public function test_cron( $cache = true ) {
global $wp_version;
if ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) {
return new WP_Error( 'wp_portfolio_cron_error', esc_html__( 'ERROR! Cron schedules are disabled by setting constant DISABLE_WP_CRON to true.
To start the import process please enable the cron by setting the constant to false. E.g. define( \'DISABLE_WP_CRON\', false );', 'cartflows' ) );
}
if ( defined( 'ALTERNATE_WP_CRON' ) && ALTERNATE_WP_CRON ) {
return new WP_Error( 'wp_portfolio_cron_error', esc_html__( 'ERROR! Cron schedules are disabled by setting constant ALTERNATE_WP_CRON to true.
To start the import process please enable the cron by setting the constant to false. E.g. define( \'ALTERNATE_WP_CRON\', false );', 'cartflows' ) );
}
$cached_status = get_transient( 'cartflows-cron-test-ok' );
if ( $cache && $cached_status ) {
return true;
}
$sslverify = version_compare( $wp_version, 4.0, '<' );
$doing_wp_cron = sprintf( '%.22F', microtime( true ) );
$cron_request = apply_filters(
'cron_request',
array(
'url' => site_url( 'wp-cron.php?doing_wp_cron=' . $doing_wp_cron ),
'key' => $doing_wp_cron,
'args' => array(
'timeout' => 3,
'blocking' => true,
'sslverify' => apply_filters( 'https_local_ssl_verify', $sslverify ),
),
)
);
$cron_request['args']['blocking'] = true;
$result = wp_remote_post( $cron_request['url'], $cron_request['args'] );
if ( is_wp_error( $result ) ) {
return $result;
} elseif ( wp_remote_retrieve_response_code( $result ) >= 300 ) {
return new WP_Error(
'unexpected_http_response_code',
sprintf(
/* translators: 1: The HTTP response code. */
__( 'Unexpected HTTP response code: %s', 'cartflows' ),
intval( wp_remote_retrieve_response_code( $result ) )
)
);
} else {
set_transient( 'cartflows-cron-test-ok', 1, 3600 );
return true;
}
}
/**
* Get Blocks Total Requests
*
* @since 1.6.15
* @param string $page_builder_slug Page builder slug.
* @param string $templates templates category to fetch.
* @return integer
*/
public function get_total_requests( $page_builder_slug = '', $templates = '' ) {
$page_builder_slug = ( ! empty( $page_builder_slug ) ) ? $page_builder_slug : wcf()->get_site_slug();
update_site_option( 'cartflows-batch-status-string', 'Getting Total Blocks', 'no' );
$api_args = array(
'timeout' => 60, //phpcs:ignore WordPressVIPMinimum.Performance.RemoteRequestTimeout.timeout_timeout
);
$url = wcf()->get_site_url( $page_builder_slug ) . 'wp-json/cartflows-server/v1/get-total-flows/';
wcf()->logger->sync_log( $url );
$response = wp_remote_get( $url, $api_args );
/* Check one more time */
if ( is_wp_error( $response ) ) {
$response = wp_remote_get( $url, $api_args );
}
if ( ! is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) === 200 ) {
$total_requests = json_decode( wp_remote_retrieve_body( $response ), true );
$suffix = 'store-checkout' === $templates ? 'store-checkout-' : '';
if ( isset( $total_requests['pages'] ) ) {
update_site_option( 'cartflows-batch-status-string', 'Updated requests ' . $total_requests['pages'], 'no' );
update_site_option( 'cartflows-' . $suffix . $page_builder_slug . '-requests', $total_requests['pages'], 'no' );
return $total_requests['pages'];
}
} else {
wcf()->logger->sync_log( 'Client\'s server is blocking requests. May be client\'s server firewall is blocking request. Make sure a firewall or any kind of secuirty pluging is blocking requests or not?' );
/* Fallback default data if client server is blocking requests */
$total_requests = array(
'no_of_items' => 15,
'pages' => 1,
'per_page' => 100,
);
update_site_option( 'cartflows-batch-status-string', 'Updated requests ' . $total_requests['pages'], 'no' );
update_site_option( 'cartflows-' . $page_builder_slug . '-requests', $total_requests['pages'], 'no' );
return $total_requests['pages'];
}
}
/**
* Process Batch
*
* @since 1.6.15
* @param string $templates templates category to fetch.
* @return mixed
*/
public function process_batch( $templates = '' ) {
if ( 'other' === wcf()->get_site_slug() ) {
if ( defined( 'WP_CLI' ) ) {
WP_CLI::error( 'Invalid page builder! Please select the page builder to start sync process.' );
} else {
return;
}
}
if ( 'no' === $this->get_last_export_checksums( $templates ) ) {
if ( defined( 'WP_CLI' ) ) {
WP_CLI::line( 'Library is up to date!' );
}
return;
}
$status = $this->test_cron();
if ( is_wp_error( $status ) ) {
if ( defined( 'WP_CLI' ) ) {
WP_CLI::line( 'Error! Batch Not Start due to disabled cron events!' );
}
update_site_option( 'cartflows-batch-status-string', 'Error! Batch Not Start due to disabled cron events!', 'no' );
if ( defined( 'WP_CLI' ) ) {
WP_CLI::line( 'Error! Batch Not Start due to disabled cron events!' );
} else {
// For non- WP CLI request return to prevent the request.
return;
}
}
// Get count.
$total_requests = $this->get_total_requests();
if ( $total_requests ) {
if ( defined( 'WP_CLI' ) ) {
WP_CLI::line( 'Total Requests ' . $total_requests );
}
for ( $page = 1; $page <= $total_requests; $page++ ) {
if ( defined( 'WP_CLI' ) ) {
WP_CLI::line( 'Added page ' . $page . ' in queue.' );
}
if ( defined( 'WP_CLI' ) ) {
Cartflows_Batch_Processing_Sync_Library::get_instance()->import_sites( $page, $templates );
} else {
self::$process_site_importer->push_to_queue(
array(
'page' => $page,
'template' => $templates,
'instance' => Cartflows_Batch_Processing_Sync_Library::get_instance(),
'method' => 'import_sites',
)
);
}
}
}
if ( defined( 'WP_CLI' ) ) {
WP_CLI::line( 'Sync Process Complete.' );
} else {
// Dispatch Queue.
self::$process_site_importer->save()->dispatch();
}
}
/**
* Enable the unfiltered upload of the elementor to upload the SVG files.
*
* @since 1.10.0
*/
public function enable_unfiltered_upload_elementor() {
add_filter( 'elementor/files/allow_unfiltered_upload', '__return_true' );
}
}
/**
* Kicking this off by calling 'get_instance()' method
*/
CartFlows_Batch_Process::get_instance();
endif;