Managing WordPress from the command line

Introduction to WP-CLI & examples in daily use

How many of you know what WP-CLI is?

How many of you are using WP-CLI?

WordPress Admin

Which was quicker?

Command Structure

$ wp plugin install wordpress-seo --activate

command

subcommand

parameter

flag

Getting Help

q key to quit

Start small

Migrations

$ wp db export
Success: Exported to 'local-2018-03-17-9d26a34.sql'.

$ wp db import local-2018-03-17-9d26a34.sql
Success: Imported from 'local-2018-03-17-9d26a34.sql'.
$ wp search-replace http://example.com https://example.com
  --skip-columns=guid --report-changed-only --dry-run
+------------+--------------+--------------+------+
| Table      | Column       | Replacements | Type |
+------------+--------------+--------------+------+
| wp_options | option_value | 2            | PHP  |
| wp_posts   | post_content | 1            | SQL  |
| wp_posts   | guid         | 3            | SQL  |
+------------+--------------+--------------+------+
Success: 6 replacements to be made.
$ wp search-replace http://example.com https://example.com
  --skip-columns=guid --report-changed-only
+------------+--------------+--------------+------+
| Table      | Column       | Replacements | Type |
+------------+--------------+--------------+------+
| wp_options | option_value | 2            | PHP  |
| wp_posts   | post_content | 1            | SQL  |
| wp_posts   | guid         | 3            | SQL  |
+------------+--------------+--------------+------+
Success: Made 6 replacements
$ wp rewrite flush
Success: Rewrite rules flushed.

$ wp cache flush
Success: The cache was flushed.

$ wp transient delete --all
Success: 8 transients deleted from the database.
$ wp media regenerate
Found 3 images to regenerate.
1/3 Regenerated thumbnails for "Vertical Image" (ID 123).
2/3 Regenerated thumbnails for "Horizontal Image" (ID 124).
3/3 Regenerated thumbnails for "Beautiful Picture" (ID 125).
Success: Regenerated 3 of 3 images.

Development

$ wp user update admin --user_pass=password

Success: Updated user 1.
$ wp db search WordPress wp_posts

wp_posts:post_content
17:Welcome to WordPress. This is your

wp_posts:post_content
36:wpmeetups "[your-subject]"
[your-name] <wordpress@>
From: [your-name] <[your-email]>

wpmeetups "[your-subject]"
wpmeetups <wordpress@>
Message Body:

Plugins

$ wp jetpack status full

Checking status for https://example.com
Success: Jetpack is currently connected
to WordPress.com
The Jetpack Version is 5.8
The WordPress.com blog_id is 328491835
The WordPress.com account for the primary
connection is info@example.com

Additional data:
version......... 5.8
wp-version...... 4.9.4
$ wp migratedb profile 8
Initiating migration...
Exporting tables   100% [==============] 0:09 / 0:09
Cleaning up...
Success: Export saved to:
/uploads/wp-migrate-db/example-migrate.sql.gz

$ wp migratedb import /uploads/wp-migrate-db/example-migrate.sql.gz
Initiating migration...
Importing file  100% [==============] 1:29 / 1:29
Cleaning up...
Flushing caches and rewrite rules...
Success: Migration successful.

Running code from the command line

$ wp eval "var_dump(wp_get_translation_updates());"

array(9) {
  [0]=>
  object(stdClass)#8262 (7) {
    ["type"]=> string(4) "core"
    ["slug"]=> string(7) "default"
    ["language"]=> string(5) "de_CH"
    ["version"]=> string(5) "4.9.4"
    ["updated"]=> string(19) "2018-02-12 10:10:36"
    ["package"]=> string(64) "https://downloads.wordpress.org/translation/core/4.9.4/de_CH.zip"
    ["autoupdate"]=> bool(true)
  }
[...]
$ wp eval-file ./scripts/migration-related-dossier.php
Processed 123 ...
Processed 124 ...
[...]
$query = new WP_Query( [
	'post_type'              => 'any',
	'post_status'            => 'any',
	'posts_per_page'         => -1,
	'no_found_rows'          => true,
	'meta_key'               => 'ph_related_dossier',
	'lang'                   => '',
	'fields'                 => 'ids',
	'update_post_meta_cache' => true,
	'update_post_term_cache' => false,
] );

if ( ! $query->have_posts() ) {
	WP_CLI::error( 'No posts.' );
}

