ProShell v2.0
Dashboard
Server Info
Server: 158.106.128.192
PHP: 8.2.33
home
planet5
public_html
bansibaba.com
wp-includes
2026-09-15 08:51:22
Editing: import-export-functions.php
Cancel
Save Changes
<?php /** * V2 Import/Export Functions * * These are wrapper functions for the existing import/export functionality * to work with the new WordPress-native admin system * * @package SeedProd_Lite * @subpackage SeedProd_Lite/admin/includes */ // Exit if accessed directly if ( ! defined( 'ABSPATH' ) ) { exit; } // Include V2 utility functions require_once __DIR__ . '/import-export-utilities.php'; /* ============================================== HELPER FUNCTIONS FOR IMPORT/EXPORT OPERATIONS ============================================== */ /** * Validate AJAX request with nonce and permissions. * * @param string $capability The capability to check. */ function seedprod_lite_v2_validate_ajax_request( $capability = 'export' ) { if ( ! check_ajax_referer( 'seedprod_v2_nonce', 'nonce', false ) ) { wp_send_json_error( __( 'Invalid security token', 'coming-soon' ) ); } if ( ! current_user_can( apply_filters( 'seedprod_import_export', $capability ) ) ) { wp_send_json_error( __( 'Insufficient permissions', 'coming-soon' ) ); } } /** * Initialize WordPress filesystem. * * @return object WP_Filesystem instance. */ function seedprod_lite_v2_init_filesystem() { if ( ! function_exists( 'WP_Filesystem' ) ) { require_once ABSPATH . 'wp-admin/includes/file.php'; } // Force direct filesystem method for AJAX requests add_filter( 'filesystem_method', function () { return 'direct'; } ); global $wp_filesystem; WP_Filesystem(); return $wp_filesystem; } /** * Get upload error message. * * @param int $error_code The PHP upload error code. * @return string The error message. */ function seedprod_lite_v2_get_upload_error_message( $error_code ) { switch ( $error_code ) { case UPLOAD_ERR_INI_SIZE: case UPLOAD_ERR_FORM_SIZE: return __( 'File is too large', 'coming-soon' ); case UPLOAD_ERR_PARTIAL: return __( 'File was only partially uploaded', 'coming-soon' ); case UPLOAD_ERR_NO_FILE: return __( 'No file was uploaded', 'coming-soon' ); default: return __( 'File upload failed', 'coming-soon' ); } } /** * Validate ZIP file upload. * * @param string $file_key The $_FILES array key. * @return array File information or sends JSON error. */ function seedprod_lite_v2_validate_zip_upload( $file_key ) { // Check if file was uploaded. if ( ! isset( $_FILES[ $file_key ] ) ) { wp_send_json_error( __( 'No file uploaded', 'coming-soon' ) ); } // Check for upload errors. if ( UPLOAD_ERR_OK !== $_FILES[ $file_key ]['error'] ) { $error_message = seedprod_lite_v2_get_upload_error_message( $_FILES[ $file_key ]['error'] ); wp_send_json_error( $error_message ); } $filename = wp_unslash( $_FILES[ $file_key ]['name'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized $source = $_FILES[ $file_key ]['tmp_name']; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash $type = $_FILES[ $file_key ]['type']; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash // Validate ZIP file type. $accepted_types = array( 'application/zip', 'application/x-zip-compressed', 'multipart/x-zip', 'application/x-compressed', ); $is_valid_type = in_array( $type, $accepted_types, true ); $has_zip_extension = preg_match( '/\.zip$/i', $filename ); if ( ! $is_valid_type && ! $has_zip_extension ) { wp_send_json_error( __( 'The file you are trying to upload is not a .zip file. Please try again.', 'coming-soon' ) ); } return array( 'filename' => $filename, 'source' => $source, 'type' => $type, ); } /** * Extract ZIP file with validation. * * @param string $zip_path Path to ZIP file. * @param string $extract_to Directory to extract to. * @param bool $is_theme Whether this is a theme import. * @return bool|WP_Error True on success, WP_Error on failure. */ function seedprod_lite_v2_extract_zip( $zip_path, $extract_to, $is_theme = true ) { // Validate ZIP contents. $validation = seedprod_lite_v2_validate_import_zip( $zip_path, $is_theme ); if ( is_wp_error( $validation ) ) { return $validation; } if ( ! class_exists( 'ZipArchive' ) ) { return new WP_Error( 'zip_not_available', __( 'ZipArchive class not available. Please contact your host to enable it.', 'coming-soon' ) ); } $zip = new ZipArchive(); if ( true === $zip->open( $zip_path ) ) { $zip->extractTo( $extract_to ); $zip->close(); return true; } return new WP_Error( 'extract_failed', __( 'Failed to extract ZIP file.', 'coming-soon' ) ); } /** * Read JSON file with HTTP/filesystem fallback. * * @param string $file_path Local file path. * @param string $url_path Optional URL for HTTP attempt. * @return object|WP_Error Decoded JSON data or WP_Error. */ function seedprod_lite_v2_read_json_file( $file_path, $url_path = null ) { global $wp_filesystem; $json_data = null; // Try HTTP first if URL provided. if ( $url_path ) { $response = wp_remote_get( $url_path, array( 'sslverify' => false ) ); if ( ! is_wp_error( $response ) && 200 === wp_remote_retrieve_response_code( $response ) ) { $json_data = wp_remote_retrieve_body( $response ); } } // Fallback to direct filesystem reading. if ( ! $json_data && $wp_filesystem && $wp_filesystem->exists( $file_path ) ) { $json_data = $wp_filesystem->get_contents( $file_path ); } if ( ! $json_data ) { return new WP_Error( 'read_failed', __( 'Unable to read data file.', 'coming-soon' ) ); } // Decode and validate JSON. $data = json_decode( $json_data ); if ( null === $data && JSON_ERROR_NONE !== json_last_error() ) { return new WP_Error( 'invalid_json', __( 'Invalid data format.', 'coming-soon' ) ); } return $data; } /** * Process and prepare export data for themes/pages. * * @param array $results Database results. * @param string $type Export type ('theme' or 'page'). * @param mixed $ptype Page type for landing pages. * @return array Processed export data. */ function seedprod_lite_v2_process_export_data( $results, $type = 'theme', $ptype = null ) { $processed_data = array(); $export = array(); $shortcode_exports = array(); // Set export type $export['type'] = ( 'theme' === $type ) ? 'theme-builder' : 'landing-page'; $export['current_home_url'] = home_url(); $export['theme'] = array(); $export['mapped'] = array(); // Check if this is a template (contains placehold.co) $is_template = false; if ( 'theme' === $type ) { foreach ( $results as $v ) { if ( strpos( $v->post_content_filtered, 'placehold.co' ) !== false ) { $is_template = true; break; } } } // Process each result foreach ( $results as $k => $v ) { // Skip if essential data is missing if ( empty( $v->ID ) ) { continue; } $meta = ( 'theme' === $type ) ? get_post_meta( $v->ID ) : wp_json_encode( get_post_meta( $v->ID ) ); if ( 'theme' === $type && $is_template ) { unset( $meta['_seedprod_css'] ); unset( $meta['_seedprod_html'] ); } if ( 'theme' === $type ) { $meta = json_encode( $meta ); // phpcs:ignore } // Handle null/empty content safely $content = ! empty( $v->post_content ) ? $v->post_content : ''; $content_filtered = ! empty( $v->post_content_filtered ) ? $v->post_content_filtered : ''; // Process image filenames if ( 'theme' === $type && $is_template ) { $processed_data[ $k ] = array( 'data' => $content_filtered, 'html' => $content, 'images' => array(), ); } else { $processed_result = seedprod_lite_v2_process_image_filenames( $content_filtered, $content ); // Ensure the result has the expected structure $processed_data[ $k ] = array( 'data' => isset( $processed_result['data'] ) ? $processed_result['data'] : $content_filtered, 'html' => isset( $processed_result['html'] ) ? $processed_result['html'] : $content, 'images' => isset( $processed_result['images'] ) && is_array( $processed_result['images'] ) ? $processed_result['images'] : array(), ); } // Safely get processed data with fallbacks $processed_html = isset( $processed_data[ $k ]['html'] ) ? $processed_data[ $k ]['html'] : ''; $processed_data_content = isset( $processed_data[ $k ]['data'] ) ? $processed_data[ $k ]['data'] : ''; // Build export entry $entry = array( 'order' => $v->menu_order, 'post_content' => base64_encode( $processed_html ), // phpcs:ignore 'post_content_filtered' => base64_encode( $processed_data_content ), // phpcs:ignore 'post_title' => base64_encode( $v->post_title ), // phpcs:ignore 'meta' => base64_encode( $meta ), // phpcs:ignore ); // Add page-specific fields if ( 'page' === $type ) { $entry['post_type'] = base64_encode( $v->post_type ); // phpcs:ignore $entry['post_status'] = base64_encode( $v->post_status ); // phpcs:ignore // Determine page type: check both meta field AND WordPress options // Special pages are identified by options, not meta $actual_ptype = get_post_meta( $v->ID, '_seedprod_page_type', true ); // If no meta, check if this is a special page by checking WordPress options if ( empty( $actual_ptype ) ) { $coming_soon_id = get_option( 'seedprod_coming_soon_page_id' ); $maintenance_id = get_option( 'seedprod_maintenance_mode_page_id' ); $login_id = get_option( 'seedprod_login_page_id' ); $fourohfour_id = get_option( 'seedprod_404_page_id' ); if ( $v->ID == $coming_soon_id ) { $actual_ptype = 'cs'; } elseif ( $v->ID == $maintenance_id ) { $actual_ptype = 'mm'; } elseif ( $v->ID == $login_id ) { $actual_ptype = 'loginp'; } elseif ( $v->ID == $fourohfour_id ) { $actual_ptype = 'p404'; } } $entry['ptype'] = base64_encode( $actual_ptype ?? '' ); // phpcs:ignore } $export['theme'][] = $entry; // Find shortcodes in content (for both themes and landing pages) if ( ! empty( $processed_html ) ) { $post_content_shortcode = base64_decode( base64_encode( $processed_html ) ); // phpcs:ignore $re = '/((\[)(sp_template_part id="){1}[0-9]*["](\]))/m'; preg_match_all( $re, $post_content_shortcode, $matches, PREG_SET_ORDER, 0 ); if ( $matches ) { foreach ( $matches as $t => $val ) { $shortcode_content = $val[0]; $shortcode_page_sc = str_replace( '[sp_template_part id="', '', $shortcode_content ); $shortcode_page_sc = str_replace( '"]', '', $shortcode_page_sc ); $shortcode_exports[ $shortcode_page_sc ] = array( 'id' => $shortcode_page_sc, 'shortcode' => $shortcode_content, ); } } } } return array( 'export' => $export, 'processed_data' => $processed_data, 'shortcode_exports' => $shortcode_exports, ); } /* ============================================== MAIN EXPORT/IMPORT FUNCTIONS ============================================== */ /** * Export landing pages (V2 implementation) * Exports all landing pages as a downloadable ZIP file */ function seedprod_lite_v2_export_landing_pages() { // Validate request and permissions try { seedprod_lite_v2_validate_ajax_request( 'export' ); } catch ( Exception $e ) { wp_send_json_error( 'Validation failed: ' . $e->getMessage() ); } // Initialize filesystem try { seedprod_lite_v2_init_filesystem(); } catch ( Exception $e ) { wp_send_json_error( 'Filesystem initialization failed: ' . $e->getMessage() ); } $page_id = isset( $_POST['page_id'] ) ? absint( sanitize_text_field( wp_unslash( $_POST['page_id'] ) ) ) : 0; $ptype = isset( $_POST['ptype'] ) ? sanitize_text_field( wp_unslash( $_POST['ptype'] ) ) : null; global $wpdb; $tablename = $wpdb->prefix . 'posts'; $meta_tablename = $wpdb->prefix . 'postmeta'; // Get list of landing pages - EXACT same logic as dropdown query // Get special page IDs (Coming Soon, Maintenance Mode, Login, 404) $coming_soon_id = get_option( 'seedprod_coming_soon_page_id' ); $maintenance_id = get_option( 'seedprod_maintenance_mode_page_id' ); $login_id = get_option( 'seedprod_login_page_id' ); $fourohfour_id = get_option( 'seedprod_404_page_id' ); $special_page_ids = array(); if ( ! empty( $coming_soon_id ) ) { $special_page_ids[] = $coming_soon_id; } if ( ! empty( $maintenance_id ) ) { $special_page_ids[] = $maintenance_id; } if ( ! empty( $login_id ) ) { $special_page_ids[] = $login_id; } if ( ! empty( $fourohfour_id ) ) { $special_page_ids[] = $fourohfour_id; } $special_pages_condition = ''; if ( ! empty( $special_page_ids ) ) { $special_ids_string = implode( ',', array_map( 'intval', $special_page_ids ) ); $special_pages_condition = " OR p.ID IN ($special_ids_string)"; } $sql = "SELECT p.*, pm.meta_key, pm.meta_value FROM $tablename p "; $sql .= "LEFT JOIN $meta_tablename pm ON (pm.post_id = p.ID AND pm.meta_key = '_seedprod_page_uuid') "; $sql .= "LEFT JOIN $meta_tablename pm4 ON (pm4.post_id = p.ID AND pm4.meta_key = '_seedprod_page_template_type') "; $sql .= "LEFT JOIN $meta_tablename pm5 ON (pm5.post_id = p.ID AND pm5.meta_key = '_seedprod_page') "; $sql .= "WHERE p.post_status != 'trash' "; $sql .= "AND p.post_type IN ('page', 'seedprod') "; $sql .= "AND ((p.post_type = 'page' AND pm4.meta_value = 'lp') OR (p.post_type = 'page' AND pm5.meta_value IS NOT NULL) $special_pages_condition) "; $sql .= "AND (pm.meta_value IS NOT NULL OR pm5.meta_value IS NOT NULL $special_pages_condition) "; if ( 0 !== $page_id ) { $sql .= "AND p.ID = $page_id "; } $sql .= 'GROUP BY p.ID '; $sql .= 'ORDER BY p.post_date DESC'; $results = $wpdb->get_results( $sql ); // phpcs:ignore if ( $wpdb->last_error ) { wp_send_json_error( 'Database error: ' . $wpdb->last_error ); } // Check if we have any pages to export if ( empty( $results ) ) { wp_send_json_error( __( 'No landing pages found to export.', 'coming-soon' ) ); } // Wrap in try-catch to catch any errors try { // Process export data using helper function $export_result = seedprod_lite_v2_process_export_data( $results, 'page', $ptype ); if ( is_wp_error( $export_result ) ) { wp_send_json_error( $export_result->get_error_message() ); } // Validate export result structure if ( ! isset( $export_result['export'] ) || ! isset( $export_result['processed_data'] ) || ! isset( $export_result['shortcode_exports'] ) ) { wp_send_json_error( __( 'Export data structure is invalid.', 'coming-soon' ) ); } $export = $export_result['export']; $processed_data = $export_result['processed_data']; $shortcode_exports = $export_result['shortcode_exports']; } catch ( Exception $e ) { /* translators: %s: Error message from the exception */ wp_send_json_error( sprintf( __( 'Export failed during processing: %s', 'coming-soon' ), $e->getMessage() ) ); } // Process shortcode mapping for landing pages (restored from old logic) foreach ( $shortcode_exports as $k => $sc_val ) { $shortcode_page_id = $sc_val['id']; // Use different variable name to avoid overwriting original $page_id $page_shortcode = $sc_val['shortcode']; $sql = "SELECT p.post_title FROM $tablename p LEFT JOIN $meta_tablename pm ON (pm.post_id = p.ID)"; $sql .= " WHERE p.ID = %d and post_status != 'trash' AND post_type IN ('page','seedprod') AND meta_key = '_seedprod_page_uuid' "; $safe_sql = $wpdb->prepare( $sql, absint( $shortcode_page_id ) ); // phpcs:ignore $page = $wpdb->get_row( $safe_sql ); // phpcs:ignore if ( ! empty( $page ) ) { $export['mapped'][] = array( 'id' => $shortcode_page_id, 'shortcode' => base64_encode( $page_shortcode ),// phpcs:ignore 'page_title' => $page->post_title, ); } } $export_json = wp_json_encode( $export ); // Check if JSON encoding failed if ( false === $export_json ) { $json_error = json_last_error_msg(); wp_send_json_error( __( 'Failed to encode export data. The page data may be too large or contain invalid characters.', 'coming-soon' ) . ' Error: ' . $json_error ); } $files_to_download = array(); global $wp_filesystem; $upload_dir = wp_upload_dir(); $path = trailingslashit( $upload_dir['basedir'] ) . 'seedprod-themes-exports/'; $targetdir = $path; // Create directory if it doesn't exist (don't delete - prevents race condition with concurrent exports). if ( ! is_dir( $targetdir ) ) { if ( ! wp_mkdir_p( $targetdir ) ) { wp_send_json_error( __( 'Failed to create export directory.', 'coming-soon' ) ); } } // Clean up old files (older than 1 hour) to prevent disk bloat. // This preserves recent exports from other users while still managing disk space. $old_files = glob( $targetdir . '*' ); $one_hour_ago = time() - HOUR_IN_SECONDS; if ( $old_files ) { foreach ( $old_files as $old_file ) { if ( filemtime( $old_file ) < $one_hour_ago ) { wp_delete_file( $old_file ); } } } // Save images locally $all_failed_images = array(); // Process images try { foreach ( $processed_data as $k1 => $v1 ) { // Check if images key exists and has items if ( isset( $processed_data[ $k1 ]['images'] ) && is_array( $processed_data[ $k1 ]['images'] ) && count( $processed_data[ $k1 ]['images'] ) > 0 ) { $failed_images = seedprod_lite_v2_save_images_locally( $processed_data[ $k1 ]['images'] ); if ( is_array( $failed_images ) ) { $all_failed_images = array_merge( $all_failed_images, $failed_images ); } } // Only add successfully downloaded images to the zip if ( isset( $processed_data[ $k1 ]['images'] ) && is_array( $processed_data[ $k1 ]['images'] ) ) { foreach ( $processed_data[ $k1 ]['images'] as $image ) { if ( ! isset( $image['filename'] ) ) { continue; } $image_path = trailingslashit( $upload_dir['basedir'] ) . 'seedprod-themes-exports/' . $image['filename']; if ( file_exists( $image_path ) ) { $files_to_download[] = $image['filename']; } } } } } catch ( Exception $e ) { /* translators: %s: Error message from the exception */ wp_send_json_error( sprintf( __( 'Export failed during image processing: %s', 'coming-soon' ), $e->getMessage() ) ); } // Create zip and return download URL try { $zip_result = seedprod_lite_v2_prepare_zip( $files_to_download, $export_json, 'page' ); if ( $zip_result && isset( $zip_result['filedata'] ) ) { wp_send_json_success( $zip_result ); } else { wp_send_json_error( __( 'Export completed but file data not generated.', 'coming-soon' ) ); } } catch ( Exception $e ) { /* translators: %s: Error message from the exception */ wp_send_json_error( sprintf( __( 'Export failed during ZIP creation: %s', 'coming-soon' ), $e->getMessage() ) ); } exit; } /** * Import landing pages (V2 implementation) * Imports landing pages from an uploaded ZIP file */ function seedprod_lite_v2_import_landing_pages() { // Validate request and permissions seedprod_lite_v2_validate_ajax_request( 'install_themes' ); // Validate and get uploaded file $zip_validation = seedprod_lite_v2_validate_zip_upload( 'seedprod_landing_files' ); if ( is_wp_error( $zip_validation ) ) { wp_send_json_error( $zip_validation->get_error_message() ); } // Initialize filesystem // Note: V2 uses direct filesystem access because this is an AJAX handler // and request_filesystem_credentials() doesn't work properly in AJAX context seedprod_lite_v2_init_filesystem(); if ( isset( $_FILES['seedprod_landing_files']['name'] ) ) { $filename = wp_unslash( $_FILES['seedprod_landing_files']['name'] ); // phpcs:ignore $source = $_FILES['seedprod_landing_files']['tmp_name']; // phpcs:ignore // Setup directories $filename_import = 'seedprod-themes-imports'; $upload_dir = wp_upload_dir(); $path = trailingslashit( $upload_dir['basedir'] ); $path_baseurl = trailingslashit( $upload_dir['baseurl'] ); $filenoext = basename( $filename_import, '.zip' ); $filenoext = basename( $filenoext, '.ZIP' ); $targetdir = $path . $filenoext; $targetzip = $path . $filename; $target_url = $path_baseurl . $filenoext; // Remove existing import directory if exists if ( is_dir( $targetdir ) ) { // Directory cleanup handled by V2 function seedprod_lite_v2_recursive_rmdir( $targetdir ); } // Create import directory wp_mkdir_p( $targetdir ); // phpcs:ignore Generic.PHP.ForbiddenFunctions.Found -- move_uploaded_file is required for handling HTTP file uploads securely. if ( move_uploaded_file( $source, $targetzip ) ) { // Validate zip contents $validation_result = seedprod_lite_v2_validate_import_zip( $targetzip, false ); if ( is_wp_error( $validation_result ) ) { wp_delete_file( $targetzip ); seedprod_lite_v2_recursive_rmdir( $targetdir ); wp_send_json_error( $validation_result->get_error_message() ); } // Extract ZIP file $extract_result = seedprod_lite_v2_extract_zip( $targetzip, $targetdir, false ); if ( is_wp_error( $extract_result ) ) { wp_delete_file( $targetzip ); seedprod_lite_v2_recursive_rmdir( $targetdir ); wp_send_json_error( $extract_result->get_error_message() ); } // Delete the zip file after extraction wp_delete_file( $targetzip ); // Read and validate landing page data $theme_json_path = $targetdir . '/export_page.json'; $url_path = $target_url . '/export_page.json'; $data = seedprod_lite_v2_read_json_file( $theme_json_path, $url_path ); if ( is_wp_error( $data ) ) { seedprod_lite_v2_recursive_rmdir( $targetdir ); wp_send_json_error( $data->get_error_message() ); } // Validate landing page type if ( ! empty( $data->type ) && 'landing-page' !== $data->type ) { seedprod_lite_v2_recursive_rmdir( $targetdir ); wp_send_json_error( __( 'This does not appear to be a SeedProd landing page.', 'coming-soon' ) ); } // Process the import // Process the landing page import $import_result = seedprod_lite_v2_landing_import_json( $data ); $warnings = isset( $import_result['warnings'] ) && is_array( $import_result['warnings'] ) ? $import_result['warnings'] : array(); // Remove the json file for security wp_delete_file( $theme_json_path ); // Clean up import directory seedprod_lite_v2_recursive_rmdir( $targetdir ); wp_send_json_success( array( 'warnings' => $warnings ) ); } else { $message = __( 'There was a problem with the upload. Please try again.', 'coming-soon' ); wp_send_json_error( $message ); } } else { wp_send_json_error( __( 'Invalid file upload.', 'coming-soon' ) ); } }
Upload Files
Cancel
Upload
Create New
Cancel
Create
Change Permissions
Cancel
Save
Change Date
Cancel
Save
Rename Item
Cancel
Save
Confirm Delete
Are you sure you want to delete the selected items?
Cancel
Delete