Files
Linux-Server-Management-Too…/modules/website/wordpress-cron-manager.sh
T
cschantz b213d9ef3a Add revert functionality to WordPress Cron Manager
New Revert Options:
- Option 6: Re-enable wp-cron for specific domain
- Option 7: Re-enable wp-cron for specific user (all sites)
- Option 8: Re-enable wp-cron server-wide (all sites)

Revert Function Features:
 Safely removes DISABLE_WP_CRON from wp-config.php
 Automatic backup before changes
 Verification of successful removal
 Auto-rollback on failure
 Removes cron jobs from user crontabs
 Batch processing for multiple sites
 Summary reporting

Menu Organization:
- Grouped options by function (Enable/Revert/Status)
- Color-coded sections (Green/Yellow/Cyan)
- Clear labeling of what each option does

Revert Process:
1. Backup wp-config.php
2. Remove DISABLE_WP_CRON line completely
3. Verify removal was successful
4. Remove wp-cron.php entries from user crontab
5. Provide feedback and summary

Safety Features:
- Won't break sites if DISABLE_WP_CRON not found
- Preserves other cron jobs when removing wp-cron entries
- Individual site failures don't stop batch operations
- Clear feedback on what was changed
2025-11-07 17:12:26 -05:00

741 lines
24 KiB
Bash
Executable File

