WP-CLIで知っておくと便利な機能

WP-CLIには便利なコマンドがあるから使って欲しいな、と思い、こんな機能があるよという紹介です。
元はWordBench富山の勉強会用として作成しました。


# 基本
## wp core version

```bash
$ wp core version
4.6.1
```
WordPressのバージョン確認。WP-CLIはカレントディレクトリを参考にするので、そもそも動いているかということの確認にも。


## wp cli version

```bash
$ wp cli version
WP-CLI 0.25
```
wp-cliの動作確認。バージョンによってはWP-CLIの機能が動かない事もよくあるのでできる限り最新版を使う。2016年10月27日現在は0.25。


## wp cli update

```bash
wp cli update
Success: WP-CLI is at the latest version.
```
wp-cliのバージョンアップ。インストール方法によってはバージョンアップ出来ないこともしばしば。
手動で入れ直した方が早いことも。

## wp eval
```bash
$ wp eval "echo 'hoge';"
hoge
```

```bash
$ wp eval "\$posts = get_posts(array('numberposts'=>1)); var_dump(\$posts);"
array(1) {
  [0]=>
  object(WP_Post)#5279 (24) {
    ["ID"]=>
    int(1)
    ["post_author"]=>
...
```

PHPコードの実行。
WordPressのPHPを呼び出したいときに利用。コマンドラインでphp -rに似た使い方ができる。ダブルクォートを使うとシェルによる展開が入りやすいので注意。
ブラウザからPHPやSQLを投げるDebug Bar Consoleというプラグインもあって、こちらも便利。

> Debug Bar Console
> https://wordpress.org/plugins/debug-bar-console/

# プラグイン
## wp plugin list

```bash
$ wp plugin list
+------------------------------+----------+-----------+---------+
| name                         | status   | update    | version |
+------------------------------+----------+-----------+---------+
| add-page-from-template       | inactive | none      | 0.4.4.1 |
| advanced-custom-fields       | inactive | available | 4.4.10  |
| akismet                      | inactive | none      | 3.2     |
```
インストールされているプラグインのリストを取得。

```bash
$ wp plugin list --format=csv
wp plugin list --format=csv
name,status,update,version
add-page-from-template,inactive,none,0.4.4.1
advanced-custom-fields,inactive,available,4.4.10
akismet,inactive,none,3.2
```
CSVでの出力も可能。

```bash
$ wp plugin list --status=active --format=csv | tail -n +2 | awk 'BEGIN {FS=",";} {printf "%s ", $1;}'

```
スペース区切りでプラグインのリストを取得。

```bash
wp plugin list --status=active --format=csv | tail -n +2 | awk 'BEGIN {FS=",";} {printf "%s ", $1;}' | xargs wp @staging plugin install --activate
```
パイプで繋げるとステージング<=>ローカル間などでプラグインの同期が可能。
ただしデータベースの内容は別なので注意。

## wp plugin install

```bash
$ wp plugin install debug-bar --activate
```
プラグインのインストール。有効化も同時に出来るので便利。

```bash
$ wp plugin install wp plugin install https://github.com/yousan/add-page-from-template/archive/master.zip
```
ZIPファイルから直接インストール。公式で配布されていないZIPをどこかにアップロードして各地で利用できる。

```bash
$ wp plugin uninstall debug-bar && wp plugin install debug-bar --version=0.8.3
Success: Uninstalled and deleted 'debug-bar' plugin.
Installing Debug Bar (0.8.3)
```
特定のプラグインのダウングレード。検証などで重宝する。

# データベース
## wp db export
```bash
wp db export
Success: Exported to 'root_ex5.sql'.
```
データベースのエクスポート。簡単にバックアップが取れる。オプションを何も付けないと`DB_NAME.sql`という名前でカレントディレクトリに保存される。

```bash
$ wp db export ~/tmp/dump.sql
```
名前を付けて保存。

```bash
$ wp db export - | gzip -c > ~/tmp/dump.sql.gz
```
エクスポートと同時に圧縮。大規模サイトの場合にはSQLファイルが1GBとかいってしまうので取り扱いが大変。
SQLはテキストベースなので圧縮率が良い。

## wp db import

