MagicWP Docs

Automatic Backups

Set up and manage automatic backup schedules for your WordPress site

Automatic Backups

Configure automatic backup schedules to ensure your WordPress site is continuously protected. Set up daily, weekly, or custom backup schedules with minimal manual intervention.

Automated Backup Setup

Basic Configuration

Enable Automatic Backups

// Enable automatic backups in wp-config.php
define('WP_AUTO_BACKUP_ENABLED', true);
define('WP_BACKUP_FREQUENCY', 'daily'); // daily, weekly, monthly
define('WP_BACKUP_TIME', '02:00'); // 2 AM server time
define('WP_BACKUP_RETENTION', 30); // Keep backups for 30 days

Backup Storage Configuration

// Configure backup storage
define('WP_BACKUP_STORAGE_TYPE', 'local'); // local, ftp, s3, dropbox
define('WP_BACKUP_STORAGE_PATH', '/path/to/backups/');
define('WP_BACKUP_COMPRESSION', 'gzip'); // gzip, zip, none
define('WP_BACKUP_ENCRYPTION', false); // true to enable encryption

Advanced Scheduling

Cron-Based Scheduling

// Schedule automatic backups
function setup_backup_schedule() {
    // Daily backups
    if (!wp_next_scheduled('daily_backup_event')) {
        wp_schedule_event(strtotime('02:00:00'), 'daily', 'daily_backup_event');
    }

    // Weekly backups (Sunday at 3 AM)
    if (!wp_next_scheduled('weekly_backup_event')) {
        wp_schedule_event(strtotime('next Sunday 03:00:00'), 'weekly', 'weekly_backup_event');
    }

    // Monthly backups (1st of month at 4 AM)
    if (!wp_next_scheduled('monthly_backup_event')) {
        wp_schedule_event(strtotime('first day of next month 04:00:00'), 'monthly', 'monthly_backup_event');
    }
}
add_action('wp', 'setup_backup_schedule');

// Execute backup functions
function execute_daily_backup() {
    perform_automated_backup('daily');
}

function execute_weekly_backup() {
    perform_automated_backup('weekly');
}

function execute_monthly_backup() {
    perform_automated_backup('monthly');
}

add_action('daily_backup_event', 'execute_daily_backup');
add_action('weekly_backup_event', 'execute_weekly_backup');
add_action('monthly_backup_event', 'execute_monthly_backup');

Custom Schedule Intervals

// Register custom cron intervals
function add_custom_cron_intervals($schedules) {
    // Every 6 hours
    $schedules['six_hours'] = array(
        'interval' => 21600, // 6 hours in seconds
        'display'  => __('Every 6 Hours')
    );

    // Every 12 hours
    $schedules['twelve_hours'] = array(
        'interval' => 43200, // 12 hours in seconds
        'display'  => __('Every 12 Hours')
    );

    // Twice daily
    $schedules['twice_daily'] = array(
        'interval' => 43200,
        'display'  => __('Twice Daily')
    );

    return $schedules;
}
add_filter('cron_schedules', 'add_custom_cron_intervals');

// Schedule custom interval backups
if (!wp_next_scheduled('custom_backup_event')) {
    wp_schedule_event(time(), 'six_hours', 'custom_backup_event');
}
add_action('custom_backup_event', 'execute_custom_backup');

Backup Content Configuration

Selective Backup Options

Database-Only Backups

function create_database_backup($schedule_type) {
    global $wpdb;

    $tables = array(
        'posts' => $wpdb->posts,
        'postmeta' => $wpdb->postmeta,
        'users' => $wpdb->users,
        'usermeta' => $wpdb->usermeta,
        'options' => $wpdb->options,
        'comments' => $wpdb->comments,
        'commentmeta' => $wpdb->commentmeta
    );

    $backup_data = array();
    foreach ($tables as $name => $table) {
        $results = $wpdb->get_results("SELECT * FROM {$table}", ARRAY_A);
        $backup_data[$name] = $results;
    }

    $filename = 'db_backup_' . $schedule_type . '_' . date('Y-m-d_H-i-s') . '.sql';
    $filepath = WP_CONTENT_DIR . '/backups/' . $filename;

    // Create backup directory if it doesn't exist
    wp_mkdir_p(dirname($filepath));

    // Write SQL dump
    $sql_content = generate_sql_dump($backup_data);
    file_put_contents($filepath, $sql_content);

    return $filepath;
}

