mirror of
https://gh.wpcy.net/https://github.com/CaptainCore/do.git
synced 2026-04-17 21:52:19 +08:00
412 lines
No EOL
17 KiB
Bash
412 lines
No EOL
17 KiB
Bash
# ----------------------------------------------------
|
||
# Finds files that have been recently modified.
|
||
# ----------------------------------------------------
|
||
function find_recent_files() {
|
||
local days="${1:-1}" # Default to 1 day if no argument is provided
|
||
|
||
# Validate that the input is a number
|
||
if ! [[ "$days" =~ ^[0-9]+$ ]]; then
|
||
echo "❌ Error: Please provide a valid number of days." >&2
|
||
echo "Usage: _do find recent-files <days>" >&2
|
||
return 1
|
||
fi
|
||
|
||
echo "🔎 Searching for files modified in the last $days day(s)..."
|
||
echo
|
||
|
||
# Check the operating system to use the correct `find` command syntax.
|
||
# The `-printf` option is not available on macOS/BSD `find`.
|
||
if [[ "$(uname)" == "Darwin" ]]; then
|
||
# On macOS, use -exec with `stat` for formatted, sortable output.
|
||
# -f "%Sm %N" formats the output: Modification time, then file name.
|
||
# -t "%Y-%m-%d %H:%M:%S" specifies the timestamp format for sorting.
|
||
find . -type f -mtime "-${days}" -exec stat -f "%Sm %N" -t "%Y-%m-%d %H:%M:%S" {} + | sort -r
|
||
else
|
||
# On Linux, the more efficient -printf option is available.
|
||
find . -type f -mtime "-${days}" -printf "%TY-%Tm-%Td %TH:%M:%S %p\n" | sort -r
|
||
fi
|
||
|
||
if [ $? -ne 0 ]; then
|
||
echo "❌ Error: The 'find' command failed to execute." >&2
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# ----------------------------------------------------
|
||
# Identifies plugins that may be slowing down WP-CLI command execution.
|
||
# ----------------------------------------------------
|
||
function find_slow_plugins() {
|
||
local page_to_check="${1}"
|
||
|
||
_get_wp_execution_time() {
|
||
local output
|
||
output=$("$WP_CLI_CMD" "$@" --debug 2>&1)
|
||
echo "$output" | perl -ne '/Debug \(bootstrap\): Running command: .+\(([^s]+s)/ && print $1'
|
||
}
|
||
if ! setup_wp_cli; then echo "❌ Error: WP-CLI (wp command) not found." >&2; return 1; fi
|
||
if ! "$WP_CLI_CMD" core is-installed --quiet; then echo "❌ Error: This does not appear to be a WordPress installation." >&2; return 1; fi
|
||
|
||
local base_command_args=("plugin" "list")
|
||
local skip_argument="--skip-plugins"
|
||
local description="wp plugin list --debug"
|
||
|
||
if [ -n "$page_to_check" ]; then
|
||
echo "🚀 WordPress Plugin Performance Test for page: '$page_to_check' 🚀"
|
||
description="wp render \"$page_to_check\" --debug"
|
||
|
||
# Check for wp render and install if missing
|
||
if ! "$WP_CLI_CMD" help render &> /dev/null; then
|
||
echo "ℹ️ 'wp render' command not found. Installing 'render-command' plugin..."
|
||
if ! "$WP_CLI_CMD" plugin install https://github.com/austinginder/render-command/releases/latest/download/render-command.zip --activate --force; then
|
||
echo "❌ Error: Failed to install 'render-command' plugin. Aborting." >&2
|
||
return 1
|
||
fi
|
||
echo "✅ 'render-command' plugin installed successfully."
|
||
fi
|
||
|
||
# Update command variables to use 'wp render'
|
||
base_command_args=("render" "$page_to_check")
|
||
skip_argument="--without-plugin"
|
||
else
|
||
echo "🚀 WordPress Plugin Performance Test 🚀"
|
||
fi
|
||
|
||
echo "This script measures the execution time of '$description' under various conditions."
|
||
echo ""
|
||
echo "📋 Initial Baseline Measurements for '$description':"
|
||
|
||
local base_time_s
|
||
printf " ⏳ Measuring base time (ALL plugins & theme active)... "
|
||
base_time_s=$(_get_wp_execution_time "${base_command_args[@]}")
|
||
if [[ -z "$base_time_s" ]]; then
|
||
echo "❌ Error: Could not measure base execution time." >&2
|
||
return 1
|
||
fi
|
||
echo "Base time: $base_time_s"
|
||
echo ""
|
||
|
||
local active_plugins=()
|
||
while IFS= read -r line; do
|
||
active_plugins+=("$line")
|
||
done < <("$WP_CLI_CMD" plugin list --field=name --status=active)
|
||
|
||
if [[ ${#active_plugins[@]} -eq 0 ]]; then
|
||
echo "ℹ️ No active plugins found to test."
|
||
return 0
|
||
fi
|
||
|
||
echo "📊 Measuring impact of individual plugins (compared to '${base_time_s}' base time):"
|
||
echo "A larger positive 'Impact' suggests the plugin contributes more to the load time of this specific WP-CLI command."
|
||
echo "---------------------------------------------------------------------------------"
|
||
printf "%-40s | %-15s | %-15s\n" "Plugin Skipped" "Time w/ Skip" "Impact (Base-Skip)"
|
||
echo "---------------------------------------------------------------------------------"
|
||
local results=()
|
||
for plugin in "${active_plugins[@]}"; do
|
||
# Skip the render-command plugin itself when using the render method
|
||
if [[ -n "$page_to_check" && "$plugin" == "render-command" ]]; then
|
||
continue
|
||
fi
|
||
|
||
local time_with_skip_s
|
||
time_with_skip_s=$(_get_wp_execution_time "${base_command_args[@]}" "${skip_argument}=$plugin")
|
||
|
||
if [[ -n "$time_with_skip_s" ]]; then
|
||
local diff_s
|
||
diff_s=$(awk -v base="${base_time_s%s}" -v skip="${time_with_skip_s%s}" 'BEGIN { printf "%.3f", base - skip }')
|
||
local impact_sign=""
|
||
if [[ $(awk -v diff="$diff_s" 'BEGIN { print (diff > 0) }') -eq 1 ]]; then
|
||
impact_sign="+"
|
||
fi
|
||
results+=("$(printf "%.3f" "$diff_s")|$plugin|$time_with_skip_s|${impact_sign}${diff_s}s")
|
||
else
|
||
results+=("0.000|$plugin|Error|Error measuring")
|
||
fi
|
||
done
|
||
|
||
local sorted_results=()
|
||
while IFS= read -r line; do
|
||
sorted_results+=("$line")
|
||
done < <(printf "%s\n" "${results[@]}" | sort -t'|' -k1,1nr)
|
||
|
||
for result_line in "${sorted_results[@]}"; do
|
||
local p_name
|
||
p_name=$(echo "$result_line" | cut -d'|' -f2)
|
||
local t_skip
|
||
t_skip=$(echo "$result_line" | cut -d'|' -f3)
|
||
local i_str
|
||
i_str=$(echo "$result_line" | cut -d'|' -f4)
|
||
printf "%-40s | %-15s | %-15s\n" "$p_name" "$t_skip" "$i_str"
|
||
done
|
||
echo "---------------------------------------------------------------------------------"
|
||
echo ""
|
||
echo "✅ Test Complete"
|
||
echo "💡 Note: This measures impact on a specific WP-CLI command. For front-end or"
|
||
echo " admin profiling, consider using a plugin like Query Monitor or New Relic."
|
||
echo ""
|
||
}
|
||
|
||
# ----------------------------------------------------
|
||
# Detects plugins that are active but hidden from the standard plugin list.
|
||
# ----------------------------------------------------
|
||
function find_hidden_plugins() {
|
||
# --- Pre-flight Checks ---
|
||
if ! setup_wp_cli; then echo "❌ Error: WP-CLI not found." >&2; return 1; fi
|
||
if ! "$WP_CLI_CMD" core is-installed --quiet; then echo "❌ Error: This does not appear to be a WordPress installation." >&2; return 1; fi
|
||
if ! setup_gum; then return 1; fi
|
||
|
||
echo "🚀 Checking for hidden WordPress plugins..."
|
||
|
||
# Get the standard list of active plugins
|
||
local active_plugins
|
||
active_plugins=$("$WP_CLI_CMD" plugin list --field=name --status=active)
|
||
|
||
# Get the "raw" list of active plugins by skipping themes and other plugins
|
||
local active_plugins_raw
|
||
active_plugins_raw=$("$WP_CLI_CMD" plugin list --field=name --status=active --skip-themes --skip-plugins)
|
||
|
||
local regular_count
|
||
regular_count=$(echo "$active_plugins" | wc -l | xargs)
|
||
local raw_count
|
||
raw_count=$(echo "$active_plugins_raw" | wc -l | xargs)
|
||
|
||
|
||
# Compare the counts of the two lists.
|
||
if [[ "$regular_count" == "$raw_count" ]]; then
|
||
echo "✅ No hidden plugins detected. The standard and raw plugin lists match ($regular_count plugins)."
|
||
return 0
|
||
fi
|
||
|
||
# If the counts differ, find the plugins that are in the raw list but not the standard one.
|
||
echo "⚠️ Found a discrepancy between plugin lists!"
|
||
echo " - Standard list shows: $regular_count active plugins."
|
||
echo " - Raw list shows: $raw_count active plugins."
|
||
echo
|
||
|
||
# Use 'comm' to find lines unique to the raw list.
|
||
local hidden_plugins
|
||
hidden_plugins=$(comm -13 <(echo "$active_plugins" | sort) <(echo "$active_plugins_raw" | sort))
|
||
|
||
if [ -z "$hidden_plugins" ]; then
|
||
echo "ℹ️ Could not isolate the specific hidden plugins, but a discrepancy exists."
|
||
else
|
||
echo "--- Found Hidden Plugin(s) ---"
|
||
# Loop through each hidden plugin and get its details
|
||
while IFS= read -r plugin; do
|
||
if [ -z "$plugin" ]; then continue; fi
|
||
|
||
"$GUM_CMD" log --level warn "Details for: $plugin"
|
||
|
||
# Get plugin details in CSV format and pipe to gum for a clean table printout.
|
||
"$WP_CLI_CMD" plugin get "$plugin" --skip-plugins --skip-themes --format=csv | \
|
||
"$GUM_CMD" table --separator "," --widths=15,0 --print
|
||
|
||
echo
|
||
done <<< "$hidden_plugins"
|
||
echo "💡 These plugins are active but may be hidden from the admin view or standard WP-CLI list."
|
||
echo " Common offenders are management plugins (like ManageWP's 'worker') or potentially malicious code."
|
||
fi
|
||
}
|
||
|
||
# ----------------------------------------------------
|
||
# Scans for potential malware and verifies WordPress core/plugin integrity.
|
||
# ----------------------------------------------------
|
||
function find_malware() {
|
||
# --- Pre-flight Checks ---
|
||
if ! setup_wp_cli; then echo "❌ Error: WP-CLI not found." >&2; return 1; fi
|
||
if ! "$WP_CLI_CMD" core is-installed --quiet; then echo "❌ Error: This does not appear to be a WordPress installation." >&2; return 1; fi
|
||
if ! command -v grep &> /dev/null; then echo "❌ Error: 'grep' command not found." >&2; return 1; fi
|
||
if ! setup_gum; then return 1; fi
|
||
|
||
echo "🚀 Starting malware scan..."
|
||
echo "This process will check for suspicious code patterns and verify core/plugin file integrity."
|
||
echo
|
||
|
||
# --- 1. Hunt for suspicious PHP code ---
|
||
echo "--- Step 1/3: Searching for suspicious PHP code patterns... ---"
|
||
local suspicious_patterns=(
|
||
'eval(base64_decode('
|
||
'eval(gzinflate('
|
||
'eval(gzuncompress('
|
||
'eval(str_rot13('
|
||
'preg_replace.*\/e'
|
||
'create_function'
|
||
'FilesMan'
|
||
'c99shell'
|
||
'r57shell'
|
||
'shell_exec('
|
||
'passthru('
|
||
'system('
|
||
'phpinfo('
|
||
'assert('
|
||
)
|
||
|
||
local found_suspicious_files=false
|
||
local combined_pattern
|
||
combined_pattern=$(IFS='|'; echo "${suspicious_patterns[*]}")
|
||
local search_results
|
||
search_results=$(grep -rn --include='*.php' -iE "$combined_pattern" . 2>/dev/null)
|
||
|
||
if [ -n "$search_results" ]; then
|
||
echo "⚠️ Found potentially malicious code in the following files:"
|
||
echo "-----------------------------------------------------"
|
||
echo "$search_results"
|
||
echo "-----------------------------------------------------"
|
||
echo "💡 Review these files carefully. They may contain legitimate code that matches these patterns."
|
||
found_suspicious_files=true
|
||
else
|
||
echo "✅ No suspicious code patterns found."
|
||
fi
|
||
echo
|
||
|
||
# --- 2. Verify WordPress Core Checksums ---
|
||
echo "--- Step 2/3: Verifying WordPress core file integrity... ---"
|
||
if ! "$WP_CLI_CMD" core verify-checksums --skip-plugins --skip-themes; then
|
||
echo "⚠️ WordPress core verification failed. The files listed above may have been modified."
|
||
else
|
||
echo "✅ WordPress core files verified successfully."
|
||
fi
|
||
echo
|
||
|
||
# --- 3. Verify Plugin Checksums ---
|
||
echo "--- Step 3/3: Verifying plugin file integrity (from wordpress.org)... ---"
|
||
local stderr_file_plugin
|
||
stderr_file_plugin=$(mktemp)
|
||
|
||
local plugin_csv_data
|
||
plugin_csv_data=$("$WP_CLI_CMD" plugin verify-checksums --all --format=csv --skip-plugins --skip-themes --quiet 2> "$stderr_file_plugin")
|
||
local plugin_checksum_status=$?
|
||
|
||
local plugin_summary_error
|
||
plugin_summary_error=$(cat "$stderr_file_plugin")
|
||
rm "$stderr_file_plugin"
|
||
|
||
if [ $plugin_checksum_status -ne 0 ]; then
|
||
echo "⚠️ Plugin verification encountered an error or found mismatches."
|
||
|
||
# Check if there is any CSV data to display
|
||
if [[ -n "$plugin_csv_data" ]]; then
|
||
echo "$plugin_csv_data" | "$GUM_CMD" table --separator "," --print
|
||
fi
|
||
|
||
# Display the summary error if it exists
|
||
if [ -n "$plugin_summary_error" ]; then
|
||
echo "$plugin_summary_error"
|
||
fi
|
||
echo "💡 This may include plugins not in the wordpress.org directory (premium plugins) or modified files."
|
||
else
|
||
echo "✅ All plugins from wordpress.org verified successfully."
|
||
fi
|
||
echo
|
||
|
||
echo "✅ Malware scan complete."
|
||
}
|
||
|
||
# ----------------------------------------------------
|
||
# Finds outdated or invalid PHP opening tags in PHP files.
|
||
# ----------------------------------------------------
|
||
function find_outdated_php_tags() {
|
||
local search_dir="${1:-.}"
|
||
|
||
# Ensure the search directory ends with a slash for consistency
|
||
if [[ "${search_dir: -1}" != "/" ]]; then
|
||
search_dir+="/"
|
||
fi
|
||
|
||
if [ ! -d "$search_dir" ]; then
|
||
echo "❌ Error: Directory '$search_dir' not found." >&2
|
||
return 1
|
||
fi
|
||
|
||
echo "🚀 Searching for outdated PHP tags in '${search_dir}'..."
|
||
echo "This can take a moment for large directories."
|
||
echo
|
||
|
||
# This new, more portable method first finds all lines with '<?',
|
||
# then filters out the lines containing valid tags like '<?php', '<?=', or '<?xml'.
|
||
# This avoids reliance on potentially unsupported 'grep -P' features.
|
||
local initial_results
|
||
initial_results=$(grep --include="*.php" --line-number --recursive '<?' "$search_dir" 2>/dev/null \
|
||
| grep -v -F -e '<?php' -e '<?=' -e '<?xml' \
|
||
| grep --color=always -e '<?' -e '$^'
|
||
)
|
||
|
||
# Filter out common false positives from comments, strings, etc.
|
||
local found_tags
|
||
found_tags=$(echo "$initial_results" \
|
||
| grep -v -F -e "strpos(" -e "str_replace(" \
|
||
| grep -v -E "^[^:]*:[^:]*:\s*(\*|//|#)|'\<\?'|\"\<\?\"" \
|
||
)
|
||
|
||
if [ -z "$found_tags" ]; then
|
||
echo "✅ No outdated PHP tags were found (after filtering common false positives)."
|
||
else
|
||
echo "⚠️ Found potentially outdated PHP tags in the following files:"
|
||
echo "-----------------------------------------------------"
|
||
# The output from grep is already well-formatted.
|
||
echo "$found_tags"
|
||
echo "-----------------------------------------------------"
|
||
# Use single quotes instead of backticks to prevent command execution.
|
||
echo "Recommendation: Replace all short tags like '<?' with the full '<?php' tag."
|
||
fi
|
||
}
|
||
|
||
# ----------------------------------------------------
|
||
# Identifies a plugin that may be causing WP-CLI commands to hang or time out.
|
||
# ----------------------------------------------------
|
||
function find_stuck_plugin() {
|
||
# --- Pre-flight Checks ---
|
||
if ! setup_wp_cli; then echo " Error: WP-CLI not found." >&2; return 1; fi
|
||
if ! "$WP_CLI_CMD" core is-installed --quiet; then echo " Error: This does not appear to be a WordPress installation." >&2; return 1; fi
|
||
if ! command -v timeout &> /dev/null; then echo " Error: 'timeout' command not found. This is required to detect hanging processes." >&2; return 1; fi
|
||
|
||
# --- Baseline Check ---
|
||
echo " Performing a baseline check to confirm WP-CLI is hanging..."
|
||
timeout 3s "$WP_CLI_CMD" option get home >/dev/null 2>&1
|
||
|
||
if [ $? -eq 0 ]; then
|
||
echo " Baseline check successful. WP-CLI doesn't appear to be hanging."
|
||
return 0
|
||
else
|
||
echo " Baseline check timed out. Confirmed that WP-CLI is hanging, proceeding with test."
|
||
fi
|
||
|
||
echo
|
||
echo " 🚀 Starting stuck plugin check..."
|
||
echo " This will test each active plugin to see if skipping it allows WP-CLI to respond quickly."
|
||
echo
|
||
|
||
# --- List of active plugins to test ---
|
||
local plugins
|
||
plugins=$("$WP_CLI_CMD" plugin list --field=name --status=active --skip-plugins)
|
||
|
||
if [ -z "$plugins" ]; then
|
||
echo " No active plugins found to test."
|
||
return 0
|
||
fi
|
||
|
||
# --- Loop through each plugin ---
|
||
for plugin in $plugins; do
|
||
echo -n " Testing with '$plugin' skipped..."
|
||
|
||
# Run the WP-CLI command with a 3-second timeout.
|
||
# We silence the output since we only care if it succeeds.
|
||
timeout 3s "$WP_CLI_CMD" option get home --skip-plugins="$plugin" >/dev/null 2>&1
|
||
|
||
# Check the exit code of the last command
|
||
if [ $? -eq 0 ]; then
|
||
# An exit code of 0 means the command completed successfully within the time limit.
|
||
echo " ✅ SUCCESS!"
|
||
echo "--------------------------------------------------------"
|
||
echo " Found the culprit! The site responded quickly when skipping:"
|
||
echo " ➡️ $plugin"
|
||
echo "--------------------------------------------------------"
|
||
return 0
|
||
else
|
||
# A non-zero exit code means it timed out or failed.
|
||
echo " ❌ Timeout."
|
||
fi
|
||
done
|
||
|
||
echo "--------------------------------------------------------"
|
||
echo " ⏹️ Finished testing all plugins. No single plugin could be identified as the culprit."
|
||
} |