Comment Management
Overview
WP-CLI provides powerful commands to manage WordPress comments—approve, spam, trash, delete, and moderate comments at scale. Essential for comment moderation, spam cleanup, and site maintenance.
Understanding WordPress Comments
WordPress comments are user-generated content attached to posts. Comments can be in different states:
- Approved - Visible on the site
- Pending - Awaiting moderation
- Spam - Marked as spam
- Trash - Moved to trash
- Deleted - Permanently removed
Listing Comments
Basic Listing
# List all comments
wp comment list
# List with specific fields
wp comment list --fields=comment_ID,comment_author,comment_date,comment_approved
# List in table format
wp comment list --format=table
Filter by Status
# List approved comments
wp comment list --status=approve
# List pending comments
wp comment list --status=hold
# List spam comments
wp comment list --status=spam
# List trashed comments
wp comment list --status=trash
# Count comments by status
wp comment list --status=approve --format=count
wp comment list --status=spam --format=count
Filter by Post
# List comments for specific post
wp comment list --post_id=123
# List comments for multiple posts
wp comment list --post_id=123,456,789
# Count comments on post
wp comment list --post_id=123 --format=count
Advanced Filtering
# List comments by author email
wp comment list --author_email=user@example.com
# List comments by author name
wp comment list --author=John
# List recent comments
wp comment list --number=10 --orderby=comment_date --order=DESC
# List comments with specific keyword
wp comment list --search="keyword"
# Get just IDs
wp comment list --status=spam --field=comment_ID
Creating Comments
Create Basic Comment
# Create comment on post
wp comment create --comment_post_ID=123 \
--comment_content="Great article!" \
--comment_author="John Doe" \
--comment_author_email="john@example.com"
# Create and approve immediately
wp comment create --comment_post_ID=123 \
--comment_content="Excellent post!" \
--comment_author="Jane Smith" \
--comment_author_email="jane@example.com" \
--comment_approved=1
Create Comment with Full Options
# Create detailed comment
wp comment create \
--comment_post_ID=123 \
--comment_content="This is a detailed comment with lots of information." \
--comment_author="John Doe" \
--comment_author_email="john@example.com" \
--comment_author_url="https://johndoe.com" \
--comment_author_IP="192.168.1.1" \
--user_id=5 \
--comment_approved=1 \
--comment_parent=0
Create Reply to Comment
# Reply to existing comment
wp comment create \
--comment_post_ID=123 \
--comment_parent=456 \
--comment_content="Thanks for your comment!" \
--comment_author="Admin" \
--comment_author_email="admin@example.com" \
--comment_approved=1
Approving Comments
Approve Single Comment
# Approve comment
wp comment approve 123
# Approve multiple comments
wp comment approve 123 456 789
Bulk Approve Comments
# Approve all pending comments
wp comment approve $(wp comment list --status=hold --field=comment_ID)
# Approve comments from specific author
wp comment approve $(wp comment list --author_email=trusted@example.com --status=hold --field=comment_ID)
# Approve comments on specific post
wp comment approve $(wp comment list --post_id=123 --status=hold --field=comment_ID)
Unapproving Comments
Unapprove Comments
# Unapprove comment (set to pending)
wp comment unapprove 123
# Unapprove multiple comments
wp comment unapprove 123 456 789
# Unapprove all comments from user
wp comment unapprove $(wp comment list --author_email=suspicious@example.com --status=approve --field=comment_ID)
Marking as Spam
Mark Single Comment as Spam
# Mark as spam
wp comment spam 123
# Mark multiple as spam
wp comment spam 123 456 789
Bulk Spam Operations
# Mark all pending comments as spam
wp comment spam $(wp comment list --status=hold --field=comment_ID)
# Mark comments from specific email as spam
wp comment spam $(wp comment list --author_email=spammer@example.com --field=comment_ID)
# Mark comments with specific keyword as spam
wp comment spam $(wp comment list --search="viagra" --field=comment_ID)
Trashing Comments
Move to Trash
# Trash comment
wp comment trash 123
# Trash multiple comments
wp comment trash 123 456 789
# Trash all spam comments
wp comment trash $(wp comment list --status=spam --field=comment_ID)
Deleting Comments
Delete Permanently
# Delete comment permanently
wp comment delete 123 --force
# Delete multiple comments
wp comment delete 123 456 789 --force
# Delete all spam comments permanently
wp comment delete $(wp comment list --status=spam --field=comment_ID) --force
# Delete all trashed comments
wp comment delete $(wp comment list --status=trash --field=comment_ID) --force
Getting Comment Information
Get Comment Details
# Get all comment data
wp comment get 123
# Get specific field
wp comment get 123 --field=comment_content
wp comment get 123 --field=comment_author
wp comment get 123 --field=comment_author_email
wp comment get 123 --field=comment_approved
# Get in JSON format
wp comment get 123 --format=json
Updating Comments
Update Comment Content
# Update comment content
wp comment update 123 --comment_content="Updated comment text"
# Update author name
wp comment update 123 --comment_author="New Author Name"
# Update author email
wp comment update 123 --comment_author_email="newemail@example.com"
# Update multiple fields
wp comment update 123 \
--comment_content="Updated content" \
--comment_author="Updated Author"
Real-World Scenarios
Scenario 1: Daily Comment Moderation
#!/bin/bash
# daily-comment-moderation.sh
echo "=== Daily Comment Moderation Report ==="
echo "Date: $(date)"
echo ""
# Count pending comments
PENDING=$(wp comment list --status=hold --format=count)
echo "Pending comments: $PENDING"
# Count spam comments
SPAM=$(wp comment list --status=spam --format=count)
echo "Spam comments: $SPAM"
# Show recent pending comments
if [ "$PENDING" -gt 0 ]; then
echo ""
echo "Recent pending comments:"
wp comment list --status=hold --number=10 --fields=comment_ID,comment_author,comment_content --format=table
fi
# Auto-delete old spam
OLD_SPAM=$(wp comment list --status=spam --before="30 days ago" --field=comment_ID)
if [ -n "$OLD_SPAM" ]; then
echo ""
echo "Deleting spam older than 30 days..."
wp comment delete $OLD_SPAM --force
echo "Deleted $(echo $OLD_SPAM | wc -w) spam comments"
fi
Scenario 2: Spam Cleanup
#!/bin/bash
# spam-cleanup.sh
echo "Starting spam cleanup..."
# Count spam
SPAM_COUNT=$(wp comment list --status=spam --format=count)
echo "Found $SPAM_COUNT spam comments"
if [ "$SPAM_COUNT" -gt 0 ]; then
read -p "Delete all spam comments? (y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
wp comment delete $(wp comment list --status=spam --field=comment_ID) --force
echo "All spam comments deleted!"
fi
fi
# Check for potential spam patterns
echo ""
echo "Checking for potential spam patterns..."
# Comments with suspicious keywords
SUSPICIOUS=$(wp comment list --search="viagra" --status=approve --format=count)
if [ "$SUSPICIOUS" -gt 0 ]; then
echo "⚠ Warning: $SUSPICIOUS approved comments contain 'viagra'"
fi
Scenario 3: Comment Migration
#!/bin/bash
# export-comments.sh
POST_ID=$1
if [ -z "$POST_ID" ]; then
echo "Usage: $0 <post_id>"
exit 1
fi
echo "Exporting comments for post $POST_ID..."
# Export to JSON
wp comment list --post_id=$POST_ID --format=json > comments-post-$POST_ID.json
# Export to CSV
wp comment list --post_id=$POST_ID --format=csv > comments-post-$POST_ID.csv
echo "Export complete!"
echo "Files created:"
echo " - comments-post-$POST_ID.json"
echo " - comments-post-$POST_ID.csv"
Scenario 4: Bulk Comment Approval
#!/bin/bash
# approve-trusted-commenters.sh
# List of trusted email addresses
TRUSTED_EMAILS=(
"john@example.com"
"jane@example.com"
"admin@example.com"
)
echo "Auto-approving comments from trusted users..."
for email in "${TRUSTED_EMAILS[@]}"; do
PENDING=$(wp comment list --author_email=$email --status=hold --field=comment_ID)
if [ -n "$PENDING" ]; then
COUNT=$(echo $PENDING | wc -w)
echo "Approving $COUNT comments from $email"
wp comment approve $PENDING
fi
done
echo "Auto-approval complete!"
Scenario 5: Comment Statistics
#!/bin/bash
# comment-statistics.sh
echo "=== Comment Statistics ==="
echo "Date: $(date)"
echo ""
# Total comments
echo "Total comments: $(wp comment list --format=count)"
echo "Approved: $(wp comment list --status=approve --format=count)"
echo "Pending: $(wp comment list --status=hold --format=count)"
echo "Spam: $(wp comment list --status=spam --format=count)"
echo "Trash: $(wp comment list --status=trash --format=count)"
echo ""
# Comments by post
echo "Top 10 Posts by Comment Count:"
wp db query "
SELECT
p.ID,
p.post_title,
COUNT(c.comment_ID) as comment_count
FROM wp_posts p
LEFT JOIN wp_comments c ON p.ID = c.comment_post_ID
WHERE p.post_status = 'publish' AND c.comment_approved = '1'
GROUP BY p.ID
ORDER BY comment_count DESC
LIMIT 10;
"
echo ""
# Recent commenters
echo "Recent Commenters:"
wp comment list --status=approve --number=10 --fields=comment_author,comment_author_email,comment_date --format=table
Advanced Operations
Auto-Moderate Based on Rules
#!/bin/bash
# auto-moderate.sh
# Approve comments from registered users
REGISTERED=$(wp comment list --status=hold --user_id!=0 --field=comment_ID)
if [ -n "$REGISTERED" ]; then
echo "Auto-approving comments from registered users..."
wp comment approve $REGISTERED
fi
# Mark short comments as spam (likely spam)
wp comment list --status=hold --field=comment_ID | while read comment_id; do
CONTENT=$(wp comment get $comment_id --field=comment_content)
LENGTH=${#CONTENT}
if [ "$LENGTH" -lt 10 ]; then
echo "Marking short comment $comment_id as spam"
wp comment spam $comment_id
fi
done
Disable Comments on Old Posts
#!/bin/bash
# close-old-comments.sh
# Close comments on posts older than 1 year
OLD_POSTS=$(wp post list --before="1 year ago" --field=ID)
for post_id in $OLD_POSTS; do
wp post update $post_id --comment_status=closed
done
echo "Closed comments on old posts"
Export Comments for Analysis
#!/bin/bash
# export-for-analysis.sh
# Export all approved comments with sentiment data
wp comment list --status=approve --format=json | \
jq -r '.[] | [.comment_ID, .comment_author, .comment_content, .comment_date] | @csv' > \
comments-analysis-$(date +%Y%m%d).csv
echo "Comments exported for analysis"
Comment Meta Management
Add Comment Meta
# Add custom field to comment
wp comment meta add 123 rating "5"
# Add moderation note
wp comment meta add 123 moderator_note "Approved by admin"
Get Comment Meta
# Get specific meta
wp comment meta get 123 rating
# List all meta for comment
wp comment meta list 123
Update Comment Meta
# Update meta value
wp comment meta update 123 rating "4"
Delete Comment Meta
# Delete specific meta
wp comment meta delete 123 old_field
Best Practices
1. Regular Spam Cleanup
# Weekly spam cleanup (cron)
0 2 * * 0 wp comment delete $(wp comment list --status=spam --field=comment_ID) --force
2. Backup Before Bulk Deletion
# Export comments before deleting
wp comment list --status=spam --format=json > spam-backup-$(date +%Y%m%d).json
# Then delete
wp comment delete $(wp comment list --status=spam --field=comment_ID) --force
3. Monitor Pending Queue
# Daily notification of pending comments
PENDING=$(wp comment list --status=hold --format=count)
if [ "$PENDING" -gt 0 ]; then
echo "$PENDING comments pending moderation" | mail -s "Comment Moderation" admin@example.com
fi
4. Auto-Approve Trusted Users
# Whitelist trusted commenters
wp comment approve $(wp comment list --author_email=trusted@example.com --status=hold --field=comment_ID)
5. Archive Old Comments
# Export comments older than 2 years
wp comment list --before="2 years ago" --format=json > archived-comments-$(date +%Y%m%d).json
Quick Reference
Essential Commands
# List
wp comment list # All comments
wp comment list --status=approve # Approved only
wp comment list --status=hold # Pending only
wp comment list --status=spam # Spam only
wp comment list --post_id=123 # For specific post
wp comment list --format=count # Count only
# Create
wp comment create --comment_post_ID=123 --comment_content="Text" --comment_author="Name"
# Moderate
wp comment approve 123 # Approve
wp comment unapprove 123 # Unapprove
wp comment spam 123 # Mark as spam
wp comment trash 123 # Move to trash
wp comment delete 123 --force # Delete permanently
# Bulk operations
wp comment approve $(wp comment list --status=hold --field=comment_ID)
wp comment spam $(wp comment list --author_email=spam@example.com --field=comment_ID)
wp comment delete $(wp comment list --status=spam --field=comment_ID) --force
# Get info
wp comment get 123 # All data
wp comment get 123 --field=comment_content # Specific field
# Update
wp comment update 123 --comment_content="New text"
# Meta
wp comment meta add 123 key "value"
wp comment meta get 123 key
wp comment meta update 123 key "new value"
wp comment meta delete 123 key
Comparison: WP-CLI vs wp-admin
| Task | WP-CLI | wp-admin |
|---|---|---|
| Delete 1000 Spam | ~5 seconds | 15-20 minutes |
| Approve 50 Comments | ~2 seconds | 5-10 minutes |
| Export Comments | Instant | Manual copy/paste |
| Bulk Moderation | Single command | Multiple clicks |
| Automation | ✅ Fully scriptable | ❌ Manual only |
| Read Comment Context | ⚠️ Limited | ✅ Full post view |
| Visual Moderation | ❌ Text-based | ✅ Visual interface |
Key Takeaway
WP-CLI excels at bulk moderation, spam cleanup, and automation. Use it for large-scale comment management. Use wp-admin for individual comment moderation where you need to see the full post context.
Next Steps
- Manage posts: Post Management
- Organize with taxonomies: Taxonomy Management
- Learn database operations: Database Management