Files-Only Backups

function create_files_backup($schedule_type) {
    $source_dir = ABSPATH;
    $backup_dir = WP_CONTENT_DIR . '/backups/files_' . $schedule_type . '_' . date('Y-m-d_H-i-s');

    // Create backup directory
    wp_mkdir_p($backup_dir);

    // Files and directories to include
    $include_paths = array(
        'wp-content/themes/',
        'wp-content/plugins/',
        'wp-content/uploads/',
        'wp-includes/',
        'wp-admin/',
        'wp-config.php',
        '.htaccess'
    );

    // Files and directories to exclude
    $exclude_patterns = array(
        'wp-content/cache/',
        'wp-content/backups/',
        '*.log',
        'wp-content/debug.log'
    );

    foreach ($include_paths as $path) {
        $full_path = $source_dir . $path;

        if (file_exists($full_path)) {
            if (is_dir($full_path)) {
                // Copy directory
                copy_directory_recursive($full_path, $backup_dir . '/' . $path);
            } else {
                // Copy file
                copy($full_path, $backup_dir . '/' . $path);
            }
        }
    }

    return $backup_dir;
}

Full Site Backups

function create_full_site_backup($schedule_type) {
    // Create database backup
    $db_backup = create_database_backup($schedule_type);

    // Create files backup
    $files_backup = create_files_backup($schedule_type);

    // Combine into single archive
    $archive_name = 'full_backup_' . $schedule_type . '_' . date('Y-m-d_H-i-s') . '.tar.gz';
    $archive_path = WP_CONTENT_DIR . '/backups/' . $archive_name;

    // Create compressed archive
    create_backup_archive($db_backup, $files_backup, $archive_path);

    // Clean up temporary files
    unlink($db_backup);
    remove_directory_recursive($files_backup);

    return $archive_path;
}

Backup Storage Management

Local Storage

function manage_local_backup_storage() {
    $backup_dir = WP_CONTENT_DIR . '/backups/';
    $max_backups = get_option('max_local_backups', 10);

    if (!is_dir($backup_dir)) {
        wp_mkdir_p($backup_dir);
        return;
    }

    // Get all backup files
    $backup_files = glob($backup_dir . '*.{sql,tar.gz,zip}', GLOB_BRACE);

    // Sort by modification time (newest first)
    usort($backup_files, function($a, $b) {
        return filemtime($b) - filemtime($a);
    });

    // Remove old backups if we have too many
    if (count($backup_files) > $max_backups) {
        $files_to_remove = array_slice($backup_files, $max_backups);
        foreach ($files_to_remove as $file) {
            unlink($file);
        }
    }
}

Remote Storage Options

FTP/SFTP Upload

function upload_backup_to_ftp($backup_path, $ftp_config) {
    $ftp_connection = ftp_connect($ftp_config['host']);

    if (!$ftp_connection) {
        return new WP_Error('ftp_connection_failed', 'Could not connect to FTP server');
    }

    $login_result = ftp_login($ftp_connection, $ftp_config['username'], $ftp_config['password']);

    if (!$login_result) {
        return new WP_Error('ftp_login_failed', 'FTP login failed');
    }

    // Enable passive mode
    ftp_pasv($ftp_connection, true);

    // Change to backup directory
    if (isset($ftp_config['directory'])) {
        ftp_chdir($ftp_connection, $ftp_config['directory']);
    }

    // Upload file
    $remote_filename = basename($backup_path);
    $upload_result = ftp_put($ftp_connection, $remote_filename, $backup_path, FTP_BINARY);

    ftp_close($ftp_connection);

    if (!$upload_result) {
        return new WP_Error('ftp_upload_failed', 'FTP upload failed');
    }

    return true;
}

Cloud Storage Integration

// Upload to Amazon S3
function upload_backup_to_s3($backup_path, $s3_config) {
    require_once 'vendor/autoload.php'; // AWS SDK

    $s3_client = new Aws\S3\S3Client(array(
        'version' => 'latest',
        'region'  => $s3_config['region'],
        'credentials' => array(
            'key'    => $s3_config['access_key'],
            'secret' => $s3_config['secret_key']
        )
    ));

    try {
        $result = $s3_client->putObject(array(
            'Bucket' => $s3_config['bucket'],
            'Key'    => basename($backup_path),
            'SourceFile' => $backup_path,
            'ACL'    => 'private'
        ));

        return $result['ObjectURL'];
    } catch (Exception $e) {
        return new WP_Error('s3_upload_failed', $e->getMessage());
    }
}

