Last active
July 28, 2025 01:44
-
-
Save davemac/e9d000e82f4d130ffa400a1efa75f59f to your computer and use it in GitHub Desktop.
WordPress test plugins to isolate errorrs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/zsh | |
# WordPress Plugin Fatal Error Diagnostic Script | |
# | |
# Purpose: Systematically test individual plugins to isolate fatal error issues | |
# Setup: chmod +x plugin-memory.sh (make executable - only needed once) | |
# Usage: ./plugin-memory.sh (run from WordPress root directory) | |
# | |
# What it does: | |
# 1. Auto-detects site URL using wp-cli (wp option get home) | |
# 2. Auto-detects all currently active plugins using wp-cli | |
# 3. Tests each plugin individually by deactivating it | |
# 4. Clears debug log and makes a site request | |
# 5. Checks for fatal memory errors in wp-content/debug.log | |
# 6. Reactivates the plugin and moves to the next one | |
# 7. Saves detailed output to timestamped log file | |
# | |
# Key Features: | |
# - Fully automatic detection (site URL + active plugins) | |
# - Configurable skip list for critical plugins | |
# - macOS/zsh compatible (uses zsh array syntax) | |
# - Interactive mode - stops when culprit is found | |
# - Logging to both terminal and file | |
# | |
# Output: plugin_memory_test_YYYYMMDD_HHMMSS.txt with full test results | |
set -e # Exit on any error | |
# Create output file with timestamp | |
OUTPUT_FILE="plugin_memory_test_$(date +%Y%m%d_%H%M%S).txt" | |
# Function to output to both terminal and file | |
output() { | |
echo "$@" | tee -a "$OUTPUT_FILE" | |
} | |
# Configuration | |
LOG_FILE="wp-content/debug.log" | |
# Colours for output (only for terminal) | |
RED='\033[0;31m' | |
GREEN='\033[0;32m' | |
YELLOW='\033[1;33m' | |
NC='\033[0m' # No Colour | |
# Plugins to skip (add plugin names here that should never be tested) | |
# Example: critical security plugins, backup plugins, etc. | |
SKIP_PLUGINS="wordfence akismet updraftplus" | |
# Function to print coloured output | |
print_status() { | |
local colour=$1 | |
local message=$2 | |
echo -e "${colour}${message}${NC}" | tee -a "$OUTPUT_FILE" | |
} | |
# Initialize output file | |
echo "WordPress Plugin Memory Error Testing Script Output" > "$OUTPUT_FILE" | |
echo "Generated: $(date)" >> "$OUTPUT_FILE" | |
echo "========================================" >> "$OUTPUT_FILE" | |
# Check if we're in a WordPress directory | |
if [[ ! -f "wp-config.php" ]]; then | |
print_status $RED "Error: This script must be run from the WordPress root directory" | |
exit 1 | |
fi | |
print_status $YELLOW "Starting WordPress plugin memory error testing..." | |
output "Output will be saved to: $OUTPUT_FILE" | |
# Check wp-cli availability first | |
if ! command -v wp &> /dev/null; then | |
print_status $RED "Error: wp-cli is not installed or not in PATH" | |
print_status $YELLOW "Please install wp-cli: https://wp-cli.org/" | |
exit 1 | |
fi | |
# Auto-detect site URL using wp-cli | |
output "Detecting site URL..." | |
SITE_URL=$(wp option get home 2>/dev/null) | |
if [[ -z "$SITE_URL" ]]; then | |
print_status $RED "Error: Could not retrieve site URL" | |
print_status $YELLOW "Make sure wp-cli is working: wp option get home" | |
exit 1 | |
fi | |
print_status $YELLOW "Site URL: $SITE_URL" | |
print_status $YELLOW "Log file: $LOG_FILE" | |
output "" | |
# Auto-detect active plugins using wp-cli | |
output "Detecting active plugins..." | |
# Get list of active plugins | |
PLUGINS=$(wp plugin list --status=active --field=name 2>/dev/null) | |
if [[ -z "$PLUGINS" ]]; then | |
print_status $RED "Error: Could not retrieve active plugins list" | |
print_status $YELLOW "Make sure wp-cli is working: wp plugin list" | |
exit 1 | |
fi | |
# Convert to array and filter out skipped plugins | |
plugins_array=() | |
skip_array=(${=SKIP_PLUGINS}) | |
# Convert newline-separated plugin list to array | |
while IFS= read -r plugin; do | |
[[ -n "$plugin" ]] || continue # Skip empty lines | |
# Check if plugin should be skipped | |
skip_plugin=false | |
for skip in "${skip_array[@]}"; do | |
if [[ "$plugin" == "$skip" ]]; then | |
output "βοΈ Skipping plugin: $plugin (in skip list)" | |
skip_plugin=true | |
break | |
fi | |
done | |
if [[ "$skip_plugin" == false ]]; then | |
plugins_array+=("$plugin") | |
fi | |
done <<< "$PLUGINS" | |
# Display detected plugins | |
output "Found ${#plugins_array[@]} active plugins to test:" | |
for plugin in "${plugins_array[@]}"; do | |
output " - $plugin" | |
done | |
output "" | |
# Explain what we're looking for | |
print_status $YELLOW "π What this script detects:" | |
output " β’ Fatal memory errors: 'Allowed memory size of X bytes exhausted'" | |
output " β’ PHP fatal errors: 'PHP Fatal error' messages" | |
output " β’ Memory-related crashes that prevent site loading" | |
output "" | |
output "β Success criteria: Site loads without fatal errors when plugin is deactivated" | |
output "β Problem identified: Fatal errors disappear when specific plugin is deactivated" | |
output "" | |
# Pre-check: Verify there's actually a fatal error to solve | |
print_status $YELLOW "π¬ Pre-check: Testing site with all plugins active..." | |
output "Clearing debug log..." | |
rm "$LOG_FILE" 2>/dev/null && touch "$LOG_FILE" | |
output "Making test request to site..." | |
if curl -s --max-time 10 --connect-timeout 5 --insecure "$SITE_URL" > /dev/null 2>&1; then | |
output "Site request successful" | |
# Wait for logs to be written | |
sleep 1 | |
# Check for fatal errors | |
if ! grep -q "Fatal error" "$LOG_FILE" 2>/dev/null; then | |
print_status $GREEN "β No fatal errors found!" | |
output "" | |
output "The site is currently working fine with all plugins active." | |
output "This script is designed to isolate plugins causing fatal errors." | |
output "" | |
print_status $YELLOW "Possible reasons:" | |
output " β’ The issue has already been resolved" | |
output " β’ The error only occurs under specific conditions" | |
output " β’ The error is intermittent" | |
output " β’ The error is theme-related, not plugin-related" | |
output "" | |
output "If you're still experiencing issues, try:" | |
output " β’ Access different pages of your site" | |
output " β’ Check wp-content/debug.log manually" | |
output " β’ Use other diagnostic scripts in this directory" | |
output "" | |
output "Full output saved to: $OUTPUT_FILE" | |
exit 0 | |
else | |
print_status $RED "β Fatal errors detected!" | |
output "Error details:" | |
grep "Fatal error" "$LOG_FILE" 2>/dev/null | head -3 | while read -r error_line; do | |
output " $error_line" | |
done | |
output "" | |
print_status $YELLOW "Proceeding with plugin isolation testing..." | |
output "" | |
fi | |
else | |
print_status $RED "β οΈ Could not reach site - proceeding with testing anyway" | |
output "This might indicate a severe error that prevents site loading" | |
output "" | |
fi | |
for plugin in "${plugins_array[@]}"; do | |
output "Testing plugin: $plugin" | |
# Deactivate plugin (removed timeout - this was causing the hangs) | |
output " β Deactivating plugin..." | |
if wp plugin deactivate "$plugin" --quiet 2>/dev/null; then | |
output " β Plugin deactivated successfully" | |
# Clear log file (using method that works on macOS) | |
output " β Clearing log file..." | |
rm "$LOG_FILE" 2>/dev/null && touch "$LOG_FILE" | |
output " β Log file cleared successfully" | |
# Wait a moment for any pending operations | |
output " β Waiting 2 seconds for changes to take effect..." | |
sleep 2 | |
output " β Wait complete" | |
# Make request to site | |
output " β Making request to site ($SITE_URL)..." | |
output " β Running: curl -s --max-time 10 --connect-timeout 5 --insecure $SITE_URL" | |
if curl -s --max-time 10 --connect-timeout 5 --insecure "$SITE_URL" > /dev/null 2>&1; then | |
output " β Site request successful" | |
# Wait a moment for logs to be written | |
sleep 1 | |
# Check for fatal errors in log | |
output " β Checking log file for fatal errors..." | |
output " β Searching for pattern: 'Fatal error' in $LOG_FILE" | |
if ! grep -q "Fatal error" "$LOG_FILE" 2>/dev/null; then | |
print_status $GREEN "β Fatal error GONE when $plugin is deactivated. This is the culprit!" | |
# Ask if user wants to stop here | |
print_status $YELLOW "Found the problematic plugin: $plugin" | |
echo "Would you like to stop testing here? (y/n): " | |
read -r response | |
output "User response: $response" | |
if [[ "$response" =~ ^[Yy]$ ]]; then | |
print_status $YELLOW "Testing stopped at user request" | |
output "Plugin causing issues: $plugin" | |
# Reactivate the plugin before exiting | |
output "Reactivating problematic plugin..." | |
wp plugin activate "$plugin" --quiet 2>/dev/null | |
output "Full output saved to: $OUTPUT_FILE" | |
exit 0 | |
fi | |
else | |
print_status $RED "β Fatal error still present with $plugin deactivated" | |
output " β Error details:" | |
grep "Fatal error" "$LOG_FILE" 2>/dev/null | head -2 | while read -r error_line; do | |
output " $error_line" | |
done | |
fi | |
else | |
print_status $YELLOW "β οΈ Could not reach site or request failed" | |
fi | |
# Reactivate plugin (removed timeout) | |
output " β Reactivating plugin..." | |
if wp plugin activate "$plugin" --quiet 2>/dev/null; then | |
output " β Plugin reactivated successfully" | |
else | |
print_status $RED "Warning: Could not reactivate plugin '$plugin'" | |
fi | |
else | |
print_status $RED "Error: Could not deactivate plugin '$plugin'" | |
fi | |
output "---------------------------------" | |
done | |
print_status $YELLOW "Testing complete!" | |
output "Full output saved to: $OUTPUT_FILE" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment