Take back the day with

wp-cli

wp user get rkanner

  • WordPress Developer for 10+ years
  • EX-East-Coaster
  • Work for Media News Group, working on websites for newspapers such as the Denver Post, Orange County Register, and the Mercury News.
  • Freelance @ LodoPress
  • Organizer of the WordPress Denver Meetup

What is wp-cli?

What is WP-CLI?

  • It's WordPress... on the command line
  • Allows you to talk to WordPress without going through the browser.
  • Open source project backed by WordPress.org, and collaborated on in Github.
  • Has an easy to use API for extending it with your own commands.
  • Available from wp-cli.org

My Journey to WP-cli Enlightenment

Hi Ryan,

Todd from marketing left the company today, and he's after our clients!!! Can we please disable his login for all of our sites?

Scenario 1: Delete user

From: boss@company.com

Subject: 911 Disable Todd's Login!

But he had access to 100 sites...

Without Wp- cli

With wp-cli

environment Aliases

# wp-cli.yml

@site1:
  path: testsite1.dev
@site2:
  path: testsite2.dev
@site3:
  ssh: rkanner@testsite3.dev
  user: rkanner
  path: ../../var/www/html/testsite3.dev
@site4:
  ssh: rkanner@testsite4.dev
  user: rkanner
  path: ../../var/www/html/testsite4.dev

Hi Ryan,

We are ready to get started with development for XYZ company, could you get all of the environments for them created?

Scenario 2: Create sites

From: pm@company.com

Subject: Environment Creation

WordPress has a 5 minute install... I got this!

Without wp-cli: 5 minute install?

  • Download WordPress
  • Unzip it
  • Create a DB, or remember it's credentials
  • Setup your wp-config file
  • Go through the site setup in the browser
  • Add your personal email for the admin account so you get tons of junk in your inbox.
  • Find your ssh creds for your staging/production box.
  • ssh into both of the boxes.
  • Do everything over 2 times without messing anything up.
  • Look through job boards for a new job.

With wp-cli

The bash script

echo "Starting WordPress Installation"

# Download Core
wp core download

# Create wp-config
wp core config --dbname=$1

# Create the database
wp db create

# Run the installer
wp core install --url=$2 --title="My sweet WP Site"

# Create a user for yourself
wp user create test test@test.com --role=administrator

# Set the site admin to a contributor
wp user set-role 1 contributor

echo "Opening Admin"
open http://$2/wp-admin

Setting the constants

# wp-cli.yml

core config:
    dbuser: root
    dbpass: password
    dbhost: localhost
core install:
    admin_email: dummy@mydumbsite.com
    admin_user: defsnotadmin

Hi Ryan,

We haven't gotten any new invoices into our system in the last 2 hours. Can you check to see if the cron job is stuck again?

Scenario 3: Debug Cron

From: client@company.com

Subject: Cron Job Stuck

Without WP-CLI

Managing other ui-less Features

# Regenerate all thumbnails
wp media regenerate

# Delete expired transients
wp transient delete --expired

# Delete all transients
wp transient delete --all

# List of scheduled cron events
wp cron event list

# Run all cron events in queue
wp cron event run --due-now

# Flush rewrite rules
wp rewrite flush

# List of rewrites
wp rewrite list --format=csv

# Flush the cache
wp cache flush

Scenario 4: update sites

Without Wp-cli

With WP-CLI

How big is the issue?

Scenario 5: Import data

Hi Ryan,

I have attached a spreadsheet of a few tags we would like to import into our site before launch. If you could have these imported by the end of the day, that would be great.

From: client@company.com

Subject: Tag list attached

Without WP-CLI

With WP-CLI

The Code

$tag_importer = function( $args ) {

	$tags = new \WP_CLI\Iterators\CSV( $args[0] );
	foreach ( $tags as $tag ) {
		wp_insert_term( $tag['level_1'], 'post_tag' );
		WP_CLI::success( 
                    sprintf( 'Added new tag: %s', $tag['level_1'] ) 
                );
	}

};

WP_CLI::add_command( 'import-tags', $tag_importer );

Hi Ryan,