Backup Verification and Testing

Automated Backup Verification

function verify_backup_integrity($backup_path) {
    $verification_results = array(
        'exists' => false,
        'readable' => false,
        'size' => 0,
        'checksum' => '',
        'corrupted' => false
    );

    // Check if file exists
    if (!file_exists($backup_path)) {
        return $verification_results;
    }
    $verification_results['exists'] = true;

    // Check if file is readable
    if (!is_readable($backup_path)) {
        return $verification_results;
    }
    $verification_results['readable'] = true;

    // Get file size
    $verification_results['size'] = filesize($backup_path);

    // Generate checksum
    $verification_results['checksum'] = hash_file('sha256', $backup_path);

    // Additional checks based on file type
    $file_extension = pathinfo($backup_path, PATHINFO_EXTENSION);

    if ($file_extension === 'sql') {
        $verification_results['is_valid_sql'] = verify_sql_backup($backup_path);
    } elseif (in_array($file_extension, array('tar', 'gz', 'zip'))) {
        $verification_results['is_valid_archive'] = verify_archive_backup($backup_path);
    }

    return $verification_results;
}

Backup Testing

function test_backup_restoration($backup_path) {
    $test_results = array(
        'database_test' => false,
        'files_test' => false,
        'overall_success' => false
    );

    // Create temporary test environment
    $test_dir = WP_CONTENT_DIR . '/backup-test-' . time();
    wp_mkdir_p($test_dir);

    try {
        $file_extension = pathinfo($backup_path, PATHINFO_EXTENSION);

        if ($file_extension === 'sql') {
            // Test database restoration
            $test_results['database_test'] = test_database_restore($backup_path, $test_dir);
        } elseif (in_array($file_extension, array('tar', 'gz', 'zip'))) {
            // Test archive extraction
            $test_results['files_test'] = test_archive_extraction($backup_path, $test_dir);
        } elseif (is_dir($backup_path)) {
            // Test directory copy
            $test_results['files_test'] = test_directory_copy($backup_path, $test_dir);
        }

        $test_results['overall_success'] = $test_results['database_test'] || $test_results['files_test'];

    } catch (Exception $e) {
        error_log('Backup test failed: ' . $e->getMessage());
    } finally {
        // Clean up test directory
        remove_directory_recursive($test_dir);
    }

    return $test_results;
}

Monitoring and Notifications

Backup Status Monitoring

function monitor_backup_status() {
    $last_backup_time = get_option('last_backup_time');
    $backup_status = get_option('last_backup_status');
    $consecutive_failures = get_option('consecutive_backup_failures', 0);

    // Check if backups are running regularly
    $hours_since_last_backup = (time() - $last_backup_time) / 3600;

    if ($hours_since_last_backup > 25 && $backup_status === 'success') { // More than 25 hours for daily backups
        // Backup is overdue
        send_backup_overdue_notification($hours_since_last_backup);
    }

    // Check for consecutive failures
    if ($backup_status === 'failed') {
        $consecutive_failures++;
        update_option('consecutive_backup_failures', $consecutive_failures);

        if ($consecutive_failures >= 3) {
            send_backup_failure_alert($consecutive_failures);
        }
    } else {
        // Reset consecutive failures on success
        update_option('consecutive_backup_failures', 0);
    }
}
add_action('backup_status_check', 'monitor_backup_status');

Email Notifications

function send_backup_notification($backup_type, $status, $details = array()) {
    $admin_email = get_option('admin_email');
    $site_name = get_bloginfo('name');

    $subject = ucfirst($status) . ': ' . ucfirst($backup_type) . ' Backup - ' . $site_name;

    $message = "
    <h3>Backup Notification</h3>
    <p><strong>Backup Type:</strong> {$backup_type}</p>
    <p><strong>Status:</strong> " . ucfirst($status) . "</p>
    <p><strong>Time:</strong> " . current_time('mysql') . "</p>
    ";

    if (!empty($details)) {
        $message .= "<h4>Details:</h4><ul>";
        foreach ($details as $key => $value) {
            $message .= "<li><strong>" . ucfirst(str_replace('_', ' ', $key)) . ":</strong> {$value}</li>";
        }
        $message .= "</ul>";
    }

    $headers = array('Content-Type: text/html; charset=UTF-8');
    wp_mail($admin_email, $subject, $message, $headers);
}