```bash
$ wp db import ~/tmp/dump.sql
```
データベースのインポート。sqlファイルから読み込ませるときに。
**間違えてインポートしてしまうことがあるのでインポートは慎重に** (戒め

## SQLを手動で実行する

`wp db cli`が便利です。

```bash
$ echo 'select * from wp_posts;' | wp db cli
```

`wp db query`でも実行できますが、出力を整形することができずテーブルレイアウトで出力されます。

```bash
$ wp db query 'select * from wp_posts;'
```

## テーブルを全て削除する

利用にはご注意ください。

```bash
$ wp db tables --all-tables-with-prefix |  while read line ; \
 do \
 echo ' drop table '${line} | wp db cli ; \
done
```

ワンライナー

```bash
$ wp db tables --all-tables-with-prefix |  while read line ;  do  echo ' drop table '${line} | wp db cli ; done
```


## wp search-replace

```bash
$ wp search-replace --dry-run --skip-columns=guid 'ex5.dev' 'ex6.dev'
+------------------+-----------------------+--------------+------+
| Table            | Column                | Replacements | Type |
+------------------+-----------------------+--------------+------+
| wp_commentmeta   | meta_key              | 0            | SQL  |
| wp_commentmeta   | meta_value            | 0            | SQL  |
| wp_comments      | comment_author        | 0            | SQL  |
| wp_comments      | comment_author_email  | 0            | SQL  |
```
データベースの置換。サイトのドメインの変更時などに重宝。
手動で置換する際にやってしまいがちな、「変更を漏らした」「シリアライズ化されたデータを壊した」という問題をうまく処理してくれる。とても便利。

なおGUIDは変更しないことが推奨されている。開発環境 => 本番環境や意図を持って変更するのはアリ。
> [GUID についての重要事項](https://wpdocs.osdn.jp/サイト_URL_の変更#GUID_.E3.81.AB.E3.81.A4.E3.81.84.E3.81.A6.E3.81.AE.E9.87.8D.E8.A6.81.E4.BA.8B.E9.A0.85)


```bash
wp search-replace  'ex5.dev' 'ex6.dev' --export > ~/tmp/replace.sql
```
変更内容をSQLとして吐き出し。変更前のチェックとして。

```bash
$ wp search-replace --dry-run --regex 'ex5.dev$' 'ex6.dev$'
```
正規表現の利用も可能。

# ユーザー
## ユーザー作成

```bash
$ wp user create username username@example.com --role=administrator --user_pass=password
```
ユーザーの作成。

## パスワード更新
```bash
wp user update yousan --user_pass=pass
```
パスワードを忘れてしまったときに。

今のところプレーンテキスト(平文)での更新のみ受け付けている模様。
**WP-CLIでの入力は履歴に残るので、管理画面から新しいパスワードに更新しましょう**


# オプション
```bash
$ wp option update home http://example.com
$ wp option update siteurl http://example.com/wp
```
サイトURLの更新。
/wpとかディレクトリを付けるのは siteurl の方。

サイトURLの更新の場合にはsearch-replaceを使った方が良い場面が多いけれど、あちらは重かったりするのでケースバイケースで使い分けを。

```bash
wp option list --search="widget*"
+------------------------+------------------------------------------------------------------------------+
| option_name            | option_value                                                                 |
+------------------------+------------------------------------------------------------------------------+
| widget_archives        | a:2:{i:2;a:3:{s:5:"title";s:0:"";s:5:"count";i:0;s:8:"dropdown";i:0;}s:12:"_ |
|                        | multiwidget";i:1;}                                                           |
| widget_calendar        | a:1:{s:12:"_multiwidget";i:1;}                                               |
```
オプションの内容検索。`--search`は`option_name`にしか使えないようなのが残念。
ここでの例はウィジェットの内容確認。

## DBから有効化されているプラグインを取得する

WP-CLIをそのまま使う方法

```console
$ wp plugin  list --format=csv --field=name | tr '\n' ',' | sed -e 's/,$/\n/g'

advanced-custom-fields-pro,akismet,contact-form-7
```

SQLを経由する方法

```console
$ echo 'select option_value from wp_options where option_name = "active_plugins" '| wp db cli | tail -1 |   php -r \
'  $object_str=fgets(STDIN); $activated_plugins = []; '\
'  foreach ( unserialize($object_str) as $plugin) { '\
'    $exploded = explode("/", $plugin); $activated_plugins[] = $exploded[0]; '\
'  }'\
'  echo implode(",", $activated_plugins) . PHP_EOL;'

advanced-custom-fields-pro,akismet,contact-form-7
```

`wp_options` の `option_name` が `active_plugins` にPHPのシリアライズ化されたデータが格納されているので、これをアンシリアライズして出力。

何らかの原因でWP-CLIが動かない時、DBから直接拾う方法

```console
$  echo 'select option_value from wp_options where option_name = "active_plugins" ' | wp db cli | tail -1 | \
  php -r \
'  $object_str=fgets(STDIN); $activated_plugins = []; '\
'  foreach ( unserialize($object_str) as $plugin) { '\
'    $exploded = explode("/", $plugin); '\
'    echo $exploded[0] . PHP_EOL; '\
'  }'

advanced-custom-fields-pro
akismet
contact-form-7
```

その出力をWP-CLIでインストールする方法（実際にはWP-CLIの場所（@などで指定）が別になります）

```
$ echo 'select option_value from wp_options where option_name = "active_plugins" ' | wp db cli | tail -1 | \
  php -r \
'  $object_str=fgets(STDIN); $activated_plugins = []; '\
'  foreach ( unserialize($object_str) as $plugin) { '\
'    $exploded = explode("/", $plugin); '\
'    echo $exploded[0] . PHP_EOL; '\
'  }' |\
xargs -n 1 wp plugin install --activate


Warning: advanced-custom-fields-pro: Plugin already installed.
Activating 'advanced-custom-fields-pro'...
Warning: Plugin 'advanced-custom-fields-pro' is already active.
Success: Plugin already installed.
Warning: akismet: Plugin already installed.
Activating 'akismet'...
Warning: Plugin 'akismet' is already active.
Success: Plugin already installed.
```

# コンフィグ

## 値の設定

`wp-config.php`の定数や変数を変更できる。これは便利。

```bash
$ wp config set table_prefix wp_abc123_
```

https://developer.wordpress.org/cli/commands/config/set/

# 記事作成
```bash
wp post generate --count=100
```
記事の作成。


```bash
$ wp post list
+-----+--------------+-------------+---------------------+-------------+
| ID  | post_title   | post_name   | post_date           | post_status |
+-----+--------------+-------------+---------------------+-------------+
| 4   | 投稿 2       | post-2      | 2016-10-27 13:15:29 | publish     |
| 5   | 投稿 3       | post-3      | 2016-10-27 13:15:29 | publish     |
| 6   | 投稿 4       | post-4      | 2016-10-27 13:15:29 | publish     |
```
確認。


# 設定ファイル（wp-cli.yml）
設定ファイルを記述しておくと読み込んでくれます。

## 読み込み順序

読み込み順序は下記の通りです。

場所 | 読み込み
---|---
wp-cli.local.yml | 現在位置のディレクトリ、もしくは上位ディレクトリ
wp-cli.yml | 現在ディレクトリ、もしくは上位ディレクトリ
~/.wp-cli/config.yml | ホームディレクトリの ~/.wp-cli/config.yml 、もしくは WP_CLI_CONFIG_PATH で指定されたディレクトリの値


ということで、プロジェクト用の `wp-cli.yml` をプロジェクトディレクトリに置いておき、案件共通でよく使う設定を `~/.wp-cli/config.yml` に書くと良いです。

`wp-cli.local.yml` と `wp-cli.yml` についてですが、自分は開発をローカル環境に本番や開発環境といったリモートの環境も記載するため、 wp-cli.yml のファイル名にしておきます。

## 設定の基本

URLとWordPressのインストールパス、色を指定しておきます。

```yaml:wp-cli.yml
url: example.local
path: app/public
color: auto
```

`app/public` は Local by FlyWheel を使った際のインストール位置です。

## リモート設定

アットマークでセクションを作成すると指定された環境を記述できます。

```yaml
@dev: # 開発用サーバ
  ssh: dev.example.com
  url: dev.example.com
  path: /home/dev/public_html/wp/
```

## 設定例

```yaml:wp-cli.yml
url: example.com
path: app/public
color: auto

@dev: # 開発用サーバ
  ssh: fw.example.com
  url: fw.example.com
  path: /home/dev/public_html/wp/

@staging: # ステージング
   ssh: staging.example.com
   url: staging.example.com
   path: /home/stg/public_html/wp/


@production: # 本番
   ssh: example.com
   url: example.com
   path: /home/prd/public_html/wp/
```


# 教えてください
* パスワードをハッシュで入力
* ymlファイルを使ったときにssh秘密鍵の指定方法

 
# おまけ
## インストール方法 @ macOS

```bash
$ mkdir /usr/local/bin/; \
curl -o /usr/local/bin/wp  https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar \
chmod +x /usr/local/bin/wp
```