I was making a couple of small edits in the backend of our site today, and I think I got a little carried away. It no longer looks like the live site at all. Can you reset it for me today? Thanks.

Scenario 6: Sync staging

From: client@company.com

Subject: Staging site messed up!!!!!!!!!!!!!!!

Without CLI

  • Re-evaluate all of your life choices
  • SSH into production server
  • Take a DB export
  • Search and replace URL's
  • SSH into staging server
  • Import database
  • Remove any production-only data

With WP-cli

The bash script

#/bin/bash

# Figure out what needs to be search & replaced
PROD_URL="$(wp @prod option get home)"
STAGE_URL="$(wp @stage option get home)"

echo "Exporting production database"
wp @prod search-replace $PROD_URL $STAGE_URL --export=db.sql

echo "Importing prod database to staging"
wp @stage db import db.sql

# Replace some production only data
echo "Clearing production API keys"
wp @stage option update prod_api_key xxxxxxx

Local Aliases

# wp-cli.local.yml

@prod:
  ssh: ubuntu@mysite.com:2222
  user: ubuntu
  path: ../var/www/html/mysite.com
@stage:
  ssh: ubuntu@stage.mysite.com:2222
  user: ubuntu
  path: ../var/www/html/stage.mysite.com

We would like to add a new "Books" post type to the site to display our book collection. We would also like a few taxonomies to filter the books by: Year Published, Genre, Author, and Publisher.

Scenario 7: Scaffold Types

Task: Add Books post type and 3 new Taxonomies

Due Date: EOD Tomorrow

Without WP-CLI

  • Write out post type & taxonomy registration by hand
  • Use a plugin with an admin UI
  • Copy & Paste
  • Use an online generator (but still have to copy & paste)

With WP-CLI

Other useful scaffold commands

## Scaffold a new theme based off of _s
wp scaffold _s my-sweet-theme --theme_name="My Sweet Theme"

## Scaffold a new plugin
wp scaffold plugin my-sweet-plugin --plugin_name="My Sweet Plugin"

## Scaffold a new Gutenblock
wp scaffold block my-sweet-block --title="My Sweet Block" --theme

## Scaffold test framework for an existing plugin
wp scaffold plugin-tests plugin-without-tests

SPEED Round

Delete all spam comments

wp comment delete $(wp comment list --status=spam --format=ids) --force

Success: Deleted comment 11.
Success: Deleted comment 10.
Success: Deleted comment 9.
Success: Deleted comment 8.
Success: Deleted comment 7.

Just pulled a site locally that you don't have a user on

wp user create codeprokid test@test.com --role=administrator --user_pass=pass

Success: Created user 2.

Create a bunch of posts for testing

wp post generate --count=100 --post_type=resource

Generating posts  100% [=============================] 0:01 / 0:04

Enable wp-debug

wp config set WP_DEBUG true --raw
wp config set WP_DEBUG_LOG true --raw
wp config set WP_DEBUG_DISPLAY true --raw
wp config set SCRIPT_DEBUG true --raw
wp config set SAVEQUERIES true --raw


Success: Added the constant 'WP_DEBUG' to the 'wp-config.php' file with the raw value 'true'.

Reset all user passwords

wp user reset-password $(wp user list --format=ids)

Reset password for user1.
Reset password for user2.
Reset password for user3.
Reset password for user4.

Run a recount on all terms

wp term recount $(wp taxonomy list --field=name)

Success: Updated category term count.
Success: Updated post_tag term count.
Success: Updated nav_menu term count.
Success: Updated link_category term count.
Success: Updated post_format term count.

Wrapping it up

WHY SHOULD I USE IT?

  • Control multiple installs from one place
  • Allows you to automate monotonous tasks.
  • Gives you an easy way to do bulk operations like deleting users, or migrating data.
  • Provides an easy way to touch some hard-to-control WordPress internals (transients, cron jobs)
  • It's consistent and repeatable.

Helpful Resources

Questions?

Take Back the Day With WP-CLI

By Ryan Kanner

Take Back the Day With WP-CLI

In this presentation, I will take you from installing wp-cli to writing your own commands.

  • 4,524