Backup Performance Optimization

Resource Management

function optimize_backup_performance() {
    // Increase PHP limits for backup operations
    if (defined('DOING_BACKUP') && DOING_BACKUP) {
        ini_set('memory_limit', '512M');
        ini_set('max_execution_time', 300);
        ini_set('max_input_time', 300);
    }

    // Disable unnecessary plugins during backup
    if (wp_doing_cron() && isset($_GET['doing_backup'])) {
        add_filter('option_active_plugins', 'disable_plugins_during_backup');
    }
}

function disable_plugins_during_backup($plugins) {
    $plugins_to_disable = array(
        'wordpress-seo/wp-seo.php', // Yoast SEO
        'w3-total-cache/w3-total-cache.php', // W3 Total Cache
        // Add other resource-intensive plugins
    );

    return array_diff($plugins, $plugins_to_disable);
}

Incremental Backup Optimization

function create_incremental_backup($last_backup_time) {
    global $wpdb;

    // Get changes since last backup
    $changed_posts = $wpdb->get_results($wpdb->prepare(
        "SELECT * FROM {$wpdb->posts} WHERE post_modified > %s",
        date('Y-m-d H:i:s', $last_backup_time)
    ));

    $changed_postmeta = $wpdb->get_results($wpdb->prepare(
        "SELECT * FROM {$wpdb->postmeta} pm
         INNER JOIN {$wpdb->posts} p ON pm.post_id = p.ID
         WHERE p.post_modified > %s",
        date('Y-m-d H:i:s', $last_backup_time)
    ));

    // Get changed media files
    $changed_media = get_changed_media_files($last_backup_time);

    // Create incremental backup archive
    return create_incremental_archive($changed_posts, $changed_postmeta, $changed_media);
}

function get_changed_media_files($since_timestamp) {
    $args = array(
        'post_type' => 'attachment',
        'posts_per_page' => -1,
        'date_query' => array(
            array(
                'after' => date('Y-m-d H:i:s', $since_timestamp),
                'column' => 'post_modified'
            )
        )
    );

    $changed_media = get_posts($args);
    return $changed_media;
}

Security Considerations

Backup Encryption

function encrypt_backup($backup_path, $encryption_key) {
    $backup_content = file_get_contents($backup_path);

    // Generate initialization vector
    $iv = openssl_random_pseudo_bytes(16);

    // Encrypt the content
    $encrypted = openssl_encrypt(
        $backup_content,
        'AES-256-CBC',
        $encryption_key,
        0,
        $iv
    );

    // Store IV with encrypted content
    $encrypted_with_iv = $iv . $encrypted;

    // Save encrypted backup
    $encrypted_path = $backup_path . '.encrypted';
    file_put_contents($encrypted_path, $encrypted_with_iv);

    // Remove original unencrypted file
    unlink($backup_path);

    return $encrypted_path;
}

function decrypt_backup($encrypted_path, $encryption_key) {
    $encrypted_content = file_get_contents($encrypted_path);

    // Extract IV from the beginning
    $iv = substr($encrypted_content, 0, 16);
    $encrypted = substr($encrypted_content, 16);

    // Decrypt the content
    $decrypted = openssl_decrypt(
        $encrypted,
        'AES-256-CBC',
        $encryption_key,
        0,
        $iv
    );

    return $decrypted;
}

Best Practices

Backup Strategy Guidelines

  1. Regular Schedule: Automate daily backups with weekly and monthly archives
  2. Multiple Locations: Store backups locally and in the cloud
  3. Encryption: Encrypt sensitive backup data
  4. Testing: Regularly test backup restoration
  5. Monitoring: Monitor backup success and performance

Performance Optimization

  1. Resource Management: Schedule backups during low-traffic periods
  2. Incremental Backups: Use incremental backups for large sites
  3. Compression: Compress backups to save storage space
  4. Cleanup: Automatically remove old backups

Security Best Practices

  1. Access Control: Limit backup access to authorized users
  2. Encryption: Encrypt backups both in transit and at rest
  3. Integrity Checks: Verify backup integrity regularly
  4. Secure Storage: Use secure storage locations and methods

Automated backup solutions for continuous WordPress protection.

On this page