#!/bin/bash
################################################################################
# WordPress Cron Manager
################################################################################
# Purpose: Disable wp-cron and convert to real system cron jobs
# Features:
# - Detect all WordPress installations
# - Disable DISABLE_WP_CRON in wp-config.php
# - Add proper cron jobs for scheduled tasks
# - Server-wide, per-user, or per-domain operations
################################################################################
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
source "$SCRIPT_DIR/lib/common-functions.sh"
source "$SCRIPT_DIR/lib/system-detect.sh"
if [ "$EUID" -ne 0 ]; then
print_error "This script must be run as root"
exit 1
fi
# Global counter for staggering cron times
CRON_OFFSET=0
# Function to generate staggered cron time
# Distributes jobs across 15 minutes to avoid load spikes
generate_staggered_cron() {
local minute=$((CRON_OFFSET % 15))
# Create pattern: 0,15,30,45 but offset by the calculated minute
local minutes=""
for base in 0 15 30 45; do
local actual_minute=$(( (base + minute) % 60 ))
if [ -z "$minutes" ]; then
minutes="$actual_minute"
else
minutes="$minutes,$actual_minute"
fi
done
# Increment offset for next site (wraps at 15)
CRON_OFFSET=$((CRON_OFFSET + 1))
echo "$minutes * * * *"
}
# Function to safely modify wp-config.php to disable wp-cron
# Returns 0 on success, 1 on failure
disable_wpcron_in_config() {
local wp_config="$1"
# Check if file exists and is writable
if [ ! -f "$wp_config" ] || [ ! -w "$wp_config" ]; then
return 1
fi
# Check if DISABLE_WP_CRON already exists (not commented)
if grep -E "^[^/]*define\s*\(\s*['\"]DISABLE_WP_CRON['\"]" "$wp_config" >/dev/null 2>&1; then
# Line exists, modify it to set true
sed -i.wpbak "s/^\([^/]*\)define\s*(\s*['\"]DISABLE_WP_CRON['\"]\s*,\s*[^)]*)/\1define('DISABLE_WP_CRON', true)/" "$wp_config"
else
# Line doesn't exist, add it after <?php
# First, check if <?php exists
if ! grep -q "<?php" "$wp_config"; then
return 1
fi
# Add the define right after <?php, but only if not already present
if ! grep -q "DISABLE_WP_CRON" "$wp_config"; then
sed -i.wpbak "/<?php/a \\
define('DISABLE_WP_CRON', true);" "$wp_config"
fi
fi
# Verify the change was successful
if grep -E "^[^/]*define\s*\(\s*['\"]DISABLE_WP_CRON['\"]\s*,\s*true\s*\)" "$wp_config" >/dev/null 2>&1; then
# Remove backup if successful
rm -f "${wp_config}.wpbak"
return 0
else
# Restore backup if verification failed
if [ -f "${wp_config}.wpbak" ]; then
mv "${wp_config}.wpbak" "$wp_config"
fi
return 1
fi
}
# Function to safely re-enable wp-cron (revert changes)
# Returns 0 on success, 1 on failure
enable_wpcron_in_config() {
local wp_config="$1"
# Check if file exists and is writable
if [ ! -f "$wp_config" ] || [ ! -w "$wp_config" ]; then
return 1
fi
# Check if DISABLE_WP_CRON exists and is set to true
if grep -E "^[^/]*define\s*\(\s*['\"]DISABLE_WP_CRON['\"]\s*,\s*true\s*\)" "$wp_config" >/dev/null 2>&1; then
# Remove or comment out the line
sed -i.wpbak "/^[^/]*define\s*(\s*['\"]DISABLE_WP_CRON['\"]\s*,\s*true\s*)/d" "$wp_config"
# Verify removal was successful
if ! grep -E "^[^/]*define\s*\(\s*['\"]DISABLE_WP_CRON['\"]\s*,\s*true\s*\)" "$wp_config" >/dev/null 2>&1; then
rm -f "${wp_config}.wpbak"
return 0
else
# Restore backup if removal failed
if [ -f "${wp_config}.wpbak" ]; then
mv "${wp_config}.wpbak" "$wp_config"
fi
return 1
fi
else
# DISABLE_WP_CRON not found or already disabled
return 0
fi
}
clear
print_banner "WordPress Cron Manager"
echo ""
echo -e "${BOLD}What would you like to do?${NC}"
echo ""
echo -e "${GREEN}Enable System Cron:${NC}"
echo " 1) Scan for WordPress installations"
echo " 2) Disable wp-cron for specific domain"
echo " 3) Disable wp-cron for specific user (all their WP sites)"
echo " 4) Disable wp-cron server-wide (all WordPress sites)"
echo ""
echo -e "${YELLOW}Revert to WP-Cron:${NC}"
echo " 6) Re-enable wp-cron for specific domain"
echo " 7) Re-enable wp-cron for specific user (all their WP sites)"
echo " 8) Re-enable wp-cron server-wide (all WordPress sites)"
echo ""
echo -e "${CYAN}Status & Information:${NC}"
echo " 5) Check wp-cron status for domain/user"
echo ""
echo " 0) Return to menu"
echo ""
echo -n "Select option [0]: "
read -r choice
choice="${choice:-0}"
case "$choice" in
1)
# Scan for WordPress installations
echo ""
print_banner "WordPress Installation Scanner"
echo ""
echo "Scanning for WordPress installations..."
echo ""
# Find all wp-config.php files in home directories
wp_sites=$(find /home/*/public_html -name "wp-config.php" -type f 2>/dev/null)
if [ -z "$wp_sites" ]; then
echo -e "${YELLOW}No WordPress installations found${NC}"
else
count=0
echo -e "${BOLD}Found WordPress Installations:${NC}"
echo ""
while IFS= read -r config_file; do
count=$((count + 1))
# Extract info
site_path=$(dirname "$config_file")
user=$(echo "$site_path" | cut -d'/' -f3)
# Try to find domain
domain="(unknown domain)"
if [ -f "/var/cpanel/userdata/$user/main" ]; then
domain=$(grep -m1 "^servername:" "/var/cpanel/userdata/$user/main" 2>/dev/null | awk '{print $2}')
fi
# Check if wp-cron is disabled
if grep -q "define.*DISABLE_WP_CRON.*true" "$config_file" 2>/dev/null; then
status="${GREEN}✓ Disabled (using system cron)${NC}"
else
status="${YELLOW}⚠ Enabled (default wp-cron)${NC}"
fi
echo -e "${count}. ${BOLD}$domain${NC}"
echo " Path: $site_path"
echo " User: $user"
echo " Status: $status"
echo ""
done <<< "$wp_sites"
echo -e "${CYAN}Total WordPress installations: $count${NC}"
fi
;;
2)
# Disable wp-cron for specific domain
echo ""
echo -n "Enter domain name: "
read -r domain
if [ -z "$domain" ]; then
print_error "Domain cannot be empty"
press_enter
exit 1
fi
# Find WordPress installation for this domain
echo ""
echo "Searching for WordPress installation for $domain..."
# Try to find via cPanel user data
wp_config=""
for userdata_file in /var/cpanel/userdata/*/main; do
if grep -q "^servername: $domain" "$userdata_file" 2>/dev/null; then
user=$(basename "$(dirname "$userdata_file")")
potential_config="/home/$user/public_html/wp-config.php"
if [ -f "$potential_config" ]; then
wp_config="$potential_config"
break
fi
fi
done
if [ -z "$wp_config" ]; then
print_error "WordPress installation not found for $domain"
press_enter
exit 1
fi
echo -e "${GREEN}Found WordPress:${NC} $wp_config"
echo ""
# Check if already disabled
if grep -q "define.*DISABLE_WP_CRON.*true" "$wp_config" 2>/dev/null; then
echo -e "${YELLOW}wp-cron is already disabled for this site${NC}"
echo ""
echo -n "Re-configure anyway? (y/n) [n]: "
read -r confirm
if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
press_enter
exit 0
fi
fi
# Backup wp-config.php
cp "$wp_config" "${wp_config}.backup-$(date +%Y%m%d-%H%M%S)"
echo -e "${GREEN}${NC} Backed up wp-config.php"
# Safely disable wp-cron in wp-config.php
if disable_wpcron_in_config "$wp_config"; then
echo -e "${GREEN}${NC} Set DISABLE_WP_CRON to true in wp-config.php"
else
print_error "Failed to modify wp-config.php"
echo " Please check file permissions and syntax"
press_enter
exit 1
fi
# Add cron job with staggered timing
site_path=$(dirname "$wp_config")
cron_cmd="cd $site_path && /usr/bin/php -q wp-cron.php >/dev/null 2>&1"
# Add to user's crontab
user=$(echo "$site_path" | cut -d'/' -f3)
# Check if cron job already exists
if crontab -u "$user" -l 2>/dev/null | grep -q "$site_path.*wp-cron.php"; then
echo -e "${YELLOW}${NC} Cron job already exists for this site"
else
# Generate staggered cron time
cron_time=$(generate_staggered_cron)
(crontab -u "$user" -l 2>/dev/null; echo "$cron_time $cron_cmd") | crontab -u "$user" -
echo -e "${GREEN}${NC} Added cron job ($cron_time)"
fi
echo ""
print_success "WordPress cron converted to system cron for $domain"
echo ""
echo "Changes made:"
echo " • DISABLE_WP_CRON set to true in wp-config.php"
echo " • System cron job added (every 15 minutes)"
echo " • Backup saved: ${wp_config}.backup-*"
;;
3)
# Disable wp-cron for specific user
echo ""
echo -n "Enter cPanel username: "
read -r target_user
if [ -z "$target_user" ]; then
print_error "Username cannot be empty"
press_enter
exit 1
fi
if [ ! -d "/home/$target_user" ]; then
print_error "User $target_user does not exist"
press_enter
exit 1
fi
echo ""
echo "Searching for WordPress installations for user: $target_user"
echo ""
wp_configs=$(find "/home/$target_user" -name "wp-config.php" -type f 2>/dev/null)
if [ -z "$wp_configs" ]; then
print_error "No WordPress installations found for $target_user"
press_enter
exit 1
fi
count=0
echo "$wp_configs" | while IFS= read -r wp_config; do
count=$((count + 1))
site_path=$(dirname "$wp_config")
echo -e "${BOLD}Site $count:${NC} $site_path"
# Backup
cp "$wp_config" "${wp_config}.backup-$(date +%Y%m%d-%H%M%S)" 2>/dev/null
echo " • Backed up wp-config.php"
# Safely disable wp-cron
if disable_wpcron_in_config "$wp_config"; then
echo " • Set DISABLE_WP_CRON to true"
else
echo "${YELLOW}Warning: Could not modify wp-config.php${NC}"
echo ""
continue
fi
# Add cron job with staggered timing
cron_cmd="cd $site_path && /usr/bin/php -q wp-cron.php >/dev/null 2>&1"
if ! crontab -u "$target_user" -l 2>/dev/null | grep -q "$site_path.*wp-cron.php"; then
cron_time=$(generate_staggered_cron)
(crontab -u "$target_user" -l 2>/dev/null; echo "$cron_time $cron_cmd") | crontab -u "$target_user" -
echo " • Added cron job ($cron_time)"
else
echo " • Cron job already exists"
fi
echo ""
done
print_success "All WordPress sites for $target_user converted to system cron"
;;
4)
# Server-wide conversion
echo ""
echo -e "${RED}${BOLD}WARNING: Server-Wide wp-cron Conversion${NC}"
echo ""
echo "This will:"
echo " • Find ALL WordPress installations on the server"
echo " • Disable wp-cron in each wp-config.php"
echo " • Add system cron jobs for each user"
echo ""
echo -n "Are you sure? Type 'yes' to confirm: "
read -r confirm
if [ "$confirm" != "yes" ]; then
echo "Cancelled"
press_enter
exit 0
fi
echo ""
echo "Scanning entire server for WordPress installations..."
echo ""
total=0
converted=0
wp_configs=$(find /home/*/public_html -name "wp-config.php" -type f 2>/dev/null)
if [ -z "$wp_configs" ]; then
echo -e "${YELLOW}No WordPress installations found${NC}"
press_enter
exit 0
fi
while IFS= read -r wp_config; do
total=$((total + 1))
site_path=$(dirname "$wp_config")
user=$(echo "$site_path" | cut -d'/' -f3)
echo -e "${BOLD}Processing:${NC} $site_path (user: $user)"
# Backup
cp "$wp_config" "${wp_config}.backup-$(date +%Y%m%d-%H%M%S)" 2>/dev/null
# Safely disable wp-cron
if ! disable_wpcron_in_config "$wp_config"; then
echo -e "${YELLOW}⚠ Failed to modify wp-config.php${NC}"
echo ""
continue
fi
# Add cron job with staggered timing
cron_cmd="cd $site_path && /usr/bin/php -q wp-cron.php >/dev/null 2>&1"
if ! crontab -u "$user" -l 2>/dev/null | grep -q "$site_path.*wp-cron.php"; then
cron_time=$(generate_staggered_cron)
(crontab -u "$user" -l 2>/dev/null; echo "$cron_time $cron_cmd") | crontab -u "$user" - 2>/dev/null
echo " Cron: $cron_time"
fi
converted=$((converted + 1))
echo -e "${GREEN}${NC} Converted"
echo ""
done <<< "$wp_configs"
echo ""
print_success "Server-wide conversion complete"
echo ""
echo "Summary:"
echo " • Total WordPress sites found: $total"
echo " • Successfully converted: $converted"
;;
5)
# Check status
echo ""
echo "Check wp-cron status for:"
echo " 1) Specific domain"
echo " 2) Specific user"
echo ""
echo -n "Select [1]: "
read -r check_choice
check_choice="${check_choice:-1}"
if [ "$check_choice" = "1" ]; then
echo ""
echo -n "Enter domain name: "
read -r domain
# Find WordPress for domain
wp_config=""
for userdata_file in /var/cpanel/userdata/*/main; do
if grep -q "^servername: $domain" "$userdata_file" 2>/dev/null; then
user=$(basename "$(dirname "$userdata_file")")
potential_config="/home/$user/public_html/wp-config.php"
if [ -f "$potential_config" ]; then
wp_config="$potential_config"
break
fi
fi
done
if [ -z "$wp_config" ]; then
print_error "WordPress not found for $domain"
press_enter
exit 1
fi
echo ""
echo -e "${BOLD}WordPress Cron Status for $domain${NC}"
echo ""
echo "Config file: $wp_config"
echo ""
if grep -q "define.*DISABLE_WP_CRON.*true" "$wp_config" 2>/dev/null; then
echo -e "wp-cron: ${GREEN}DISABLED${NC} (using system cron)"
# Check for cron job
site_path=$(dirname "$wp_config")
user=$(echo "$site_path" | cut -d'/' -f3)
if crontab -u "$user" -l 2>/dev/null | grep -q "wp-cron.php"; then
echo -e "System cron: ${GREEN}CONFIGURED${NC}"
echo ""
echo "Cron jobs:"
crontab -u "$user" -l 2>/dev/null | grep "wp-cron.php"
else
echo -e "System cron: ${RED}NOT CONFIGURED${NC}"
fi
else
echo -e "wp-cron: ${YELLOW}ENABLED${NC} (default WordPress cron)"
echo ""
echo "Recommendation: Disable wp-cron and use system cron for better performance"
fi
else
echo ""
echo -n "Enter cPanel username: "
read -r check_user
if [ ! -d "/home/$check_user" ]; then
print_error "User $check_user does not exist"
press_enter
exit 1
fi
echo ""
echo -e "${BOLD}WordPress Cron Status for user: $check_user${NC}"
echo ""
wp_configs=$(find "/home/$check_user" -name "wp-config.php" -type f 2>/dev/null)
if [ -z "$wp_configs" ]; then
echo "No WordPress installations found"
else
count=0
while IFS= read -r wp_config; do
count=$((count + 1))
site_path=$(dirname "$wp_config")
echo -e "${count}. ${BOLD}$site_path${NC}"
if grep -q "define.*DISABLE_WP_CRON.*true" "$wp_config" 2>/dev/null; then
echo " wp-cron: ${GREEN}DISABLED${NC}"
else
echo " wp-cron: ${YELLOW}ENABLED${NC}"
fi
echo ""
done <<< "$wp_configs"
# Show cron jobs
echo -e "${BOLD}Cron Jobs:${NC}"
if crontab -u "$check_user" -l 2>/dev/null | grep -q "wp-cron.php"; then
crontab -u "$check_user" -l 2>/dev/null | grep "wp-cron.php"
else
echo " No wp-cron jobs found"
fi
fi
fi
;;
6)
# Re-enable wp-cron for specific domain
echo ""
echo -n "Enter domain name: "
read -r domain
if [ -z "$domain" ]; then
print_error "Domain cannot be empty"
press_enter
exit 1
fi
# Find WordPress installation
wp_config=""
for userdata_file in /var/cpanel/userdata/*/main; do
if grep -q "^servername: $domain" "$userdata_file" 2>/dev/null; then
user=$(basename "$(dirname "$userdata_file")")
potential_config="/home/$user/public_html/wp-config.php"
if [ -f "$potential_config" ]; then
wp_config="$potential_config"
break
fi
fi
done
if [ -z "$wp_config" ]; then
print_error "WordPress installation not found for $domain"
press_enter
exit 1
fi
echo -e "${GREEN}Found WordPress:${NC} $wp_config"
echo ""
# Backup wp-config.php
cp "$wp_config" "${wp_config}.backup-$(date +%Y%m%d-%H%M%S)"
echo -e "${GREEN}${NC} Backed up wp-config.php"
# Re-enable wp-cron
if enable_wpcron_in_config "$wp_config"; then
echo -e "${GREEN}${NC} Removed DISABLE_WP_CRON from wp-config.php"
else
echo -e "${YELLOW}${NC} DISABLE_WP_CRON not found or already enabled"
fi
# Remove cron job
site_path=$(dirname "$wp_config")
user=$(echo "$site_path" | cut -d'/' -f3)
if crontab -u "$user" -l 2>/dev/null | grep -q "$site_path.*wp-cron.php"; then
crontab -u "$user" -l 2>/dev/null | grep -v "$site_path.*wp-cron.php" | crontab -u "$user" -
echo -e "${GREEN}${NC} Removed cron job from user crontab"
else
echo -e "${YELLOW}${NC} No cron job found for this site"
fi
echo ""
print_success "WordPress cron reverted to default for $domain"
;;
7)
# Re-enable wp-cron for specific user
echo ""
echo -n "Enter cPanel username: "
read -r target_user
if [ -z "$target_user" ]; then
print_error "Username cannot be empty"
press_enter
exit 1
fi
if [ ! -d "/home/$target_user" ]; then
print_error "User $target_user does not exist"
press_enter
exit 1
fi
echo ""
echo "Reverting WordPress installations for user: $target_user"
echo ""
wp_configs=$(find "/home/$target_user" -name "wp-config.php" -type f 2>/dev/null)
if [ -z "$wp_configs" ]; then
print_error "No WordPress installations found for $target_user"
press_enter
exit 1
fi
count=0
echo "$wp_configs" | while IFS= read -r wp_config; do
count=$((count + 1))
site_path=$(dirname "$wp_config")
echo -e "${BOLD}Site $count:${NC} $site_path"
# Backup
cp "$wp_config" "${wp_config}.backup-$(date +%Y%m%d-%H%M%S)" 2>/dev/null
echo " • Backed up wp-config.php"
# Re-enable wp-cron
if enable_wpcron_in_config "$wp_config"; then
echo " • Removed DISABLE_WP_CRON"
else
echo " • Already using default wp-cron"
fi
echo ""
done
# Remove all wp-cron jobs for this user
if crontab -u "$target_user" -l 2>/dev/null | grep -q "wp-cron.php"; then
crontab -u "$target_user" -l 2>/dev/null | grep -v "wp-cron.php" | crontab -u "$target_user" -
echo -e "${GREEN}${NC} Removed all wp-cron jobs from user crontab"
fi
print_success "All WordPress sites for $target_user reverted to default wp-cron"
;;
8)
# Server-wide revert
echo ""
echo -e "${RED}${BOLD}WARNING: Server-Wide Revert${NC}"
echo ""
echo "This will:"
echo " • Find ALL WordPress installations on the server"
echo " • Remove DISABLE_WP_CRON from each wp-config.php"
echo " • Remove all wp-cron system cron jobs"
echo ""
echo -n "Are you sure? Type 'yes' to confirm: "
read -r confirm
if [ "$confirm" != "yes" ]; then
echo "Cancelled"
press_enter
exit 0
fi
echo ""
echo "Scanning entire server for WordPress installations..."
echo ""
total=0
reverted=0
wp_configs=$(find /home/*/public_html -name "wp-config.php" -type f 2>/dev/null)
if [ -z "$wp_configs" ]; then
echo -e "${YELLOW}No WordPress installations found${NC}"
press_enter
exit 0
fi
while IFS= read -r wp_config; do
total=$((total + 1))
site_path=$(dirname "$wp_config")
user=$(echo "$site_path" | cut -d'/' -f3)
echo -e "${BOLD}Processing:${NC} $site_path (user: $user)"
# Backup
cp "$wp_config" "${wp_config}.backup-$(date +%Y%m%d-%H%M%S)" 2>/dev/null
# Re-enable wp-cron
if enable_wpcron_in_config "$wp_config"; then
reverted=$((reverted + 1))
echo -e "${GREEN}${NC} Reverted"
else
echo -e "${YELLOW}${NC} Already using default wp-cron"
fi
echo ""
done <<< "$wp_configs"
# Remove all wp-cron jobs from all users
echo ""
echo "Removing wp-cron jobs from user crontabs..."
for user_home in /home/*; do
user=$(basename "$user_home")
if crontab -u "$user" -l 2>/dev/null | grep -q "wp-cron.php"; then
crontab -u "$user" -l 2>/dev/null | grep -v "wp-cron.php" | crontab -u "$user" - 2>/dev/null
echo " • Removed cron jobs for user: $user"
fi
done
echo ""
print_success "Server-wide revert complete"
echo ""
echo "Summary:"
echo " • Total WordPress sites found: $total"
echo " • Successfully reverted: $reverted"
;;
0)
exit 0
;;
*)
print_error "Invalid option"
;;
esac
echo ""
press_enter