id !== 'themes' ) {
// return;
// }
// Enqueue admin CSS
wp_enqueue_style(
'aptce-admin',
plugins_url( 'assets/aptce-admin.css', AATCE_PLUGIN_FILE ),
[],
APTCE_VERSION
);
// Enqueue admin JS
wp_enqueue_script(
'aptce-admin',
plugins_url( 'assets/aptce-admin.js', AATCE_PLUGIN_FILE ),
['jquery'],
APTCE_VERSION,
true
);
wp_localize_script(
'aptce-admin',
'aptce',
[
'nonce' => wp_create_nonce( 'aptce_export' ),
'ajax_url' => admin_url( 'admin-ajax.php' )
]
);
// Prepare theme data
$themes = wp_get_themes();
$export = [];
foreach ( $themes as $slug => $theme ) {
$export[ $slug ] = [
'name' => $theme->get('Name'),
'aptce_download' => wp_nonce_url(
admin_url( 'admin-post.php?action=aptce_download_theme&slug=' . $slug ),
'aptce_download_' . $slug
),
];
}
// IMPORTANT: Do NOT overwrite wp.themes.*
wp_add_inline_script(
'aptce-admin',
'window.aptceThemeData = ' . wp_json_encode( $export, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT ) . ';',
'before'
);
}
public function aptce_register_menu() {
add_management_page(
__( 'Advanced Addons, Theme & Core Exporter', 'advanced-addons-theme-core-exporter' ),
__( 'Advanced Addons, Theme & Core Exporter', 'advanced-addons-theme-core-exporter' ),
'manage_options',
'advanced-addons-theme-core-exporter',
[ $this, 'aptce_render_admin_page' ]
);
}
public function aptce_add_settings_link( $links ) {
// New correct settings page URL
$url = admin_url( 'tools.php?page=advanced-addons-theme-core-exporter' );
// Create the link
$settings_link = '' .
__( 'Settings', 'advanced-addons-theme-core-exporter' ) .
'';
// Add link at the first position
array_unshift( $links, $settings_link );
return $links;
}
public function aptce_add_review_row_meta( $plugin_meta, $plugin_file ) {
if ( plugin_basename( __FILE__ ) !== $plugin_file ) {
return $plugin_meta;
}
$review_link = '' .
__( 'Leave a review', 'advanced-addons-theme-core-exporter' ) .
'';
$inserted = false;
foreach ( $plugin_meta as $index => $meta_item ) {
if ( false !== strpos( $meta_item, 'plugin-install.php?tab=plugin-information' ) ) {
array_splice( $plugin_meta, $index + 1, 0, [ $review_link ] );
$inserted = true;
break;
}
}
if ( ! $inserted ) {
$plugin_meta[] = $review_link;
}
return $plugin_meta;
}
public function aptce_render_admin_page() {
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( __( 'Insufficient permissions', 'advanced-addons-theme-core-exporter' ) );
}
// Check ZipArchive
$zip_ok = class_exists( 'ZipArchive' );
?>
isFile() ) {
$size += $file->getSize();
}
}
return $size;
}
/**
* Get directory size with exclusions
*/
protected function aptce_get_directory_size_with_exclusions( $dir, $exclude = [] ) {
if ( ! is_dir( $dir ) ) {
return 0;
}
$size = 0;
$files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $dir, FilesystemIterator::SKIP_DOTS ), RecursiveIteratorIterator::LEAVES_ONLY );
foreach ( $files as $file ) {
if ( $file->isDir() ) continue;
$filePath = $file->getRealPath();
// Check exclusions
$skip = false;
foreach ( $exclude as $ex ) {
if ( empty( $ex ) ) continue;
// if $ex is an absolute path (realpath), compare prefix
if ( realpath( $ex ) && strpos( $filePath, realpath( $ex ) ) === 0 ) {
$skip = true;
break;
}
// if $ex is just a filename like 'wp-config.php'
if ( basename( $filePath ) === $ex ) {
$skip = true;
break;
}
}
if ( $skip ) continue;
if ( $file->isFile() ) {
$size += $file->getSize();
}
}
return $size;
}
/**
* Get database size
*/
protected function aptce_get_database_size() {
global $wpdb;
$size = 0;
$tables = $wpdb->get_results( 'SHOW TABLE STATUS', ARRAY_A );
if ( $tables ) {
foreach ( $tables as $table ) {
if ( isset( $table['Data_length'] ) && isset( $table['Index_length'] ) ) {
$size += $table['Data_length'] + $table['Index_length'];
}
}
}
return $size;
}
/**
* Single plugin/theme download (existing)
*/
public function aptce_handle_export_single() {
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( __( 'Insufficient permissions', 'advanced-addons-theme-core-exporter' ) );
}
// Verify nonce for single export action
$nonce = '';
if ( isset( $_GET['_wpnonce'] ) ) {
$nonce = sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) );
}
if ( empty( $nonce ) || ! wp_verify_nonce( $nonce, 'aptce_export_single' ) ) {
wp_die(
esc_html__( 'Security check failed.', 'advanced-addons-theme-core-exporter' ),
esc_html__( 'Error', 'advanced-addons-theme-core-exporter' ),
array(
'response' => 403,
)
);
}
$type = isset( $_GET['type'] ) ? sanitize_text_field( wp_unslash( $_GET['type'] ) ) : '';
$item = isset( $_GET['item'] ) ? sanitize_text_field( wp_unslash( $_GET['item'] ) ) : '';
if ( ! in_array( $type, ['plugin', 'theme'], true ) || empty( $item ) ) {
wp_safe_redirect( wp_get_referer() ?: admin_url() );
exit;
}
// Get plugin/theme name for filename
$item_name = '';
if ( 'plugin' === $type ) {
if ( ! function_exists( 'get_plugin_data' ) ) {
require_once AATCE_ADMIN_INCLUDES . 'plugin.php';
}
$plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $item );
$item_name = ! empty( $plugin_data['Name'] ) ? $plugin_data['Name'] : dirname( $item );
} elseif ( 'theme' === $type ) {
$theme = wp_get_theme( $item );
$item_name = $theme->get( 'Name' ) ? $theme->get( 'Name' ) : $item;
}
// Sanitize filename (remove special characters, spaces, etc.)
$item_name = sanitize_file_name( $item_name );
// Ensure lowercase and replace any remaining spaces with hyphens
$item_name = strtolower( str_replace( ' ', '-', $item_name ) );
$upload = wp_upload_dir();
// Ensure basedir exists and is writable
$basedir = ! empty( $upload['basedir'] ) ? trailingslashit( wp_normalize_path( $upload['basedir'] ) ) : wp_normalize_path( AATCE_UPLOADS_DIR );
// Create directory if it doesn't exist
if ( ! is_dir( $basedir ) ) {
wp_mkdir_p( $basedir );
}
// Check if directory is writable
if ( ! is_writable( $basedir ) ) {
wp_die( esc_html__( 'Upload directory is not writable. Please check folder permissions.', 'advanced-addons-theme-core-exporter' ) );
}
// Temporary zip file path
$tmp_zip = $basedir . 'aptce-single-' . time() . '.zip';
// Zip filename for download (sanitize for safety)
$zip_filename = sanitize_file_name( $item_name ) . '.zip';
// ✅ Prefer ZipArchive if available
if ( class_exists( 'ZipArchive' ) ) {
$zip = new ZipArchive();
if ( $zip->open( $tmp_zip, ZipArchive::CREATE ) !== TRUE ) {
wp_die( esc_html__( 'Could not create archive', 'advanced-addons-theme-core-exporter' ) );
}
if ( 'plugin' === $type ) {
// Build full plugin path from item (relative path)
$plugin_dir = wp_normalize_path( WP_PLUGIN_DIR . '/' . dirname( $item ) );
if ( is_dir( $plugin_dir ) ) {
$base = basename( $plugin_dir );
$plugin_dir_normalized = wp_normalize_path( rtrim( $plugin_dir, '/\\' ) );
$files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $plugin_dir ), RecursiveIteratorIterator::LEAVES_ONLY );
foreach ( $files as $file ) {
if ( $file->isDir() ) continue;
$filePath = $file->getRealPath();
if ( ! $filePath ) continue;
$filePath_normalized = wp_normalize_path( $filePath );
if ( strpos( $filePath_normalized, $plugin_dir_normalized ) === 0 ) {
$relative = substr( $filePath_normalized, strlen( $plugin_dir_normalized ) );
$relative = ltrim( $relative, '/' );
$relative = str_replace( '\\', '/', $relative );
$zip->addFile( $filePath, $base . '/' . $relative );
}
}
}
} elseif ( 'theme' === $type ) {
$theme_dir = wp_normalize_path( get_theme_root() . '/' . $item );
if ( is_dir( $theme_dir ) ) {
$base = basename( $theme_dir );
$theme_dir_normalized = wp_normalize_path( rtrim( $theme_dir, '/\\' ) );
$files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $theme_dir ), RecursiveIteratorIterator::LEAVES_ONLY );
foreach ( $files as $file ) {
if ( $file->isDir() ) continue;
$filePath = $file->getRealPath();
if ( ! $filePath ) continue;
$filePath_normalized = wp_normalize_path( $filePath );
if ( strpos( $filePath_normalized, $theme_dir_normalized ) === 0 ) {
$relative = substr( $filePath_normalized, strlen( $theme_dir_normalized ) );
$relative = ltrim( $relative, '/' );
$relative = str_replace( '\\', '/', $relative );
$zip->addFile( $filePath, $base . '/' . $relative );
}
}
}
}
$zip->close();
} else {
// ✅ Fallback to WordPress bundled PclZip
if ( ! class_exists( 'PclZip' ) ) {
include_once AATCE_ADMIN_INCLUDES . 'class-pclzip.php';
}
$file_paths = array();
if ( 'plugin' === $type ) {
// Build full plugin path from item (relative path)
$plugin_dir = wp_normalize_path( WP_PLUGIN_DIR . '/' . dirname( $item ) );
if ( is_dir( $plugin_dir ) ) {
$files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $plugin_dir ), RecursiveIteratorIterator::LEAVES_ONLY );
foreach ( $files as $file ) {
if ( $file->isDir() ) continue;
$filePath = $file->getRealPath();
if ( file_exists( $filePath ) ) {
$file_paths[] = $filePath;
}
}
}
} elseif ( 'theme' === $type ) {
$theme_dir = wp_normalize_path( get_theme_root() . '/' . $item );
if ( is_dir( $theme_dir ) ) {
$files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $theme_dir ), RecursiveIteratorIterator::LEAVES_ONLY );
foreach ( $files as $file ) {
if ( $file->isDir() ) continue;
$filePath = $file->getRealPath();
if ( file_exists( $filePath ) ) {
$file_paths[] = $filePath;
}
}
}
}
if ( ! empty( $file_paths ) ) {
$archive = new PclZip( $tmp_zip );
if ( 'plugin' === $type ) {
$plugin_dir = wp_normalize_path( WP_PLUGIN_DIR . '/' . dirname( $item ) );
$archive->create( $file_paths, PCLZIP_OPT_REMOVE_PATH, dirname( $plugin_dir ) );
} else {
$theme_dir = wp_normalize_path( get_theme_root() . '/' . $item );
$archive->create( $file_paths, PCLZIP_OPT_REMOVE_PATH, dirname( $theme_dir ) );
}
}
}
// Verify ZIP file was created successfully
if ( ! file_exists( $tmp_zip ) ) {
wp_die( esc_html__( 'ZIP creation failed11: File was not created. Check directory permissions and available disk space.', 'advanced-addons-theme-core-exporter' ) );
}
if ( filesize( $tmp_zip ) === 0 ) {
@unlink( $tmp_zip );
wp_die( esc_html__( 'ZIP creation failed11: File is empty. The item may contain no files or read permissions are restricted.', 'advanced-addons-theme-core-exporter' ) );
}
if ( is_file( $tmp_zip ) ) {
header( 'Content-Description: File Transfer' );
header( 'Content-Type: application/zip' );
header( 'Content-Disposition: attachment; filename="' . esc_attr( $zip_filename ) . '"' );
header( 'Content-Length: ' . filesize( $tmp_zip ) );
readfile( $tmp_zip );
@unlink( $tmp_zip );
exit;
}
wp_die( __( 'ZIP creation failed11', 'advanced-addons-theme-core-exporter' ) );
}
/**
* Single core download handler (for the Download buttons)
*/
public function aptce_handle_download_core_single() {
// Verify nonce for core download action
$nonce = '';
if ( isset( $_REQUEST['_wpnonce'] ) ) {
$nonce = sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) );
}
if ( empty( $nonce ) || ! wp_verify_nonce( $nonce, 'aptce_download_core' ) ) {
wp_die(
esc_html__( 'Security check failed.', 'advanced-addons-theme-core-exporter' ),
esc_html__( 'Error', 'advanced-addons-theme-core-exporter' ),
array(
'response' => 403,
)
);
}
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( __( 'Insufficient permissions', 'advanced-addons-theme-core-exporter' ) );
}
$type = isset( $_GET['type'] ) ? sanitize_text_field( wp_unslash( $_GET['type'] ) ) : '';
$upload = wp_upload_dir();
switch ( $type ) {
case 'full_100':
// Full WordPress root
$source = ABSPATH; // no realpath()
$zip_name = 'wordpress-full-100-percent-' . date( 'Ymd-His' ) . '.zip';
$exclude = []; // include everything
break;
case 'full':
// Full root except uploads + wp-config
$source = ABSPATH;
$uploads_dir = $upload['basedir'];
$exclude = [
$uploads_dir,
ABSPATH . 'wp-config.php',
];
$zip_name = 'wordpress-core-full-' . date( 'Ymd-His' ) . '.zip';
break;
case 'uploads':
// Only uploads – safe via wp_upload_dir()
$source = $upload['basedir'];
$zip_name = 'wp-uploads-' . date( 'Ymd-His' ) . '.zip';
$exclude = [];
break;
case 'wpcontent':
// wp-content excluding uploads
$wpcontent_dir = WP_CONTENT_DIR;
$uploads_dir = $upload['basedir'];
$source = $wpcontent_dir;
$exclude = [
$uploads_dir,
];
$zip_name = 'wp-content-no-uploads-' . date( 'Ymd-His' ) . '.zip';
break;
case 'admin':
// wp-admin folder properly resolved
$source = trailingslashit( ABSPATH ) . 'wp-admin';
$zip_name = 'wp-admin-' . date( 'Ymd-His' ) . '.zip';
$exclude = [];
break;
case 'includes':
// wp-includes folder properly resolved
$source = trailingslashit( ABSPATH ) . 'wp-includes';
$zip_name = 'wp-includes-' . date( 'Ymd-His' ) . '.zip';
$exclude = [];
break;
default:
wp_die( __( 'Invalid download type', 'advanced-addons-theme-core-exporter' ) );
}
if ( ! $source || ! is_dir( $source ) ) {
wp_die( __( 'Directory not found', 'advanced-addons-theme-core-exporter' ) );
}
$tmp_zip = $upload['basedir'] . '/aptce-core-' . time() . '.zip';
// ✅ Prefer ZipArchive if available
if ( class_exists( 'ZipArchive' ) ) {
$zip = new ZipArchive();
if ( $zip->open( $tmp_zip, ZipArchive::CREATE ) !== TRUE ) {
wp_die( esc_html__( 'Could not create archive', 'advanced-addons-theme-core-exporter' ) );
}
$this->aptce_add_folder_to_zip( $zip, $source, $source, $exclude );
$zip->close();
} else {
// ✅ Fallback to WordPress bundled PclZip
if ( ! class_exists( 'PclZip' ) ) {
include_once AATCE_ADMIN_INCLUDES . 'class-pclzip.php';
}
$file_paths = array();
$files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $source, FilesystemIterator::SKIP_DOTS ), RecursiveIteratorIterator::LEAVES_ONLY );
foreach ( $files as $file ) {
if ( $file->isDir() ) continue;
$filePath = $file->getRealPath();
// Exclude by absolute path or by basename (wp-config.php)
$skip = false;
foreach ( $exclude as $ex ) {
if ( empty( $ex ) ) continue;
// if $ex is an absolute path (realpath), compare prefix
if ( realpath( $ex ) && strpos( $filePath, realpath( $ex ) ) === 0 ) {
$skip = true;
break;
}
// if $ex is just a filename like 'wp-config.php'
if ( basename( $filePath ) === $ex ) {
$skip = true;
break;
}
}
if ( $skip ) continue;
if ( file_exists( $filePath ) ) {
$file_paths[] = $filePath;
}
}
if ( ! empty( $file_paths ) ) {
$archive = new PclZip( $tmp_zip );
$archive->create( $file_paths, PCLZIP_OPT_REMOVE_PATH, dirname( $source ) );
}
}
if ( is_file( $tmp_zip ) ) {
header( 'Content-Description: File Transfer' );
header( 'Content-Type: application/zip' );
header( 'Content-Disposition: attachment; filename="' . $zip_name . '"' );
header( 'Content-Length: ' . filesize( $tmp_zip ) );
readfile( $tmp_zip );
@unlink( $tmp_zip );
exit;
}
wp_die( __( 'ZIP creation failed', 'advanced-addons-theme-core-exporter' ) );
}
/**
* Database download handler
*/
public function aptce_handle_download_database() {
// Verify nonce
$nonce = isset( $_REQUEST['_wpnonce'] ) ? wp_unslash( $_REQUEST['_wpnonce'] ) : '';
if ( ! wp_verify_nonce( $nonce, 'aptce_download_core' ) ) {
wp_die( __( 'Security check failed.', 'advanced-addons-theme-core-exporter' ), 403 );
}
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( __( 'Insufficient permissions.', 'advanced-addons-theme-core-exporter' ) );
}
global $wpdb;
$filename = 'wordpress-database-' . date( 'Ymd-His' ) . '.sql';
$db_name = DB_NAME;
$db_charset = defined( 'DB_CHARSET' ) ? DB_CHARSET : 'utf8mb4';
$nl = "\n";
// Force download headers
nocache_headers();
header( 'Content-Type: application/octet-stream' );
header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
header( 'Content-Transfer-Encoding: binary' );
// SQL Header
echo "-- WordPress Database Dump{$nl}";
echo "-- Generated: " . date( 'Y-m-d H:i:s' ) . "{$nl}";
echo "-- Database: {$db_name}{$nl}";
echo "--{$nl}{$nl}";
echo "SET NAMES {$db_charset};{$nl}";
echo "SET SQL_MODE = \"NO_AUTO_VALUE_ON_ZERO\";{$nl}";
echo "SET time_zone = \"+00:00\";{$nl}{$nl}";
echo "/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;{$nl}";
echo "/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;{$nl}";
echo "/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;{$nl}";
echo "/*!40101 SET NAMES {$db_charset} */;{$nl}{$nl}";
echo "/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;{$nl}";
echo "/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;{$nl}{$nl}";
// Fetch tables
$tables = $wpdb->get_results( 'SHOW TABLES', ARRAY_N );
foreach ( $tables as $table ) {
$table_name = $table[0];
echo "{$nl}--{$nl}-- Table structure for table `{$table_name}`{$nl}--{$nl}{$nl}";
echo "DROP TABLE IF EXISTS `{$table_name}`;{$nl}";
$create_table = $wpdb->get_row( "SHOW CREATE TABLE `{$table_name}`", ARRAY_A );
if ( isset( $create_table['Create Table'] ) ) {
echo rtrim( $create_table['Create Table'], ';' ) . ";{$nl}{$nl}";
}
// Table data
$rows = $wpdb->get_results( "SELECT * FROM `{$table_name}`", ARRAY_A );
if ( empty( $rows ) ) {
continue;
}
echo "{$nl}--{$nl}-- Dumping data for table `{$table_name}`{$nl}--{$nl}{$nl}";
$columns = array_keys( $rows[0] );
$column_list = '`' . implode( '`, `', $columns ) . '`';
$chunk_size = 100;
$total_rows = count( $rows );
for ( $i = 0; $i < $total_rows; $i += $chunk_size ) {
$chunk = array_slice( $rows, $i, $chunk_size );
echo "INSERT INTO `{$table_name}` ({$column_list}) VALUES{$nl}";
$values = [];
foreach ( $chunk as $row ) {
$row_values = [];
foreach ( $row as $value ) {
if ( is_null( $value ) ) {
$row_values[] = 'NULL';
} elseif ( is_numeric( $value ) && ! is_string( $value ) ) {
$row_values[] = $value;
} else {
$escaped = (string) $value;
$escaped = str_replace( "\r\n", "\n", $escaped );
$escaped = str_replace( "\r", "\n", $escaped );
$escaped = str_replace( '\\', '\\\\', $escaped );
$escaped = str_replace( "'", "''", $escaped );
$escaped = str_replace( "\x00", "\\0", $escaped );
$escaped = str_replace( "\x1a", "\\Z", $escaped );
$escaped = str_replace( "\n", "\\n", $escaped );
$row_values[] = "'" . $escaped . "'";
}
}
$values[] = '(' . implode( ', ', $row_values ) . ')';
}
echo implode( ",{$nl}", $values ) . ";{$nl}{$nl}";
}
}
// Footer
echo "{$nl}/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;{$nl}";
echo "/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;{$nl}{$nl}";
echo "--{$nl}-- End of database dump{$nl}--{$nl}";
echo "/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;{$nl}";
echo "/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;{$nl}";
echo "/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;{$nl}";
exit;
}
/**
* Helper: Generate database dump to a file
* Returns the file path on success, false on failure
* Cross-platform compatible (Windows/Linux)
*/
protected function aptce_generate_database_dump_file( $file_path ) {
global $wpdb;
$db_name = DB_NAME;
$db_charset = defined( 'DB_CHARSET' ) ? DB_CHARSET : 'utf8mb4';
// Open file in binary mode for cross-platform compatibility (ensures consistent line endings)
$handle = fopen( $file_path, 'wb' );
if ( ! $handle ) {
return false;
}
// Use LF line endings for cross-platform compatibility (Linux/Unix standard)
$nl = "\n";
// Write SQL header with UTF-8 BOM for better compatibility
fwrite( $handle, "-- WordPress Database Dump{$nl}" );
fwrite( $handle, "-- Generated: " . date( 'Y-m-d H:i:s' ) . "{$nl}" );
fwrite( $handle, "-- Database: " . $db_name . "{$nl}" );
fwrite( $handle, "--{$nl}{$nl}" );
fwrite( $handle, "SET NAMES utf8mb4;{$nl}" );
fwrite( $handle, "SET SQL_MODE = \"NO_AUTO_VALUE_ON_ZERO\";{$nl}" );
fwrite( $handle, "SET time_zone = \"+00:00\";{$nl}{$nl}" );
fwrite( $handle, "/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;{$nl}" );
fwrite( $handle, "/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;{$nl}" );
fwrite( $handle, "/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;{$nl}" );
fwrite( $handle, "/*!40101 SET NAMES " . $db_charset . " */;{$nl}{$nl}" );
// Disable foreign key checks for better import compatibility
fwrite( $handle, "/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;{$nl}" );
fwrite( $handle, "/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;{$nl}{$nl}" );
// Get all tables
$tables = $wpdb->get_results( 'SHOW TABLES', ARRAY_N );
if ( empty( $tables ) ) {
fclose( $handle );
return false;
}
foreach ( $tables as $table ) {
$table_name = $table[0];
// Skip non-existent table
if ( ! $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s", $table_name ) ) ) {
continue;
}
// Table structure
fwrite( $handle, "{$nl}--{$nl}-- Table structure for table `" . $table_name . "`{$nl}--{$nl}{$nl}" );
fwrite( $handle, "DROP TABLE IF EXISTS `" . $table_name . "`;{$nl}" );
$create_table = $wpdb->get_row( "SHOW CREATE TABLE `{$table_name}`", ARRAY_A );
if ( isset( $create_table['Create Table'] ) ) {
// Ensure CREATE TABLE statement ends with semicolon and newline
$create_sql = rtrim( $create_table['Create Table'], " \t\n\r\0\x0B;" ) . ";{$nl}{$nl}";
fwrite( $handle, $create_sql );
}
// Table data
$rows = $wpdb->get_results( "SELECT * FROM `{$table_name}`", ARRAY_A );
if ( ! empty( $rows ) ) {
fwrite( $handle, "{$nl}--{$nl}-- Dumping data for table `" . $table_name . "`{$nl}--{$nl}{$nl}" );
$columns = array_keys( $rows[0] );
$column_list = '`' . implode( '`, `', array_map( 'esc_sql', $columns ) ) . '`';
$chunk_size = 100;
$total_rows = count( $rows );
for ( $i = 0; $i < $total_rows; $i += $chunk_size ) {
$chunk = array_slice( $rows, $i, $chunk_size );
fwrite( $handle, "INSERT INTO `{$table_name}` ({$column_list}) VALUES{$nl}" );
$values = [];
foreach ( $chunk as $row ) {
$row_values = [];
foreach ( $row as $value ) {
if ( is_null( $value ) ) {
$row_values[] = 'NULL';
} else {
// Use MySQL's proper escaping for cross-platform compatibility
if ( is_numeric( $value ) && ! is_string( $value ) ) {
// For numeric values, use them directly without quotes
$row_values[] = $value;
} else {
// For strings, use MySQL standard escaping (works on Windows & Linux)
$value_str = (string) $value;
// Normalize line endings first (before escaping backslashes)
$escaped = str_replace( "\r\n", "\n", $value_str ); // Windows CRLF -> LF
$escaped = str_replace( "\r", "\n", $escaped ); // Old Mac CR -> LF
// Escape backslashes (critical: must be done before other escapes)
$escaped = str_replace( '\\', '\\\\', $escaped );
// Escape single quotes (MySQL standard: double the quote)
$escaped = str_replace( "'", "''", $escaped );
// Handle control characters that can break SQL imports
$escaped = str_replace( "\x00", "\\0", $escaped ); // NULL byte
$escaped = str_replace( "\x1a", "\\Z", $escaped ); // EOF marker
// Escape normalized line endings for SQL
$escaped = str_replace( "\n", "\\n", $escaped ); // Unix LF -> \n
$row_values[] = "'" . $escaped . "'";
}
}
}
$values[] = '(' . implode( ', ', $row_values ) . ')';
}
fwrite( $handle, implode( ",{$nl}", $values ) . ";{$nl}{$nl}" );
}
}
}
// Re-enable foreign key checks
fwrite( $handle, "{$nl}/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;{$nl}" );
fwrite( $handle, "/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;{$nl}{$nl}" );
// SQL footer
fwrite( $handle, "--{$nl}-- End of database dump{$nl}--{$nl}" );
fwrite( $handle, "/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;{$nl}" );
fwrite( $handle, "/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;{$nl}" );
fwrite( $handle, "/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;{$nl}" );
fclose( $handle );
return file_exists( $file_path ) ? $file_path : false;
}
/**
* Helper: add folder recursively to open ZipArchive
* $root_source is used to calculate relative paths correctly
* $exclude is an array of absolute paths (realpath) or filenames to skip
*/
protected function aptce_add_folder_to_zip( $zip, $folder, $root_source, $exclude = [] ) {
$folder = rtrim( $folder, '/\\' );
if ( ! is_dir( $folder ) ) return;
$files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $folder, FilesystemIterator::SKIP_DOTS ), RecursiveIteratorIterator::LEAVES_ONLY );
// Normalize root_source for consistent path comparison
$root_source_normalized = wp_normalize_path( rtrim( $root_source, '/\\' ) );
foreach ( $files as $file ) {
if ( $file->isDir() ) continue;
$filePath = $file->getRealPath();
if ( ! $filePath ) continue;
// Normalize file path for consistent comparison
$filePath_normalized = wp_normalize_path( $filePath );
// Exclude by absolute path or by basename (wp-config.php)
$skip = false;
foreach ( $exclude as $ex ) {
if ( empty( $ex ) ) continue;
// if $ex is an absolute path (realpath), compare prefix
$ex_path = realpath( $ex );
if ( $ex_path && strpos( $filePath_normalized, wp_normalize_path( $ex_path ) ) === 0 ) {
$skip = true;
break;
}
// if $ex is just a filename like 'wp-config.php'
if ( basename( $filePath ) === $ex ) {
$skip = true;
break;
}
}
if ( $skip ) continue;
// Calculate relative path using normalized paths
if ( strpos( $filePath_normalized, $root_source_normalized ) === 0 ) {
$localPath = substr( $filePath_normalized, strlen( $root_source_normalized ) );
// Remove leading slash if present
$localPath = ltrim( $localPath, '/' );
// Ensure forward slashes for ZIP compatibility
$localPath = str_replace( '\\', '/', $localPath );
$zip->addFile( $filePath, $localPath );
}
}
}
/**
* Bulk export handler (form submit)
*/
public function aptce_handle_export() {
if ( empty( $_POST ) ) {
wp_safe_redirect( wp_get_referer() ?: admin_url() );
exit;
}
// Verify POST nonce for export action
if ( empty( $_POST['aptce_nonce'] ) ) {
wp_die(
esc_html__( 'Security check failed: nonce missing.', 'advanced-addons-theme-core-exporter' ),
esc_html__( 'Error', 'advanced-addons-theme-core-exporter' ),
array(
'response' => 403,
)
);
}
$nonce = sanitize_text_field( wp_unslash( $_POST['aptce_nonce'] ) );
if ( ! wp_verify_nonce( $nonce, 'aptce_export' ) ) {
wp_die(
esc_html__( 'Security check failed: invalid nonce.', 'advanced-addons-theme-core-exporter' ),
esc_html__( 'Error', 'advanced-addons-theme-core-exporter' ),
array(
'response' => 403,
)
);
}
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( __( 'Insufficient permissions', 'advanced-addons-theme-core-exporter' ) );
}
$files_to_add = [];
$temp_files = [];
// Plugins selected
$plugins = isset( $_POST['aptce_plugins'] ) && is_array( $_POST['aptce_plugins'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['aptce_plugins'] ) ) : [];
if ( $plugins ) {
if ( is_admin() && ! function_exists( 'is_plugin_active' ) ) {
include_once AATCE_ADMIN_INCLUDES . 'plugin.php';
}
foreach ( $plugins as $plugin_path ) {
// Build full plugin path from relative path
$plugin_dir = wp_normalize_path( WP_PLUGIN_DIR . '/' . dirname( $plugin_path ) );
if ( is_dir( $plugin_dir ) ) {
$files_to_add[] = realpath( $plugin_dir );
}
}
}
// Themes selected
$themes = isset( $_POST['aptce_themes'] ) && is_array( $_POST['aptce_themes'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['aptce_themes'] ) ) : [];
if ( $themes ) {
foreach ( $themes as $slug ) {
$theme_dir = get_theme_root() . '/' . $slug;
if ( is_dir( $theme_dir ) ) {
$files_to_add[] = realpath( $theme_dir );
}
}
}
// Core selections (if user checked the "Export selected WordPress core options" box)
$export_core = isset( $_POST['aptce_export_core'] ) && '1' == $_POST['aptce_export_core'];
if ( $export_core ) {
// For each core checkbox, add a special marker or real path
if ( isset( $_POST['aptce_core_full'] ) && '1' == $_POST['aptce_core_full'] ) {
// Full core -> mark as root|core (we treat as special)
$root_path = trailingslashit( realpath( ABSPATH ) );
if ( $root_path ) {
$files_to_add[] = $root_path . '|core';
}
}
if ( isset( $_POST['aptce_core_uploads'] ) && '1' == $_POST['aptce_core_uploads'] ) {
$upload_info = wp_upload_dir();
$uploads_dir = isset( $upload_info['basedir'] ) ? $upload_info['basedir'] : '';
if ( ! empty( $uploads_dir ) && is_dir( $uploads_dir ) ) {
$files_to_add[] = trailingslashit( $uploads_dir );
}
}
if ( isset( $_POST['aptce_core_wpcontent'] ) && '1' == $_POST['aptce_core_wpcontent'] ) {
$wpcontent_dir = wp_normalize_path( WP_CONTENT_DIR );
if ( ! empty( $wpcontent_dir ) && is_dir( $wpcontent_dir ) ) {
$files_to_add[] = array(
'path' => trailingslashit( $wpcontent_dir ),
'type' => 'wpcontent_no_uploads',
'exclude' => array( wp_normalize_path( AATCE_UPLOADS_DIR ) ),
);
}
}
if ( isset( $_POST['aptce_core_admin'] ) && '1' == $_POST['aptce_core_admin'] ) {
$admin_dir = wp_normalize_path( AATCE_ADMIN );
if ( ! empty( $admin_dir ) && is_dir( $admin_dir ) ) {
$files_to_add[] = array(
'path' => trailingslashit( $admin_dir ),
'type' => 'admin',
);
}
}
if ( isset( $_POST['aptce_core_includes'] ) && '1' == $_POST['aptce_core_includes'] ) {
$includes_dir = wp_normalize_path( ABSPATH . 'wp-includes' );
if ( ! empty( $includes_dir ) && is_dir( $includes_dir ) ) {
$files_to_add[] = array(
'path' => trailingslashit( $includes_dir ),
'type' => 'includes',
);
}
}
if ( isset( $_POST['aptce_core_full_100'] ) && '1' == $_POST['aptce_core_full_100'] ) {
//$root_dir = wp_normalize_path( ABSPATH );
$root_dir = wp_normalize_path( trailingslashit( ABSPATH ) );
if ( ! empty( $root_dir ) && is_dir( $root_dir ) ) {
$files_to_add[] = array(
'path' => trailingslashit( $root_dir ),
'type' => 'core_100', // Full WordPress export (no exclusions)
);
}
}
}
// Remote repo download by slug (optional)
$remote_slug = isset( $_POST['aptce_remote_slug'] ) ? sanitize_text_field( wp_unslash( $_POST['aptce_remote_slug'] ) ) : '';
$remote_type = isset( $_POST['aptce_remote_type'] ) ? sanitize_text_field( wp_unslash( $_POST['aptce_remote_type'] ) ) : '';
if ( $remote_slug && in_array( $remote_type, ['plugin', 'theme'], true ) ) {
$zip_url = '';
if ( 'plugin' === $remote_type ) {
$zip_url = 'https://downloads.wordpress.org/plugin/' . rawurlencode( $remote_slug ) . '.zip';
} else {
$zip_url = 'https://downloads.wordpress.org/theme/' . rawurlencode( $remote_slug ) . '.zip';
}
$response = wp_remote_get( $zip_url, [ 'timeout' => 30 ] );
if ( ! is_wp_error( $response ) && 200 === wp_remote_retrieve_response_code( $response ) ) {
$body = wp_remote_retrieve_body( $response );
if ( $body ) {
$tmp = wp_tempnam( $zip_url );
file_put_contents( $tmp, $body );
$temp_files[] = $tmp;
}
}
}
// Database export (if checkbox is checked)
$database_file = null;
if ( isset( $_POST['aptce_download_database'] ) && '1' == $_POST['aptce_download_database'] ) {
$upload = wp_upload_dir();
$db_file_path = $upload['basedir'] . '/aptce-database-' . time() . '.sql';
$database_file = $this->aptce_generate_database_dump_file( $db_file_path );
if ( $database_file ) {
$temp_files[] = $database_file;
}
}
if ( empty( $files_to_add ) && empty( $temp_files ) ) {
wp_safe_redirect( wp_get_referer() ?: admin_url() );
exit;
}
$upload = wp_upload_dir();
$tmp_zip = $upload['basedir'] . '/aptce-export-' . time() . '.zip';
// ✅ Prefer ZipArchive if available
if ( class_exists( 'ZipArchive' ) ) {
$zip = new ZipArchive();
if ( $zip->open( $tmp_zip, ZipArchive::CREATE ) !== TRUE ) {
wp_die( esc_html__( 'Could not create archive', 'advanced-addons-theme-core-exporter' ) );
}
// Track added files to prevent duplicates
$added_files = array();
// Add items to main ZIP
foreach ( $files_to_add as $item ) {
// Handle array-based items (with type and exclude info)
if ( is_array( $item ) ) {
$item_path = isset( $item['path'] ) ? $item['path'] : '';
$item_type = isset( $item['type'] ) ? $item['type'] : '';
$item_exclude = isset( $item['exclude'] ) ? (array) $item['exclude'] : [];
if ( empty( $item_path ) ) {
continue;
}
// Handle different types
if ( 'core_100' === $item_type ) {
// Full core with no exclusions
$root = AATCE_ROOT_PATH;
if ( $root ) {
$root_normalized = wp_normalize_path( rtrim( $root, '/\\' ) );
$iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $root, FilesystemIterator::SKIP_DOTS ), RecursiveIteratorIterator::LEAVES_ONLY );
foreach ( $iterator as $file ) {
if ( $file->isDir() ) continue;
$filePath = $file->getRealPath();
if ( ! $filePath ) continue;
$filePath_normalized = wp_normalize_path( $filePath );
if ( strpos( $filePath_normalized, $root_normalized ) === 0 ) {
$localPath = substr( $filePath_normalized, strlen( $root_normalized ) );
$localPath = ltrim( $localPath, '/' );
$localPath = str_replace( '\\', '/', $localPath );
if ( ! isset( $added_files[ $localPath ] ) ) {
$zip->addFile( $filePath, $localPath );
$added_files[ $localPath ] = true;
}
}
}
}
} elseif ( 'wpcontent_no_uploads' === $item_type ) {
// wp-content excluding uploads
$base_path = realpath( $item_path );
if ( $base_path ) {
$files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $base_path, FilesystemIterator::SKIP_DOTS ), RecursiveIteratorIterator::LEAVES_ONLY );
foreach ( $files as $file ) {
if ( $file->isDir() ) continue;
$filePath = $file->getRealPath();
// Check exclusions
$skip = false;
foreach ( $item_exclude as $exclude_path ) {
if ( realpath( $exclude_path ) && strpos( $filePath, realpath( $exclude_path ) ) === 0 ) {
$skip = true;
break;
}
}
if ( $skip ) continue;
$base_path_normalized = wp_normalize_path( rtrim( $base_path, '/\\' ) );
$filePath_normalized = wp_normalize_path( $filePath );
if ( strpos( $filePath_normalized, $base_path_normalized ) === 0 ) {
$relative = substr( $filePath_normalized, strlen( $base_path_normalized ) );
$relative = ltrim( $relative, '/' );
$localPath = 'wp-content/' . str_replace( '\\', '/', $relative );
} else {
continue;
}
if ( ! isset( $added_files[ $localPath ] ) ) {
$zip->addFile( $filePath, $localPath );
$added_files[ $localPath ] = true;
}
}
}
} elseif ( 'admin' === $item_type || 'includes' === $item_type ) {
// Admin or includes directory
$dir_path = realpath( $item_path );
if ( $dir_path ) {
$base = basename( $dir_path );
$files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $dir_path, FilesystemIterator::SKIP_DOTS ), RecursiveIteratorIterator::LEAVES_ONLY );
foreach ( $files as $file ) {
if ( $file->isDir() ) continue;
$filePath = $file->getRealPath();
if ( ! $filePath ) continue;
$dir_path_normalized = wp_normalize_path( rtrim( $dir_path, '/\\' ) );
$filePath_normalized = wp_normalize_path( $filePath );
if ( strpos( $filePath_normalized, $dir_path_normalized ) === 0 ) {
$relative = substr( $filePath_normalized, strlen( $dir_path_normalized ) );
$relative = ltrim( $relative, '/' );
$localPath = $base . '/' . str_replace( '\\', '/', $relative );
} else {
continue;
}
if ( ! isset( $added_files[ $localPath ] ) ) {
$zip->addFile( $filePath, $localPath );
$added_files[ $localPath ] = true;
}
}
}
}
continue;
}
// Handle string-based items
if ( ! is_string( $item ) ) {
continue;
}
// core 100% special handling - include everything, no exclusions
if ( false !== strpos( $item, '|core_100' ) ) {
$root = AATCE_ROOT_PATH;
if ( $root ) {
$root_normalized = wp_normalize_path( rtrim( $root, '/\\' ) );
$iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $root, FilesystemIterator::SKIP_DOTS ), RecursiveIteratorIterator::LEAVES_ONLY );
foreach ( $iterator as $file ) {
if ( $file->isDir() ) continue;
$filePath = $file->getRealPath();
if ( ! $filePath ) continue;
$filePath_normalized = wp_normalize_path( $filePath );
if ( strpos( $filePath_normalized, $root_normalized ) === 0 ) {
$localPath = substr( $filePath_normalized, strlen( $root_normalized ) );
$localPath = ltrim( $localPath, '/' );
$localPath = str_replace( '\\', '/', $localPath );
// Check for duplicates
if ( ! isset( $added_files[ $localPath ] ) ) {
$zip->addFile( $filePath, $localPath );
$added_files[ $localPath ] = true;
}
}
}
}
continue;
}
// core special handling (excludes uploads and wp-config.php)
if ( false !== strpos( $item, '|core' ) ) {
$root = AATCE_ROOT_PATH;
if ( $root ) {
$iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $root, FilesystemIterator::SKIP_DOTS ), RecursiveIteratorIterator::LEAVES_ONLY );
foreach ( $iterator as $file ) {
if ( $file->isDir() ) continue;
$filePath = $file->getRealPath();
// exclude uploads
//if ( 0 === strpos( $filePath, realpath( WP_CONTENT_DIR . '/uploads' ) ) ) continue;
$uploads = wp_upload_dir();
$uploads_dir = wp_normalize_path( $uploads['basedir'] );
if ( 0 === strpos( wp_normalize_path( $filePath ), $uploads_dir ) ) {
continue;
}
// exclude wp-config.php
if ( basename( $filePath ) === 'wp-config.php' ) continue;
$root_normalized = wp_normalize_path( rtrim( $root, '/\\' ) );
$filePath_normalized = wp_normalize_path( $filePath );
if ( strpos( $filePath_normalized, $root_normalized ) === 0 ) {
$localPath = substr( $filePath_normalized, strlen( $root_normalized ) );
$localPath = ltrim( $localPath, '/' );
$localPath = str_replace( '\\', '/', $localPath );
// Check for duplicates
if ( ! isset( $added_files[ $localPath ] ) ) {
$zip->addFile( $filePath, $localPath );
$added_files[ $localPath ] = true;
}
}
}
}
continue;
}
if ( false !== strpos( $item, '|wpcontent_no_uploads' ) ) {
$base_path = realpath( WP_CONTENT_DIR );
if ( $base_path ) {
$files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $base_path, FilesystemIterator::SKIP_DOTS ), RecursiveIteratorIterator::LEAVES_ONLY );
foreach ( $files as $file ) {
if ( $file->isDir() ) continue;
$filePath = $file->getRealPath();
//if ( 0 === strpos( $filePath, realpath( WP_CONTENT_DIR . '/uploads' ) ) ) continue;
$uploads = wp_upload_dir();
$uploads_dir = wp_normalize_path( $uploads['basedir'] );
if ( 0 === strpos( wp_normalize_path( $filePath ), $uploads_dir ) ) {
continue;
}
$base_path_normalized = wp_normalize_path( rtrim( $base_path, '/\\' ) );
$filePath_normalized = wp_normalize_path( $filePath );
if ( strpos( $filePath_normalized, $base_path_normalized ) === 0 ) {
$relative = substr( $filePath_normalized, strlen( $base_path_normalized ) );
$relative = ltrim( $relative, '/' );
$localPath = 'wp-content/' . str_replace( '\\', '/', $relative );
} else {
continue;
}
// Check for duplicates
if ( ! isset( $added_files[ $localPath ] ) ) {
$zip->addFile( $filePath, $localPath );
$added_files[ $localPath ] = true;
}
}
}
continue;
}
// regular directory (plugins, themes, etc.)
if ( is_dir( $item ) ) {
$item_realpath = realpath( $item );
if ( $item_realpath ) {
$base = basename( $item_realpath );
$files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $item_realpath, FilesystemIterator::SKIP_DOTS ), RecursiveIteratorIterator::LEAVES_ONLY );
foreach ( $files as $file ) {
if ( $file->isDir() ) continue;
$filePath = $file->getRealPath();
if ( ! $filePath ) continue;
$item_realpath_normalized = wp_normalize_path( rtrim( $item_realpath, '/\\' ) );
$filePath_normalized = wp_normalize_path( $filePath );
if ( strpos( $filePath_normalized, $item_realpath_normalized ) === 0 ) {
$relative = substr( $filePath_normalized, strlen( $item_realpath_normalized ) );
$relative = ltrim( $relative, '/' );
$localPath = $base . '/' . str_replace( '\\', '/', $relative );
} else {
continue;
}
// Check for duplicates
if ( ! isset( $added_files[ $localPath ] ) ) {
$zip->addFile( $filePath, $localPath );
$added_files[ $localPath ] = true;
}
}
}
}
}
// add any temp files (database or remote zips)
foreach ( $temp_files as $tf ) {
if ( is_file( $tf ) ) {
// Check if it's a database file
if ( false !== strpos( $tf, 'aptce-database' ) ) {
$zip->addFile( $tf, 'wordpress-database-' . date( 'Ymd-His' ) . '.sql' );
} else {
// Remote zips go in 'remote' folder
$zip->addFile( $tf, 'remote/' . basename( $tf ) );
}
}
}
$zip->close();
} else {
// ✅ Fallback to WordPress bundled PclZip
if ( ! class_exists( 'PclZip' ) ) {
include_once AATCE_ADMIN_INCLUDES . 'class-pclzip.php';
}
$archive = new PclZip( $tmp_zip );
$added_files = array();
// Add items to main ZIP
foreach ( $files_to_add as $item ) {
// Handle array-based items (with type and exclude info)
if ( is_array( $item ) ) {
$item_path = isset( $item['path'] ) ? $item['path'] : '';
$item_type = isset( $item['type'] ) ? $item['type'] : '';
$item_exclude = isset( $item['exclude'] ) ? (array) $item['exclude'] : [];
if ( empty( $item_path ) ) {
continue;
}
// Handle different types
if ( 'core_100' === $item_type ) {
// Full core with no exclusions
$root = AATCE_ROOT_PATH;
if ( $root ) {
$archive->add( $root, PCLZIP_OPT_REMOVE_PATH, dirname( $root ) );
}
} elseif ( 'wpcontent_no_uploads' === $item_type ) {
// wp-content excluding uploads
$base_path = realpath( $item_path );
if ( $base_path ) {
$files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $base_path, FilesystemIterator::SKIP_DOTS ), RecursiveIteratorIterator::LEAVES_ONLY );
$file_list = array();
foreach ( $files as $file ) {
if ( $file->isDir() ) continue;
$filePath = $file->getRealPath();
// Check exclusions
$skip = false;
foreach ( $item_exclude as $exclude_path ) {
if ( realpath( $exclude_path ) && strpos( $filePath, realpath( $exclude_path ) ) === 0 ) {
$skip = true;
break;
}
}
if ( $skip ) continue;
if ( file_exists( $filePath ) ) {
$file_list[] = $filePath;
}
}
if ( ! empty( $file_list ) ) {
$archive->add( $file_list, PCLZIP_OPT_REMOVE_PATH, dirname( $base_path ) );
}
}
} elseif ( 'admin' === $item_type || 'includes' === $item_type ) {
// Admin or includes directory
$dir_path = realpath( $item_path );
if ( $dir_path ) {
$archive->add( $dir_path, PCLZIP_OPT_REMOVE_PATH, dirname( $dir_path ) );
}
}
continue;
}
// Handle string-based items
if ( ! is_string( $item ) ) {
continue;
}
// core 100% special handling - include everything, no exclusions
if ( false !== strpos( $item, '|core_100' ) ) {
$root = AATCE_ROOT_PATH;
if ( $root ) {
$archive->add( $root, PCLZIP_OPT_REMOVE_PATH, dirname( $root ) );
}
continue;
}
// core special handling (excludes uploads and wp-config.php)
if ( false !== strpos( $item, '|core' ) ) {
$root = AATCE_ROOT_PATH;
if ( $root ) {
$files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $root, FilesystemIterator::SKIP_DOTS ), RecursiveIteratorIterator::LEAVES_ONLY );
$file_list = array();
foreach ( $files as $file ) {
if ( $file->isDir() ) continue;
$filePath = $file->getRealPath();
// exclude uploads
//if ( 0 === strpos( $filePath, realpath( WP_CONTENT_DIR . '/uploads' ) ) ) continue;
$uploads = wp_upload_dir();
$uploads_dir = wp_normalize_path( $uploads['basedir'] );
if ( 0 === strpos( wp_normalize_path( $filePath ), $uploads_dir ) ) {
continue;
}
// exclude wp-config.php
if ( basename( $filePath ) === 'wp-config.php' ) continue;
if ( file_exists( $filePath ) ) {
$file_list[] = $filePath;
}
}
if ( ! empty( $file_list ) ) {
$archive->add( $file_list, PCLZIP_OPT_REMOVE_PATH, dirname( $root ) );
}
}
continue;
}
if ( false !== strpos( $item, '|wpcontent_no_uploads' ) ) {
$base_path = realpath( WP_CONTENT_DIR );
if ( $base_path ) {
$files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $base_path, FilesystemIterator::SKIP_DOTS ), RecursiveIteratorIterator::LEAVES_ONLY );
$file_list = array();
foreach ( $files as $file ) {
if ( $file->isDir() ) continue;
$filePath = $file->getRealPath();
//if ( 0 === strpos( $filePath, realpath( WP_CONTENT_DIR . '/uploads' ) ) ) continue;
$uploads = wp_upload_dir();
$uploads_dir = wp_normalize_path( $uploads['basedir'] );
if ( 0 === strpos( wp_normalize_path( $filePath ), $uploads_dir ) ) {
continue;
}
if ( file_exists( $filePath ) ) {
$file_list[] = $filePath;
}
}
if ( ! empty( $file_list ) ) {
$archive->add( $file_list, PCLZIP_OPT_REMOVE_PATH, dirname( $base_path ) );
}
}
continue;
}
// regular directory (plugins, themes, etc.)
if ( is_dir( $item ) ) {
$item_realpath = realpath( $item );
if ( $item_realpath ) {
// For plugins/themes, preserve the folder structure by removing parent directory
$parent_dir = dirname( $item_realpath );
$archive->add( $item_realpath, PCLZIP_OPT_REMOVE_PATH, $parent_dir );
}
}
}
// add any temp files (database or remote zips)
foreach ( $temp_files as $tf ) {
if ( is_file( $tf ) && file_exists( $tf ) ) {
// Check if it's a database file
if ( false !== strpos( $tf, 'aptce-database' ) ) {
// Create temp file with proper name for PclZip
$db_filename = 'wordpress-database-' . date( 'Ymd-His' ) . '.sql';
$temp_db_file = dirname( $tf ) . '/' . $db_filename;
if ( copy( $tf, $temp_db_file ) ) {
$archive->add( $temp_db_file, PCLZIP_OPT_REMOVE_PATH, dirname( $temp_db_file ) );
// Clean up temp file after adding
@unlink( $temp_db_file );
}
} else {
// Remote zips go in 'remote' folder
$archive->add( $tf, PCLZIP_OPT_ADD_PATH, 'remote' );
}
}
}
}
if ( is_file( $tmp_zip ) ) {
header( 'Content-Description: File Transfer' );
header( 'Content-Type: application/zip' );
header( 'Content-Disposition: attachment; filename="' . basename( $tmp_zip ) . '"' );
header( 'Content-Length: ' . filesize( $tmp_zip ) );
readfile( $tmp_zip );
@unlink( $tmp_zip );
foreach ( $temp_files as $f ) {
@unlink( $f );
}
exit;
}
wp_die( __( 'ZIP creation failed', 'advanced-addons-theme-core-exporter' ) );
}
/**
* Add download link to plugin action links
*/
function aptce_add_plugin_download_link( $actions, $plugin_file ) {
if ( ! current_user_can( 'manage_options' ) ) {
return $actions;
}
// Ensure get_plugins() is loaded
if ( ! function_exists( 'get_plugins' ) ) {
require_once AATCE_ADMIN_INCLUDES . 'plugin.php';
}
$all_plugins = get_plugins();
if ( ! isset( $all_plugins[ $plugin_file ] ) ) {
return $actions; // plugin not found
}
// Generate download URL
$download_url = wp_nonce_url(
admin_url( 'admin-post.php?action=aptce_export_single&type=plugin&item=' . rawurlencode( $plugin_file ) ),
'aptce_export_single'
);
// Build download link
$download_link = '' . esc_html__( 'Download', 'advanced-addons-theme-core-exporter' ) . '';
// Insert the download link at the beginning of action links
$actions = array_merge( [ 'aptce_download' => $download_link ], $actions );
return $actions;
}
/**
* Add download link to theme action links
*/
public function aptce_add_theme_download_link( $actions, $theme, $context = 'all' ) {
// Check permissions
if ( ! current_user_can( 'manage_options' ) ) {
return $actions;
}
// Ensure $actions is an array
if ( ! is_array( $actions ) ) {
$actions = array();
}
// Ensure $theme is a WP_Theme object
if ( ! is_a( $theme, 'WP_Theme' ) ) {
return $actions;
}
// Get theme slug
$theme_slug = $theme->get_stylesheet();
if ( empty( $theme_slug ) ) {
return $actions;
}
$theme_dir = get_theme_root() . '/' . $theme_slug;
if ( ! is_dir( $theme_dir ) ) {
return $actions;
}
$download_url = wp_nonce_url(
admin_url( 'admin-post.php?action=aptce_export_single&type=theme&item=' . rawurlencode( $theme_slug ) ),
'aptce_export_single'
);
$download_link = '' . esc_html__( 'Download', 'advanced-addons-theme-core-exporter' ) . '';
// Add download link to actions array
// Use array_merge to preserve existing actions and add ours at the beginning
$actions = array_merge( array( 'aptce_download' => $download_link ), $actions );
return $actions;
}
/**
* Add download link to themes prepared for JavaScript (wp_prepare_themes_for_js filter)
*/
public function aptce_prepare_themes_for_js( $themes ) {
// Check permissions
if ( ! current_user_can( 'manage_options' ) ) {
return $themes;
}
if ( ! is_array( $themes ) ) {
return $themes;
}
foreach ( $themes as &$theme ) {
if ( empty( $theme['stylesheet'] ) ) continue;
$slug = $theme['stylesheet'];
// Generate export link
$download_url = wp_nonce_url(
admin_url( 'admin-post.php?action=aptce_export_single&type=theme&item=' . rawurlencode( $slug ) ),
'aptce_export_single'
);
// Attach to REST API response
$theme['aptce_download'] = esc_url( $download_url );
}
return $themes;
}
/**
* Download theme handler
*/
public function aptce_download_theme() {
// ---- Required params check ----
if ( ! isset( $_GET['slug'], $_GET['_wpnonce'] ) ) {
wp_die(
__( 'Invalid request.', 'advanced-addons-theme-core-exporter' ),
__( 'Error', 'advanced-addons-theme-core-exporter' ),
array( 'response' => 400 )
);
}
// ---- Sanitize & validate slug FIRST ----
$slug = sanitize_key( wp_unslash( $_GET['slug'] ) );
if ( empty( $slug ) ) {
wp_die(
__( 'Invalid theme slug.', 'advanced-addons-theme-core-exporter' ),
__( 'Error', 'advanced-addons-theme-core-exporter' ),
array( 'response' => 400 )
);
}
// ---- Sanitize nonce ----
$nonce = sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) );
// ---- Construct & verify nonce ----
$nonce_action = 'aptce_download_' . $slug;
if ( ! wp_verify_nonce( $nonce, $nonce_action ) ) {
wp_die(
__( 'Security check failed (invalid nonce).', 'advanced-addons-theme-core-exporter' ),
__( 'Error', 'advanced-addons-theme-core-exporter' ),
array( 'response' => 403 )
);
}
// ---- Capability check ----
if ( ! current_user_can( 'manage_options' ) ) {
wp_die(
__( 'You do not have permission to download themes.', 'advanced-addons-theme-core-exporter' ),
__( 'Error', 'advanced-addons-theme-core-exporter' ),
array( 'response' => 403 )
);
}
// ---- Validate theme directory ----
$theme_dir = trailingslashit( get_theme_root() ) . $slug;
if ( ! is_dir( $theme_dir ) ) {
wp_die(
__( 'Theme directory not found.', 'advanced-addons-theme-core-exporter' ),
__( 'Error', 'advanced-addons-theme-core-exporter' ),
array( 'response' => 404 )
);
}
// ---- Temp ZIP directory safe fallback ----
$temp_dir = wp_normalize_path( sys_get_temp_dir() );
if ( ! is_writable( $temp_dir ) ) {
$upload = wp_upload_dir();
$temp_dir = wp_normalize_path( $upload['basedir'] );
}
if ( ! is_dir( $temp_dir ) ) {
wp_mkdir_p( $temp_dir );
}
$zip_path = $temp_dir . '/aptce_' . time() . '_' . wp_generate_password( 8, false ) . '.zip';
/**
* =================================================
* 1. TRY ZipArchive FIRST
* =================================================
*/
if ( class_exists( 'ZipArchive' ) ) {
$zip = new ZipArchive();
if ( $zip->open( $zip_path, ZipArchive::CREATE ) === true ) {
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator( $theme_dir, RecursiveDirectoryIterator::SKIP_DOTS ),
RecursiveIteratorIterator::SELF_FIRST
);
$theme_dir_normalized = wp_normalize_path( rtrim( $theme_dir, '/\\' ) );
foreach ( $files as $file ) {
$real = $file->getRealPath();
if ( ! $real ) continue;
$real_normalized = wp_normalize_path( $real );
if ( strpos( $real_normalized, $theme_dir_normalized ) === 0 ) {
$local = substr( $real_normalized, strlen( $theme_dir_normalized ) );
$local = ltrim( $local, '/' );
$local = str_replace( '\\', '/', $local );
if ( $file->isDir() ) {
$zip->addEmptyDir( $local );
} else {
$zip->addFile( $real, $local );
}
}
}
$zip->close();
} else {
wp_die( __( 'Failed to create ZIP using ZipArchive.', 'advanced-addons-theme-core-exporter' ) );
}
} else {
/**
* =================================================
* 2. FALLBACK TO PclZip
* =================================================
*/
if ( ! class_exists( 'PclZip' ) ) {
$pclzip_path = AATCE_ADMIN_INCLUDES . 'class-pclzip.php';
if ( file_exists( $pclzip_path ) ) {
include_once $pclzip_path;
} else {
wp_die( __( 'Neither ZipArchive nor PclZip are available on this server.', 'advanced-addons-theme-core-exporter' ) );
}
}
$archive = new PclZip( $zip_path );
$result = $archive->create(
$theme_dir,
PCLZIP_OPT_REMOVE_PATH,
dirname( $theme_dir )
);
if ( ! $result ) {
wp_die(
esc_html__( 'PclZip failed: ', 'advanced-addons-theme-core-exporter' ) .
esc_html( $archive->errorInfo( true ) )
);
}
}
// ---- Send ZIP ----
if ( ! file_exists( $zip_path ) || filesize( $zip_path ) === 0 ) {
wp_die( __( 'ZIP file creation failed.', 'advanced-addons-theme-core-exporter' ) );
}
header( 'Content-Type: application/zip' );
header( 'Content-Disposition: attachment; filename="' . $slug . '.zip"' );
header( 'Content-Length: ' . filesize( $zip_path ) );
readfile( $zip_path );
unlink( $zip_path );
exit;
}
/**
* AJAX handler for plugin download
*/
public function aptce_ajax_download_plugin() {
check_ajax_referer( 'aptce_export', 'nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( [ 'message' => __( 'Insufficient permissions', 'advanced-addons-theme-core-exporter' ) ] );
}
$plugin_path = isset( $_POST['plugin'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin'] ) ) : '';
if ( empty( $plugin_path ) ) {
wp_send_json_error( [ 'message' => __( 'Invalid plugin', 'advanced-addons-theme-core-exporter' ) ] );
}
// Create the zip file
$result = $this->aptce_create_plugin_zip( $plugin_path );
if ( $result['success'] ) {
wp_send_json_success( [
'file' => $result['file'],
'url' => $result['url'],
'filename' => $result['filename']
] );
} else {
wp_send_json_error( [ 'message' => $result['message'] ] );
}
}
/**
* AJAX handler for theme download
*/
public function aptce_ajax_download_theme() {
check_ajax_referer( 'aptce_export', 'nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( [ 'message' => __( 'Insufficient permissions', 'advanced-addons-theme-core-exporter' ) ] );
}
$theme_slug = isset( $_POST['theme'] ) ? sanitize_text_field( wp_unslash( $_POST['theme'] ) ) : '';
if ( empty( $theme_slug ) ) {
wp_send_json_error( [ 'message' => __( 'Invalid theme', 'advanced-addons-theme-core-exporter' ) ] );
}
// Create the zip file
$result = $this->aptce_create_theme_zip( $theme_slug );
if ( $result['success'] ) {
wp_send_json_success( [
'file' => $result['file'],
'url' => $result['url'],
'filename' => $result['filename']
] );
} else {
wp_send_json_error( [ 'message' => $result['message'] ] );
}
}
/**
* AJAX handler for core files download
*/
public function aptce_ajax_download_core() {
check_ajax_referer( 'aptce_export', 'nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( [ 'message' => __( 'Insufficient permissions', 'advanced-addons-theme-core-exporter' ) ] );
}
$type = isset( $_POST['type'] ) ? sanitize_text_field( wp_unslash( $_POST['type'] ) ) : '';
if ( empty( $type ) ) {
wp_send_json_error( [ 'message' => __( 'Invalid type', 'advanced-addons-theme-core-exporter' ) ] );
}
// Create the zip file
$result = $this->aptce_create_core_zip( $type );
if ( $result['success'] ) {
wp_send_json_success( [
'file' => $result['file'],
'url' => $result['url'],
'filename' => $result['filename']
] );
} else {
wp_send_json_error( [ 'message' => $result['message'] ] );
}
}
/**
* AJAX handler for database download
*/
public function aptce_ajax_download_database() {
check_ajax_referer( 'aptce_export', 'nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( [ 'message' => __( 'Insufficient permissions', 'advanced-addons-theme-core-exporter' ) ] );
}
// Create the database dump file
$result = $this->aptce_create_database_dump();
if ( $result['success'] ) {
wp_send_json_success( [
'file' => $result['file'],
'url' => $result['url'],
'filename' => $result['filename']
] );
} else {
wp_send_json_error( [ 'message' => $result['message'] ] );
}
}
/**
* Helper: Create plugin zip
*/
protected function aptce_create_plugin_zip( $plugin_path ) {
if ( ! function_exists( 'get_plugin_data' ) ) {
require_once AATCE_ADMIN_INCLUDES . 'plugin.php';
}
$plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin_path );
$item_name = ! empty( $plugin_data['Name'] ) ? $plugin_data['Name'] : dirname( $plugin_path );
$item_name = sanitize_file_name( strtolower( str_replace( ' ', '-', $item_name ) ) );
$upload = wp_upload_dir();
$basedir = trailingslashit( wp_normalize_path( $upload['basedir'] ) );
$tmp_zip = $basedir . 'aptce-plugin-' . time() . '.zip';
$zip_filename = $item_name . '.zip';
try {
if ( class_exists( 'ZipArchive' ) ) {
$zip = new ZipArchive();
if ( $zip->open( $tmp_zip, ZipArchive::CREATE ) !== TRUE ) {
return [ 'success' => false, 'message' => __( 'Could not create archive', 'advanced-addons-theme-core-exporter' ) ];
}
$plugin_dir = wp_normalize_path( WP_PLUGIN_DIR . '/' . dirname( $plugin_path ) );
if ( is_dir( $plugin_dir ) ) {
$base = basename( $plugin_dir );
$plugin_dir_normalized = wp_normalize_path( rtrim( $plugin_dir, '/\\\\' ) );
$files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $plugin_dir ), RecursiveIteratorIterator::LEAVES_ONLY );
foreach ( $files as $file ) {
if ( $file->isDir() ) continue;
$filePath = $file->getRealPath();
if ( ! $filePath ) continue;
$filePath_normalized = wp_normalize_path( $filePath );
if ( strpos( $filePath_normalized, $plugin_dir_normalized ) === 0 ) {
$relative = substr( $filePath_normalized, strlen( $plugin_dir_normalized ) );
$relative = ltrim( $relative, '/' );
$relative = str_replace( '\\\\', '/', $relative );
$zip->addFile( $filePath, $base . '/' . $relative );
}
}
}
$zip->close();
} else {
return [ 'success' => false, 'message' => __( 'ZipArchive not available', 'advanced-addons-theme-core-exporter' ) ];
}
if ( ! file_exists( $tmp_zip ) || filesize( $tmp_zip ) === 0 ) {
return [ 'success' => false, 'message' => __( 'ZIP creation failed', 'advanced-addons-theme-core-exporter' ) ];
}
return [
'success' => true,
'file' => basename( $tmp_zip ),
'url' => $upload['baseurl'] . '/' . basename( $tmp_zip ),
'filename' => $zip_filename
];
} catch ( Exception $e ) {
return [ 'success' => false, 'message' => $e->getMessage() ];
}
}
/**
* Helper: Create theme zip
*/
protected function aptce_create_theme_zip( $theme_slug ) {
$theme = wp_get_theme( $theme_slug );
$item_name = $theme->get( 'Name' ) ? $theme->get( 'Name' ) : $theme_slug;
$item_name = sanitize_file_name( strtolower( str_replace( ' ', '-', $item_name ) ) );
$upload = wp_upload_dir();
$basedir = trailingslashit( wp_normalize_path( $upload['basedir'] ) );
$tmp_zip = $basedir . 'aptce-theme-' . time() . '.zip';
$zip_filename = $item_name . '.zip';
try {
if ( class_exists( 'ZipArchive' ) ) {
$zip = new ZipArchive();
if ( $zip->open( $tmp_zip, ZipArchive::CREATE ) !== TRUE ) {
return [ 'success' => false, 'message' => __( 'Could not create archive', 'advanced-addons-theme-core-exporter' ) ];
}
$theme_dir = wp_normalize_path( get_theme_root() . '/' . $theme_slug );
if ( is_dir( $theme_dir ) ) {
$base = basename( $theme_dir );
$theme_dir_normalized = wp_normalize_path( rtrim( $theme_dir, '/\\\\' ) );
$files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $theme_dir ), RecursiveIteratorIterator::LEAVES_ONLY );
foreach ( $files as $file ) {
if ( $file->isDir() ) continue;
$filePath = $file->getRealPath();
if ( ! $filePath ) continue;
$filePath_normalized = wp_normalize_path( $filePath );
if ( strpos( $filePath_normalized, $theme_dir_normalized ) === 0 ) {
$relative = substr( $filePath_normalized, strlen( $theme_dir_normalized ) );
$relative = ltrim( $relative, '/' );
$relative = str_replace( '\\\\', '/', $relative );
$zip->addFile( $filePath, $base . '/' . $relative );
}
}
}
$zip->close();
} else {
return [ 'success' => false, 'message' => __( 'ZipArchive not available', 'advanced-addons-theme-core-exporter' ) ];
}
if ( ! file_exists( $tmp_zip ) || filesize( $tmp_zip ) === 0 ) {
return [ 'success' => false, 'message' => __( 'ZIP creation failed', 'advanced-addons-theme-core-exporter' ) ];
}
return [
'success' => true,
'file' => basename( $tmp_zip ),
'url' => $upload['baseurl'] . '/' . basename( $tmp_zip ),
'filename' => $zip_filename
];
} catch ( Exception $e ) {
return [ 'success' => false, 'message' => $e->getMessage() ];
}
}
/**
* Helper: Create core files zip
*/
protected function aptce_create_core_zip( $type ) {
$upload = wp_upload_dir();
switch ( $type ) {
case 'full_100':
$source = ABSPATH;
$zip_name = 'wordpress-full-100-percent-' . date( 'Ymd-His' ) . '.zip';
$exclude = [];
break;
case 'full':
$source = ABSPATH;
$uploads_dir = $upload['basedir'];
$exclude = [ $uploads_dir, ABSPATH . 'wp-config.php' ];
$zip_name = 'wordpress-core-full-' . date( 'Ymd-His' ) . '.zip';
break;
case 'uploads':
$source = $upload['basedir'];
$zip_name = 'wp-uploads-' . date( 'Ymd-His' ) . '.zip';
$exclude = [];
break;
case 'wpcontent':
$source = WP_CONTENT_DIR;
$uploads_dir = $upload['basedir'];
$exclude = [ $uploads_dir ];
$zip_name = 'wp-content-no-uploads-' . date( 'Ymd-His' ) . '.zip';
break;
case 'admin':
$source = trailingslashit( ABSPATH ) . 'wp-admin';
$zip_name = 'wp-admin-' . date( 'Ymd-His' ) . '.zip';
$exclude = [];
break;
case 'includes':
$source = trailingslashit( ABSPATH ) . 'wp-includes';
$zip_name = 'wp-includes-' . date( 'Ymd-His' ) . '.zip';
$exclude = [];
break;
default:
return [ 'success' => false, 'message' => __( 'Invalid type', 'advanced-addons-theme-core-exporter' ) ];
}
if ( ! $source || ! is_dir( $source ) ) {
return [ 'success' => false, 'message' => __( 'Directory not found', 'advanced-addons-theme-core-exporter' ) ];
}
$tmp_zip = $upload['basedir'] . '/aptce-core-' . time() . '.zip';
try {
if ( class_exists( 'ZipArchive' ) ) {
$zip = new ZipArchive();
if ( $zip->open( $tmp_zip, ZipArchive::CREATE ) !== TRUE ) {
return [ 'success' => false, 'message' => __( 'Could not create archive', 'advanced-addons-theme-core-exporter' ) ];
}
$this->aptce_add_folder_to_zip( $zip, $source, $source, $exclude );
$zip->close();
} else {
return [ 'success' => false, 'message' => __( 'ZipArchive not available', 'advanced-addons-theme-core-exporter' ) ];
}
if ( ! file_exists( $tmp_zip ) || filesize( $tmp_zip ) === 0 ) {
return [ 'success' => false, 'message' => __( 'ZIP creation failed', 'advanced-addons-theme-core-exporter' ) ];
}
return [
'success' => true,
'file' => basename( $tmp_zip ),
'url' => $upload['baseurl'] . '/' . basename( $tmp_zip ),
'filename' => $zip_name
];
} catch ( Exception $e ) {
return [ 'success' => false, 'message' => $e->getMessage() ];
}
}
/**
* Helper: Create database dump
*/
protected function aptce_create_database_dump() {
$upload = wp_upload_dir();
$db_file_path = $upload['basedir'] . '/aptce-database-' . time() . '.sql';
$filename = 'wordpress-database-' . date( 'Ymd-His' ) . '.sql';
$result = $this->aptce_generate_database_dump_file( $db_file_path );
if ( $result ) {
return [
'success' => true,
'file' => basename( $db_file_path ),
'url' => $upload['baseurl'] . '/' . basename( $db_file_path ),
'filename' => $filename
];
} else {
return [ 'success' => false, 'message' => __( 'Database dump failed', 'advanced-addons-theme-core-exporter' ) ];
}
}
/**
* AJAX handler to cleanup temporary files
*/
public function aptce_cleanup_file() {
check_ajax_referer( 'aptce_export', 'nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error();
}
$file = isset( $_POST['file'] ) ? sanitize_file_name( wp_unslash( $_POST['file'] ) ) : '';
if ( empty( $file ) ) {
wp_send_json_error();
}
$upload = wp_upload_dir();
$file_path = $upload['basedir'] . '/' . $file;
if ( file_exists( $file_path ) && strpos( $file_path, 'aptce-' ) !== false ) {
@unlink( $file_path );
wp_send_json_success();
}
wp_send_json_error();
}
/**
* AJAX handler for bulk export
*/
public function aptce_ajax_bulk_export() {
check_ajax_referer( 'aptce_export', 'nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( [ 'message' => __( 'Insufficient permissions', 'advanced-addons-theme-core-exporter' ) ] );
}
$plugins = isset( $_POST['plugins'] ) && is_array( $_POST['plugins'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['plugins'] ) ) : [];
$themes = isset( $_POST['themes'] ) && is_array( $_POST['themes'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['themes'] ) ) : [];
$export_core = isset( $_POST['export_core'] ) && '1' == $_POST['export_core'];
$core_options = isset( $_POST['core_options'] ) && is_array( $_POST['core_options'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['core_options'] ) ) : [];
// Create the bulk export zip
$result = $this->aptce_create_bulk_export( $plugins, $themes, $export_core, $core_options );
if ( $result['success'] ) {
wp_send_json_success( [
'file' => $result['file'],
'url' => $result['url'],
'filename' => $result['filename']
] );
} else {
wp_send_json_error( [ 'message' => $result['message'] ] );
}
}
/**
* Helper: Create bulk export zip
*/
protected function aptce_create_bulk_export( $plugins, $themes, $export_core, $core_options ) {
$files_to_add = [];
$temp_files = [];
// Add selected plugins
if ( ! empty( $plugins ) ) {
foreach ( $plugins as $plugin_path ) {
$plugin_dir = wp_normalize_path( WP_PLUGIN_DIR . '/' . dirname( $plugin_path ) );
if ( is_dir( $plugin_dir ) ) {
$files_to_add[] = realpath( $plugin_dir );
}
}
}
// Add selected themes
if ( ! empty( $themes ) ) {
foreach ( $themes as $slug ) {
$theme_dir = get_theme_root() . '/' . $slug;
if ( is_dir( $theme_dir ) ) {
$files_to_add[] = realpath( $theme_dir );
}
}
}
// Add core files if selected
if ( $export_core && ! empty( $core_options ) ) {
$upload = wp_upload_dir();
foreach ( $core_options as $option ) {
switch ( $option ) {
case 'full_100':
$root_dir = wp_normalize_path( trailingslashit( ABSPATH ) );
if ( ! empty( $root_dir ) && is_dir( $root_dir ) ) {
$files_to_add[] = [
'path' => trailingslashit( $root_dir ),
'type' => 'core_100',
];
}
break;
case 'full':
$root_path = trailingslashit( realpath( ABSPATH ) );
if ( $root_path ) {
$files_to_add[] = $root_path . '|core';
}
break;
case 'uploads':
$uploads_dir = isset( $upload['basedir'] ) ? $upload['basedir'] : '';
if ( ! empty( $uploads_dir ) && is_dir( $uploads_dir ) ) {
$files_to_add[] = trailingslashit( $uploads_dir );
}
break;
case 'wpcontent':
$wpcontent_dir = wp_normalize_path( WP_CONTENT_DIR );
if ( ! empty( $wpcontent_dir ) && is_dir( $wpcontent_dir ) ) {
$files_to_add[] = [
'path' => trailingslashit( $wpcontent_dir ),
'type' => 'wpcontent_no_uploads',
'exclude' => [ wp_normalize_path( $upload['basedir'] ) ],
];
}
break;
case 'admin':
$admin_dir = wp_normalize_path( AATCE_ADMIN );
if ( ! empty( $admin_dir ) && is_dir( $admin_dir ) ) {
$files_to_add[] = [
'path' => trailingslashit( $admin_dir ),
'type' => 'admin',
];
}
break;
case 'includes':
$includes_dir = wp_normalize_path( ABSPATH . 'wp-includes' );
if ( ! empty( $includes_dir ) && is_dir( $includes_dir ) ) {
$files_to_add[] = [
'path' => trailingslashit( $includes_dir ),
'type' => 'includes',
];
}
break;
case 'database':
$db_file_path = $upload['basedir'] . '/aptce-database-' . time() . '.sql';
$database_file = $this->aptce_generate_database_dump_file( $db_file_path );
if ( $database_file ) {
$temp_files[] = $database_file;
}
break;
}
}
}
if ( empty( $files_to_add ) && empty( $temp_files ) ) {
return [ 'success' => false, 'message' => __( 'No items selected', 'advanced-addons-theme-core-exporter' ) ];
}
$upload = wp_upload_dir();
$tmp_zip = $upload['basedir'] . '/aptce-export-' . time() . '.zip';
try {
if ( ! class_exists( 'ZipArchive' ) ) {
return [ 'success' => false, 'message' => __( 'ZipArchive not available', 'advanced-addons-theme-core-exporter' ) ];
}
$zip = new ZipArchive();
if ( $zip->open( $tmp_zip, ZipArchive::CREATE ) !== TRUE ) {
return [ 'success' => false, 'message' => __( 'Could not create archive', 'advanced-addons-theme-core-exporter' ) ];
}
$added_files = [];
// Add items to ZIP
foreach ( $files_to_add as $item ) {
if ( is_array( $item ) ) {
$item_path = isset( $item['path'] ) ? $item['path'] : '';
$item_type = isset( $item['type'] ) ? $item['type'] : '';
$item_exclude = isset( $item['exclude'] ) ? (array) $item['exclude'] : [];
if ( empty( $item_path ) ) continue;
if ( 'core_100' === $item_type ) {
$root = AATCE_ROOT_PATH;
if ( $root ) {
$root_normalized = wp_normalize_path( rtrim( $root, '/\\' ) );
$iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $root, FilesystemIterator::SKIP_DOTS ), RecursiveIteratorIterator::LEAVES_ONLY );
foreach ( $iterator as $file ) {
if ( $file->isDir() ) continue;
$filePath = $file->getRealPath();
if ( ! $filePath ) continue;
$filePath_normalized = wp_normalize_path( $filePath );
if ( strpos( $filePath_normalized, $root_normalized ) === 0 ) {
$localPath = substr( $filePath_normalized, strlen( $root_normalized ) );
$localPath = ltrim( $localPath, '/' );
$localPath = str_replace( '\\', '/', $localPath );
if ( ! isset( $added_files[ $localPath ] ) ) {
$zip->addFile( $filePath, $localPath );
$added_files[ $localPath ] = true;
}
}
}
}
} elseif ( 'wpcontent_no_uploads' === $item_type ) {
$base_path = realpath( $item_path );
if ( $base_path ) {
$files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $base_path, FilesystemIterator::SKIP_DOTS ), RecursiveIteratorIterator::LEAVES_ONLY );
foreach ( $files as $file ) {
if ( $file->isDir() ) continue;
$filePath = $file->getRealPath();
$skip = false;
foreach ( $item_exclude as $exclude_path ) {
if ( realpath( $exclude_path ) && strpos( $filePath, realpath( $exclude_path ) ) === 0 ) {
$skip = true;
break;
}
}
if ( $skip ) continue;
$base_path_normalized = wp_normalize_path( rtrim( $base_path, '/\\' ) );
$filePath_normalized = wp_normalize_path( $filePath );
if ( strpos( $filePath_normalized, $base_path_normalized ) === 0 ) {
$relative = substr( $filePath_normalized, strlen( $base_path_normalized ) );
$relative = ltrim( $relative, '/' );
$localPath = 'wp-content/' . str_replace( '\\', '/', $relative );
if ( ! isset( $added_files[ $localPath ] ) ) {
$zip->addFile( $filePath, $localPath );
$added_files[ $localPath ] = true;
}
}
}
}
} elseif ( 'admin' === $item_type || 'includes' === $item_type ) {
$dir_path = realpath( $item_path );
if ( $dir_path ) {
$base = basename( $dir_path );
$files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $dir_path, FilesystemIterator::SKIP_DOTS ), RecursiveIteratorIterator::LEAVES_ONLY );
foreach ( $files as $file ) {
if ( $file->isDir() ) continue;
$filePath = $file->getRealPath();
if ( ! $filePath ) continue;
$dir_path_normalized = wp_normalize_path( rtrim( $dir_path, '/\\' ) );
$filePath_normalized = wp_normalize_path( $filePath );
if ( strpos( $filePath_normalized, $dir_path_normalized ) === 0 ) {
$relative = substr( $filePath_normalized, strlen( $dir_path_normalized ) );
$relative = ltrim( $relative, '/' );
$localPath = $base . '/' . str_replace( '\\', '/', $relative );
if ( ! isset( $added_files[ $localPath ] ) ) {
$zip->addFile( $filePath, $localPath );
$added_files[ $localPath ] = true;
}
}
}
}
}
continue;
}
if ( ! is_string( $item ) ) continue;
if ( false !== strpos( $item, '|core' ) ) {
$root = AATCE_ROOT_PATH;
if ( $root ) {
$iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $root, FilesystemIterator::SKIP_DOTS ), RecursiveIteratorIterator::LEAVES_ONLY );
foreach ( $iterator as $file ) {
if ( $file->isDir() ) continue;
$filePath = $file->getRealPath();
$uploads = wp_upload_dir();
$uploads_dir = wp_normalize_path( $uploads['basedir'] );
if ( 0 === strpos( wp_normalize_path( $filePath ), $uploads_dir ) ) continue;
if ( basename( $filePath ) === 'wp-config.php' ) continue;
$root_normalized = wp_normalize_path( rtrim( $root, '/\\' ) );
$filePath_normalized = wp_normalize_path( $filePath );
if ( strpos( $filePath_normalized, $root_normalized ) === 0 ) {
$localPath = substr( $filePath_normalized, strlen( $root_normalized ) );
$localPath = ltrim( $localPath, '/' );
$localPath = str_replace( '\\', '/', $localPath );
if ( ! isset( $added_files[ $localPath ] ) ) {
$zip->addFile( $filePath, $localPath );
$added_files[ $localPath ] = true;
}
}
}
}
continue;
}
if ( is_dir( $item ) ) {
$item_realpath = realpath( $item );
if ( $item_realpath ) {
$base = basename( $item_realpath );
$files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $item_realpath, FilesystemIterator::SKIP_DOTS ), RecursiveIteratorIterator::LEAVES_ONLY );
foreach ( $files as $file ) {
if ( $file->isDir() ) continue;
$filePath = $file->getRealPath();
if ( ! $filePath ) continue;
$item_realpath_normalized = wp_normalize_path( rtrim( $item_realpath, '/\\' ) );
$filePath_normalized = wp_normalize_path( $filePath );
if ( strpos( $filePath_normalized, $item_realpath_normalized ) === 0 ) {
$relative = substr( $filePath_normalized, strlen( $item_realpath_normalized ) );
$relative = ltrim( $relative, '/' );
$localPath = $base . '/' . str_replace( '\\', '/', $relative );
if ( ! isset( $added_files[ $localPath ] ) ) {
$zip->addFile( $filePath, $localPath );
$added_files[ $localPath ] = true;
}
}
}
}
}
}
// Add temp files (database)
foreach ( $temp_files as $tf ) {
if ( is_file( $tf ) ) {
if ( false !== strpos( $tf, 'aptce-database' ) ) {
$zip->addFile( $tf, 'wordpress-database-' . date( 'Ymd-His' ) . '.sql' );
}
}
}
$zip->close();
// Clean up temp files
foreach ( $temp_files as $f ) {
@unlink( $f );
}
if ( ! file_exists( $tmp_zip ) || filesize( $tmp_zip ) === 0 ) {
return [ 'success' => false, 'message' => __( 'ZIP creation failed', 'advanced-addons-theme-core-exporter' ) ];
}
return [
'success' => true,
'file' => basename( $tmp_zip ),
'url' => $upload['baseurl'] . '/' . basename( $tmp_zip ),
'filename' => basename( $tmp_zip )
];
} catch ( Exception $e ) {
return [ 'success' => false, 'message' => $e->getMessage() ];
}
}
}
new APTCE_Download_Exporter();