Menü schliessen
Created: October 30th 2024
Last updated: October 31st 2024
Categories: Advanced Custom Fields,  Linux,  Wordpress
Author: Marcus Fleuti

Automate ACF Pro Updates Across Multiple WordPress Sites: A Server-Side Bash Script Solution

Donation Section: Background
Monero Badge: QR-Code
Monero Badge: Logo Icon Donate with Monero Badge: Logo Text
82uymVXLkvVbB4c4JpTd1tYm1yj1cKPKR2wqmw3XF8YXKTmY7JrTriP4pVwp2EJYBnCFdXhLq4zfFA6ic7VAWCFX5wfQbCC

Bulk Update ACF Pro Across Multiple WordPress Sites: Fixing 6.3.10 Update Issues with Bash

The recent Advanced Custom Fields Pro (ACF Pro) update from version 6.3.9 to 6.3.10 has created unique challenges for WordPress administrators. Due to a legal conflict between WPEngine (ACF's parent company) and the WordPress.org team, many users are experiencing issues with the automatic update process. This situation has forced many developers and site administrators to perform manual updates across their WordPress installations. For those managing multiple WordPress sites, this presents a significant maintenance challenge.

If you're experiencing the dreaded "Download failed. Connection timed out" error while trying to update ACF Pro automatically, or if the updater simply doesn't show the new version, you're not alone. These issues are particularly prevalent with the 6.3.9 to 6.3.10 update, which includes critical changes required by WPEngine to comply with WordPress.org guidelines. While manual updates are necessary in this case, performing them across multiple sites can be time-consuming and error-prone.

In this guide, we'll explore a powerful bash script solution that automates the manual update process across all your WordPress installations, ensuring consistent and efficient updates while maintaining proper file permissions and ownership.

The Challenge of Managing Multiple ACF Pro Installations

If you're managing multiple WordPress sites on a server, updating ACF Pro manually for each installation can be time-consuming and error-prone. The traditional approach requires logging into each WordPress dashboard individually or using WP-CLI commands repeatedly. Our bash script solution streamlines this process by handling updates at the file system level.

Script Overview and Features

Our script provides the following key features:

  • Automatic detection of all ACF Pro installations using the `locate` command
  • Preservation of original file permissions and ownership
  • Interactive prompt system for controlled execution
  • Batch processing capability with "process all" option
  • Detailed status reporting for each operation

Prerequisites

Before using the script, ensure you have:

  • Shell access to your Linux server
  • The `locate` command installed (usually part of the `mlocate` package)
  • Sufficient permissions to modify WordPress installation directories
  • The latest ACF Pro ZIP file at e.g. `/opt/advanced-custom-fields-pro.zip` (can be changed in global script variable)

The Script Implementation

Here's the complete script with detailed comments explaining each section:

#!/bin/bash

################################################################################
# Configuration - MODIFY THIS SECTION
################################################################################
# Path to your ACF Pro ZIP file
# IMPORTANT:
# 1. Update this path to point to your ACF Pro ZIP file location
# 2. The ZIP file MUST contain the directory "advanced-custom-fields-pro" 
#    in its root level for the script to work properly.
#
# Correct ZIP structure when opened:
# advanced-custom-fields-pro.zip
# └── advanced-custom-fields-pro/
#     ├── acf.php
#     ├── assets/
#     ├── includes/
#     └── ... (other plugin files)
#
# INCORRECT ZIP structure:
# your-acf-pro.zip
# └── some-other-folder/
#     └── advanced-custom-fields-pro/
#         └── ... (plugin files)
#
ZIP_FILE="/opt/advanced-custom-fields-pro.zip"

# Plugin directory pattern to search for
# This is the default pattern for ACF Pro installations. Most probably you'll not need to change it.
PLUGIN_DIR_PATTERN="wp-content/plugins/advanced-custom-fields-pro$"

################################################################################
# Script Description
################################################################################
# This script automatically updates Advanced Custom Fields (ACF) Pro plugin
# across multiple WordPress installations on your system. It:
#
# 1. Locates all ACF Pro plugin directories using the 'locate' command
# 2. Allows interactive confirmation for each update
# 3. Preserves original file permissions and ownership
# 4. Replaces old plugin files with new ones from the specified ZIP file
#
# Prerequisites:
# - Root/sudo access (for permission/ownership operations)
# - 'locate' command installed and database updated (updatedb)
# - 'unzip' command installed
# - ACF Pro ZIP file in the specified location
#
# Note: Run 'sudo updatedb' before this script to ensure locate finds all instances

################################################################################
# Functions
################################################################################

# Function to check if we should continue with the next directory
# Parameters:
#   $1 - Path to the next directory to be processed
# Returns:
#   0 - Yes, process this directory
#   1 - No, stop script
#   2 - Yes, process this and all remaining directories automatically
check_continue() {
    local next_dir="$1"
    
    echo -e "\nNext directory to process: $next_dir"
    while true; do
        read -p "Continue? (y/n/a for all): " answer
        case "$answer" in
            y|Y) return 0 ;;  # Process this directory
            n|N) return 1 ;;  # Stop script
            a|A) return 2 ;;  # Process all remaining directories
            *) echo "Please enter y, n, or a" ;;
        esac
    done
}

