Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.watchsyncrc*
watch-sync.sh
config.sh
1 change: 1 addition & 0 deletions .shellcheckrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
external-sources=true
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# WP-CLI scripts
This is a collection of miscellaneous scripts that utilize [WP-CLI](https://wp-cli.org/), the command line interface for WordPress.

# Usage
Clone this repo and configure the path in `source/config.sh`. Make the scripts executable as needed (i.e. `chmod +x wpcli-scripts/*.sh`).
80 changes: 80 additions & 0 deletions count-plugin.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#!/bin/env bash

# Set the exact slug of the plugin you want to check
plugin_slug='classic-editor';

source 'source/includes.sh';

# Requires 'bc' for floating-point percentage calculation
if ! command -v bc &> /dev/null; then
echo "Error: 'bc' (basic calculator) is not installed."
echo "Please install 'bc' to run this script."
exit 1
fi

# Initialize counters
active_count=0
failed_sites=0

# Get all site URLs into a bash array (ignores 'Loading...' line)
mapfile -t sites < <(wp_skip_all site list --field=url --quiet)

# Get total site count
total_sites=${#sites[@]}

if [[ $total_sites -eq 0 ]]; then
echo "No sites found."
exit 0
fi

echo "Auditing '$plugin_slug' plugin status across $total_sites sites..."
echo "---"

# Loop through each site and check plugin status.
for s in "${sites[@]}"; do

# Check if the plugin is active. Suppress errors for archived/deleted sites.
# Exits with 0 if active, 1 if inactive/not-installed.
wp_skip_all plugin is-active "$plugin_slug" --url="$s" >/dev/null 2>&1
plugin_status=$?

if [[ $plugin_status -eq 0 ]]; then
# Status 0: Plugin is ACTIVE
((active_count++))
echo "Site: $s | ACTIVE"
elif [[ $plugin_status -eq 1 ]]; then
# Status 1: Plugin is INACTIVE or not installed
echo "Site: $s | INACTIVE"
else
# Any other status: WP-CLI command failed
echo "Site: $s | FAILED to get status (site may be archived or deleted)"
((failed_sites++))
fi
done

# Calculate results. Base percentages only on sites we could successfully check.
total_checked=$((total_sites - failed_sites))
inactive_count=$((total_checked - active_count))

if [[ $total_checked -gt 0 ]]; then
# Use 'bc' for floating-point percentage calculation
active_perc=$(echo "scale=2; ($active_count / $total_checked) * 100" | bc)
inactive_perc=$(echo "scale=2; ($inactive_count / $total_checked) * 100" | bc)
else
active_perc="0.00"
inactive_perc="0.00"
fi

echo
echo "##################################################"
echo " Plugin Usage Report for: $plugin_slug"
echo "##################################################"

# Print the report
printf "Active: %-5s sites (%s%%)\n" "$active_count" "$active_perc"
printf "Inactive: %-5s sites (%s%%)\n" "$inactive_count" "$inactive_perc"
echo "---"
printf "Total Sites Checked: %s\n" "$total_checked"
if [[ $failed_sites -gt 0 ]]; then
printf "Sites Failed (skipped): %s\n" "$failed_sites"
fi
74 changes: 74 additions & 0 deletions count-themes.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/bin/env bash

# This script audits all sites in a WordPress Multisite network and provides a count and percentage
# for every active theme.

source 'source/includes.sh';

# Requires 'bc' for floating-point percentage calculation.
if ! command -v bc &> /dev/null; then
echo "Error: 'bc' (basic calculator) is not installed."
echo "Please install 'bc' to run this script."
exit 1
fi

# Declare an associative array to hold theme counts
declare -A theme_counts

# Get all site URLs into a bash array (ignores 'Loading...' line)
mapfile -t sites < <(wp_skip_all site list --field=url --deleted=0 --archived=0 --quiet)

# Get total site count
total_sites=${#sites[@]}
failed_sites=0

if [[ $total_sites -eq 0 ]]; then
echo "No sites found."
exit 0
fi

echo "Auditing $total_sites sites..."
echo "---"

# Loop through each site and get its active theme
for s in "${sites[@]}"; do
# Get the slug of the active theme.
# '2>/dev/null' suppresses errors from archived/deleted sites.
active_theme=$(wp_skip_all theme list --status=active --field=name --url="$s" 2>/dev/null)

# Check if the command was successful and returned a theme name
if [[ -n "$active_theme" ]]; then
# Increment the count for this theme in the array
((theme_counts[$active_theme]++))
echo "Site: $s | Theme: $active_theme"
else
echo "Site: $s | FAILED to get theme (site may be archived or deleted)"
((failed_sites++))
fi
done

echo
echo "########################################"
echo " Theme Usage Report"
echo "########################################"

# Loop through the counted themes and print the report

# Get all unique theme names (the array keys) and sort them
sorted_themes=($(printf "%s\n" "${!theme_counts[@]}" | sort))

for theme in "${sorted_themes[@]}"; do
count=${theme_counts[$theme]}

# Use 'bc' for floating-point percentage calculation
percentage=$(echo "scale=2; ($count / $total_sites) * 100" | bc)

# Use 'printf' for clean, aligned columns
printf "Theme: %-30s | Count: %-5s | Percentage: %s%%\n" "$theme" "$count" "$percentage"
done

echo "---"
printf "Total Sites Checked: %-5s\n" "$total_sites"
if [[ $failed_sites -gt 0 ]]; then
printf "Sites Failed: %-5s (not included in percentage)\n" "$failed_sites"
fi
16 changes: 8 additions & 8 deletions delete-transient-every-network-site.sh
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
#!/bin/sh
#!/bin/env bash

# Loop through each network site and delete a transient.

#
# The transient to search for (can use wild cards *).
transient_search_term='*events_*';

source 'source/includes.sh';

echo;
for site_url in $(wp site list --allow-root --skip-themes --skip-plugins --deleted=0 --archived=0 --spam=0 --field=url); do
for site_url in $(wp_skip_all site list --field=url); do

found_transients=$(wp transient list --allow-root --skip-themes --skip-plugins --format=csv --fields=name --search=$transient_search_term --url=$site_url | awk 'NR>1 {print}'
found_transients=$(wp_skip_all transient list --format=csv --fields=name --search=$transient_search_term --url=$site_url | awk 'NR>1 {print}'
);

echo '################################################'
Expand All @@ -18,13 +20,11 @@ for site_url in $(wp site list --allow-root --skip-themes --skip-plugins --delet

# Check if it is NOT empty.
if [[ -z $found_transients ]]; then
echo 'none';
echo ' none';
else
echo $found_transients;
echo " $found_transients";
fi

echo;

for transient in $found_transients; do

wp transient delete --allow-root --skip-themes --skip-plugins --url=$site_url $transient;
Expand Down
18 changes: 10 additions & 8 deletions delete-user.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#!/bin/sh
#!/bin/env bash

# This interactive script deletes a given user by their ID and reattributes their content to another
# user based on the provided ID.

source 'source/includes.sh';

echo;
echo 'You are about to delete a user and attribute any content they may have to another use.';
echo;
Expand All @@ -28,22 +30,22 @@ done;

# Prompt for the site ID to delete the user from.
if [[ 999 = $site_id ]]; then
sites=$(wp --allow-root --skip-themes --skip-plugins site list --field="url" --archived=0);
sites=$(wp_skip_all site list --field="url" --archived=0);
sites_name='All sites in the WP network';
else
sites=$(wp --allow-root --skip-themes --skip-plugins site list --field="url" --site__in=${site_id});
sites=$(wp_skip_all site list --field="url" --site__in=${site_id});
sites_name="$sites";
fi

echo;

# Add human readable info for the user to be deleted.
user_name_delete=$(wp --allow-root --skip-themes --skip-plugins user get ${user_id_delete} --field="display_name");
# user_login_delete=$(wp --allow-root --skip-themes --skip-plugins user get ${user_id_delete} --field="user_login");
user_name_delete=$(wp_skip_all user get ${user_id_delete} --field="display_name");
# user_login_delete=$(wp_skip_all user get ${user_id_delete} --field="user_login");

# Add human readable info for the user to get attribution of content.
user_name_attribute=$(wp --allow-root --skip-themes --skip-plugins user get ${user_id_attribute} --field="display_name");
# user_login_attribute=$(wp --allow-root --skip-themes --skip-plugins user get ${user_id_attribute} --field="user_login");
user_name_attribute=$(wp_skip_all user get ${user_id_attribute} --field="display_name");
# user_login_attribute=$(wp_skip_all user get ${user_id_attribute} --field="user_login");

# Confirm before moving on.
while [[ -z "$confirmed" ]]; do
Expand Down Expand Up @@ -72,5 +74,5 @@ esac
# you reattribute content.
echo 'Removing the user...';
for site in $sites; do
wp --allow-root --skip-themes --skip-plugins user delete $user_id_delete --reassign="${user_id_attribute}" --url="${site}" ;
wp_skip_all user delete $user_id_delete --reassign="${user_id_attribute}" --url="${site}" ;
done;
Loading