foreach ( $query->posts as $post_id ) {
	$dossier_id = get_post_meta( $post_id, 'ph_related_dossier', true );
	if ( ! $dossier_id || is_array( $dossier_id ) ) { // No dossier linked or already in new format.
		continue;
	}

	if ( 'ph_artist' === get_post_type( $post_id ) ) {
		$success = delete_post_meta( $post_id, 'ph_related_dossier', $dossier_id );
		if ( $success ) {
			WP_CLI::log( "Deleted Artist $post_id meta..." );
		}
		continue;
	}

	// Convert to array...
	update_post_meta( $post_id, 'ph_related_dossier', [ $dossier_id ] );
	// ...and add new meta.
	add_post_meta( $post_id, 'ph_related_dossier_' . $dossier_id, true );

	WP_CLI::log( "Processed $post_id..." );
}
wp_reset_postdata();
WP_CLI::success( 'Done.' );

Multisite

$ wp plugin list

+-----------------------------------+----------------+-----------+---------+
| name                              | status         | update    | version |
+-----------------------------------+----------------+-----------+---------+
| google-analytics-for-wordpress    | active-network | available | 7.0.4   |
| gutenberg                         | active         | none      | 2.7.0   |
+-----------------------------------+----------------+-----------+---------+

$ wp plugin list --url=stage.example.com/de

+-----------------------------------+----------------+-----------+---------+
| name                              | status         | update    | version |
+-----------------------------------+----------------+-----------+---------+
| google-analytics-for-wordpress    | active-network | available | 7.0.4   |
| gutenberg                         | inactive       | none      | 2.7.0   |
+-----------------------------------+----------------+-----------+---------+
$ wp plugin activate gutenberg --url=stage.example.com/de

Plugin 'gutenberg' activated.
Success: Activated 1 of 1 plugins.

$ wp plugin activate gutenberg --network

Plugin 'gutenberg' network activated.
Success: Network activated 1 of 1 plugins.
$ wp core multisite-install 
> --title="Welcome to the WordPress" \
> --admin_user="admin" --admin_password="password" \
> --admin_email="user@example.com"

Single site database tables already present.
Set up multisite database tables.
Added multisite constants to wp-config.php.
Success: Network installed. Don't forget to set
up rewrite rules.
$ wp core multisite-convert

Set up multisite database tables.
Added multisite constants to wp-config.php.
Success: Network installed. Don't forget to
set up rewrite rules
path: web/wp

_envs:
  - &test_data
    ssh: deploy@example.com/var/www/stage.example.com
    path: web/wp

@stage-de:
  url: https://stage.example.com/de/
  <<: *test_data
wp-cli.yml

Running command remotely

path: web/wp

@prod:
  ssh: deploy@example.com/var/www/example.com
@prod2:
  ssh: deploy@1.example.com/var/www/example.com
@prod-all:
  @prod
  @prod2

@stage:
  ssh: deploy@example.com/var/www/stage.example.com

@dev:
  ssh: vagrant/var/www/example.com
wp-cli.yml
$ wp @prod cli version
WP-CLI 1.5.0

$ wp @prod-all cli version
@prod
WP-CLI 1.5.0
@prod2
WP-CLI 1.5.0

Doing multiple tasks

https://make.wordpress.org/cli/handbook/shell-friends/

Scenario:

Reorganising the categories. Delete term A and add the posts to term B.

$ wp post list --category_name=a --format=ids |
  xargs -0 -d ' ' -I % wp post term add % category b
Success: Added term.
Success: Added term.
Success: Added term.
[...]
$ wp post delete $(wp post list
  --post_type='page' --format=ids)
Success: Trashed post 32.
Success: Trashed post 28.
Success: Trashed post 4.
Success: Trashed post 2.
$ wp post list --format=ids --post_type=
  $(wp post-type list --capability_type=post
   --field=name | tr "\n" ",")

6486 6484 6482 6480 6478 6476 6474 6472 6470 6468 6466 

Packages

$ wp package install git@github.com:trepmal/wp-revisions-cli.git
Installing package trepmal/wp-revisions-cli (dev-master)
Updating ~/.wp-cli/packages/composer.json to require the package...
Registering git@github.com:trepmal/wp-revisions-cli.git as
a VCS repository...
Using Composer to install the package...
---
Loading composer repositories with package information
Updating dependencies
Resolving dependencies through SAT
Dependency resolution completed in 0.185 seconds
Analyzed 5540 packages to resolve dependencies
Analyzed 333592 rules to resolve dependencies
Package operations: 1 install, 2 updates, 0 removals
Installs: trepmal/wp-revisions-cli:dev-master fa49116
Updates: gettext/gettext:dev-master 9ba1532, wp-cli/i18n-command:dev-master 90f3f8e
 - Installing trepmal/wp-revisions-cli (dev-master fa49116)
Writing lock file
Generating autoload files
---
Success: Package installed.

https://make.wordpress.org/cli/handbook/common-issues/

Gutenberg

$ wp scaffold block movie --title="Movie block" --plugin=movies
Success: Created block 'Movie block'.
0 8 * * 7 ~/bin/wp cli update --yes --quiet  > /dev/null

Updating WP-CLI

Resources

Made with Slides.com