# Function to process a single ACF Pro directory
# Parameters:
#   $1 - Full path to the ACF Pro directory to update
# Returns:
#   0 - Success
#   1 - Failure (with error message)
process_directory() {
    local dir="$1"
    echo "Processing directory: $dir"
    
    # Verify directory exists
    if [ ! -d "$dir" ]; then
        echo "Directory $dir does not exist. Skipping."
        return 1
    fi
    
    # Store original filesystem attributes
    local orig_perms=$(stat -c '%a' "$dir")
    local orig_user=$(stat -c '%U' "$dir")
    local orig_group=$(stat -c '%G' "$dir")
    
    echo "Original permissions: $orig_perms"
    echo "Original ownership: $orig_user:$orig_group"
    
    # Get parent plugins directory
    local parent_dir=$(dirname "$dir")
    
    # Remove existing ACF Pro directory
    echo "Removing directory: $dir"
    rm -rf "$dir"
    if [ $? -ne 0 ]; then
        echo "Failed to remove directory. Skipping."
        return 1
    fi
    
    # Extract new ACF Pro files
    echo "Unzipping new files into: $parent_dir"
    unzip -q "$ZIP_FILE" -d "$parent_dir"
    if [ $? -ne 0 ]; then
        echo "Failed to unzip files. Skipping."
        return 1
    fi
    
    # Restore original filesystem attributes
    echo "Restoring permissions and ownership"
    chmod "$orig_perms" "$dir"
    chown -R "$orig_user:$orig_group" "$dir"
    if [ $? -ne 0 ]; then
        echo "Failed to restore permissions/ownership."
        return 1
    fi
    
    echo "Successfully processed $dir"
    return 0
}

################################################################################
# Main Script
################################################################################
echo "Starting ACF Pro Update Script"

# Verify ZIP file exists
if [ ! -f "$ZIP_FILE" ]; then
    echo "Error: ACF Pro ZIP file not found at $ZIP_FILE"
    echo "Please update the ZIP_FILE variable at the top of this script."
    exit 1
fi

# Find all ACF Pro installations using locate
echo "Locating ACF Pro installations..."
mapfile -t dirs < <(locate --regex "$PLUGIN_DIR_PATTERN")
if [ ${#dirs[@]} -eq 0 ]; then
    echo "No ACF Pro installations found."
    echo "Note: Make sure to run 'sudo updatedb' if you expect to find installations."
    exit 1
fi

echo "Found ${#dirs[@]} ACF Pro installation(s)"
continue_all=0

# Process each ACF Pro installation
for dir in "${dirs[@]}"; do
    if [ $continue_all -eq 0 ]; then
        check_continue "$dir"
        status=$?
        
        case $status in
            0) : ;;  # Continue with current directory
            1) echo "Script terminated by user."; exit 0 ;;
            2) continue_all=1 ;;  # Process all remaining directories automatically
        esac
    fi
    
    process_directory "$dir"
    echo "----------------------------------------"
done

echo "ACF Pro update script completed."

################################################################################
# Usage Instructions
################################################################################
# To use this script:
#
# 1. Update the ZIP_FILE variable at the top of the script to point to your
#    ACF Pro ZIP file location
#
# 2. Make sure the locate database is updated:
#    $ sudo updatedb
#
# 3. Run the script with sudo:
#    $ sudo ./acf_pro_update.sh
#
# The script will:
# - Find all ACF Pro installations
# - Ask for confirmation before processing each directory
# - Update each installation while preserving permissions
#
# Options during execution:
# y - Process current directory
# n - Stop script
# a - Process all remaining directories automatically

Comparison with Alternative Solutions

Feature This Script WP-CLI Manual Update
Batch Processing Yes Limited No
Permission Preservation Yes Yes Manual
Interactive Control Yes No Yes

Usage Tips and Best Practices

  1. Always keep a backup of your WordPress installations before running the script
  2. Test the script on a single installation first using the interactive mode
  3. Ensure the ACF Pro ZIP file is properly downloaded and placed in the correct location
  4. Run the script during low-traffic periods
  5. Monitor the script output for any potential issues

Common Issues and Solutions

Permission Errors

If you encounter permission errors, ensure you're running the script with sufficient privileges (usually as the web server user or via sudo).

Locate Database Issues

If the script doesn't find all installations, update the locate database:

sudo updatedb

Conclusion

This bash script provides an efficient solution for managing ACF Pro updates across multiple WordPress installations. It combines automation with careful permission handling and interactive control, making it a valuable tool for server administrators and WordPress developers managing multiple sites.

Future Improvements

Consider these potential enhancements:

  • Add logging functionality
  • Implement automatic backup before updates
  • Add support for other premium plugins
  • Include error notification via email