繰り返さないでください:WP-CLIを使用した反復タスクの自動化
公開: 2022-03-11テーマ、プラグイン、およびWPコアを更新するためにWordPress管理エリアにアクセスしたことがありますか? もちろんあります。 「このCSVファイルのすべてのユーザーを作成/更新/削除できますか?」と尋ねられましたか? あなたもそれに遭遇したと確信しています。 サイトの移行を試みて、その仕事をするために到達できるプラグインまたはサードパーティのツールがあればいいのにと思いましたか? 私は持っていることを知っています!
これらのタスクなどを支援するために利用できる非常に強力なツールがあります。 それについてお話しする前に、簡単な逸話を設定したいと思います。
問題:最近のプロジェクトでは、定期的に繰り返す必要のあるプログラム的なタスクがいくつかありました。 特に1つのタスクには、メンバーシップレベルの購入またはサブスクリプションの証拠に基づいてユーザーレベルの権限を更新することが含まれていました。 会社が特定のメンバーシップレベルのユーザーからの支払いを見つけることができなかった場合、彼らはメンバーシップレベルをユーザーから削除することを望みました。 なぜこれが必要だったのですか? おそらく、メンバーはサブスクリプションを停止しましたが、イベントは発生しなかったため、メンバーは料金を支払っていなくてもアクセスできます(そうです!)。 または、誰かが試用版のオファーを行っていたが、そのオファーは期限切れになり、クライアントはまだサブスクリプションを持っています(これもイケてる!)。
解決策:管理パネルに移動して数百(おそらく数千)のサブスクリプションを手動で削除する代わりに、お気に入りのWordPressツールの1つであるWP-CLIにアクセスすることを選択しました。これにより、数回のキーストロークで問題が修正されました。
この投稿では、WP-CLIを紹介し(まだ親しい友人ではないと仮定して)、この特定の状況のために作成した簡単なカスタムコマンドを紹介し、WP-CLIを使用するためのアイデアとリソースを提供します。あなた自身の開発。
WP-CLIとは何ですか?
これまでWP-CLIについて聞いたことがない場合は、あなただけではありません。 このプロジェクトは数年前のものでしたが、しばらくの間WordPressのレーダーの下で飛んでいたようです。 WP-CLIとは何か、公式Webサイトからの機能について簡単に説明します。
WP-CLIは、WordPressのインストールを管理するためのコマンドラインツールのセットです。 Webブラウザーを使用せずに、プラグインの更新、マルチサイトインストールのセットアップなどを行うことができます。
次のコマンドは、すぐに使用できるWP-CLIの機能を示しています。
-
wp plugin update --all
は、更新可能なすべてのプラグインを更新します。 -
wp db export
は、データベースのSQLダンプをエクスポートします。 -
wp media regenerate
は、添付ファイルのサムネイルを再生成します(たとえば、テーマのサイズを変更した後)。 -
wp checksum core
は、WordPressコアファイルが改ざんされていないことを確認します。 -
wp search-replace
は、データベース内の文字列を検索して置換します。
ここでさらに多くのコマンドを調べると、すべてのWordPress開発者またはサイトメンテナーが毎日または毎週実行する反復タスクに使用できるコマンドがたくさんあることがわかります。 これらのコマンドにより、1年を通して、ページの再読み込みをポイント、クリック、および待機する時間を数え切れないほど節約できました。
確信していますか? 始める準備はできましたか? すごい!
WP-CLIをWordPressと一緒に(またはグローバルにローカルマシンに)インストールする必要があります。 ローカル開発環境にWP-CLIをまだインストールしていない場合、インストール手順はこちらのWebサイトにあります。 Varying Vagrant Vagrants(VVV2)を使用している場合は、WP-CLIが含まれています。 多くのホスティングプロバイダーは、プラットフォームにWP-CLIも含まれています。 これが正常にインストールされていることを前提としています。
WP-CLIを使用して問題を解決する
反復的なタスクの問題を解決するには、WordPressのインストールでカスタムWP-CLIコマンドを使用できるようにする必要があります。 サイトに機能を追加する最も簡単な方法の1つは、プラグインを作成することです。 このインスタンスでは、次の3つの主な理由でプラグインを使用します。
- カスタムコマンドが必要ない場合は、オフにすることができます
- モジュール化を維持しながら、コマンドとサブコマンドをすべて簡単に拡張できます。
- テーマ間で機能を維持でき、他のWordPressインストールでも機能を維持できます。
プラグインの作成
プラグインを作成するには、 wp-content
ディレクトリの/plugins
ディレクトリにディレクトリを追加する必要があります。 このディレクトリをtoptal-wpcli
と呼ぶことができます。 次に、そのディレクトリに2つのファイルを作成します。
-
index.php
、コードは1行だけにする必要があります:<?php // Silence is golden
-
plugin.php
、これは私たちのコードが行くところです(このファイルには好きな名前を付けることができます)。
plugin.php
ファイルを開き、次のコードを追加します。
<?php /** * Plugin Name: TOPTAL WP-CLI Commands * Version: 0.1 * Plugin URI: https://n8finch.com/ * Description: Some rando wp-cli commands to make life easier... * Author: Nate Finch * Author URI: https://n8finch.com/ * Text Domain: toptal-wpcli * Domain Path: /languages/ * License: GPL v3 */ /** * NOTE: THIS PLUGIN FILE WILL NOT WORK IN PRODUCTION AS IS AND IS ONLY FOR DEMONSTRATION PURPOSES! * You can of course take the code and repurpose it:-). */ if ( !defined( 'WP_CLI' ) && WP_CLI ) { //Then we don't want to load the plugin return; }
これらの最初の数行には2つの部分があります。
まず、プラグインヘッダーがあります。 この情報はWordPressプラグインの管理ページに取り込まれ、プラグインを登録してアクティブ化することができます。 プラグイン名のみが必要ですが、このコードを使用する可能性のある人(および将来の自分自身)のために残りを含める必要があります。
次に、WP-CLIが定義されていることを確認します。 つまり、WP-CLI定数が存在するかどうかを確認しています。 そうでない場合は、プラグインを実行せずに保釈します。 存在する場合は、残りのコードを実行することは明らかです。
これらの2つのセクションの間に、一部の関数は実際の関数のプレースホルダーであるため、このコードを本番環境で「そのまま」使用しないように注意してください。 これらのプレースホルダー関数を実際のアクティブな関数に変更する場合は、このメモを自由に削除してください。
カスタムコマンドの追加
次に、次のコードを含めます。
class TOPTAL_WP_CLI_COMMANDS extends WP_CLI_Command { function remove_user() { echo "\n\n hello world \n\n"; } } WP_CLI::add_command( 'toptal', 'TOPTAL_WP_CLI_COMMANDS' );
このコードブロックは、次の2つのことを行います。
- これは、引数を渡すことができるクラス
TOPTAL_WP_CLI_COMMANDS
を定義します。 - コマンド
toptal
をクラスに割り当てるので、コマンドラインから実行できます。
ここで、 wp toptal remove_user
を実行すると、次のようになります。
$ wp toptal hello hello world
これは、コマンドtoptal
が登録され、サブコマンドremove_user
が機能していることを意味します。
変数の設定
ユーザーを削除する一括処理を行っているため、次の変数を設定します。
// Keep a tally of warnings and loops $total_warnings = 0; $total_users_removed = 0; // If it's a dry run, add this to the end of the success message $dry_suffix = ''; // Keep a list of emails for users we may want to double check $emails_not_existing = array(); $emails_without_level = array(); // Get the args $dry_run = $assoc_args['dry-run']; $level = $assoc_args['level']; $emails = explode( ',', $assoc_args['email'] );
各変数の目的は次のとおりです。
-
total_warnings
:メールが存在しない場合、またはメールが削除するメンバーシップレベルに関連付けられていない場合は、警告を集計します。 -
$total_users_removed
:プロセスで削除されたユーザーの数を集計します(以下の警告を参照)。 -
$dry_suffix
:これがドライランの場合、最終的な成功通知に文言を追加します。 -
$emails_not_existing
:存在しない電子メールのリストを格納します。 -
$emails_without_level
:指定されたレベルを持たない電子メールのリストを格納します。 -
$dry_run
:スクリプトがドライランを実行しているか(true)、実行していないか(false)を格納するブール値。 -
$level
:チェックして削除する可能性のあるレベルを表す整数。 -
$email
:指定されたレベルに対してチェックする一連の電子メール。 この配列をループします
変数を設定すると、実際に関数を実行する準備が整います。 本当のWordPressのやり方で、ループを実行します。
関数自体を書く
まず、 foreach
ループを作成して、 $emails
配列内のすべての電子メールを循環させます。
// Loop through emails foreach ( $emails as $email ) { // code coming soon } // end foreach
次に、条件付きチェックを追加します。
// Loop through emails foreach ( $emails as $email ) { //Get User ID $user_id = email_exists($email); if( !$user_id ) { WP_CLI::warning( "The user {$email} does not seem to exist." ); array_push( $emails_not_existing, $email ); $total_warnings++; continue; } } // end foreach
このチェックにより、チェックしている電子メールに登録ユーザーがいることが保証されます。 email_exists()
関数を使用して、その電子メールを持つユーザーがいるかどうかを確認します。 その電子メールを持つユーザーが見つからない場合は、警告がスローされ、ターミナル画面で電子メールが見つからなかったことがわかります。
$ wp toptal remove_user [email protected] --dry-run Warning: The user [email protected] does not seem to exist.
その後、電子メールは後で表示するために$emails_not_existing
配列に格納されます。 次に、警告の合計を1つ増やし、ループを続けて次の電子メールに進みます。
電子メールが存在する場合は、 $user_id
変数と$level
変数を使用して、ユーザーがレベルにアクセスできるかどうかを確認します。 結果のブール値を$has_level
変数に格納します。
// Loop through emails foreach ( $emails as $email ) { //Get User ID $user_id = email_exists($email); if( !$user_id ) { WP_CLI::warning( "The user {$email} does not seem to exist." ); array_push( $emails_not_existing, $email ); $total_warnings++; continue; } // Check membership level. This is a made up function, but you could write one or your membership plugin probably has one. $has_level = function_to_check_membership_level( $level, $user_id ); } // end foreach
この例のほとんどの関数と同様に、このfunction_to_check_membership_level()
関数は作成されていますが、ほとんどのメンバーシッププラグインには、この情報を取得するためのヘルパー関数が必要です。

次に、メインアクションであるユーザーからレベルを削除することに移ります。 次のようなif/else
構造を使用します。
foreach ( $emails as $email ) { // Previous code here... // Check membership level. This is a made up function, but you could write one or your membership plugin probably has one. $has_level = function_to_check_membership_level( $level, $user_id ); if ( $has_level ) { if ( !$dry_run ) { // Deactivate membership level. This is a made up function, but you could write one or your membership plugin probably has one. function_to_deactivate_membership_level( $level, $user_id, 'inactive' ); } WP_CLI::success( "Membership canceled for {$email}, Level {$level} removed" . PHP_EOL ); $total_users_removed++; } else { WP_CLI::warning( "The user {$email} does not have Level = {$level} membership." ); array_push( $emails_without_level, $email ); $total_warnings++; } // We could echo something here to show that things are processing... } // end foreach
$has_level
の値が「truthy」である場合、つまりユーザーがメンバーシップレベルにアクセスできる場合は、そのレベルを削除する関数を実行する必要があります。 この例では、 function_to_deactivate_membership_level()
関数を使用してこのアクションを実行します。
ただし、実際にユーザーからレベルを削除する前に、その関数を条件付きチェックで囲んで、これが実際にdry-run
であるかどうかを確認します。 そうである場合は、何も削除せず、削除したことを報告するだけです。 dry-run
でない場合は、先に進んでユーザーからレベルを削除し、成功メッセージをターミナルに記録して、電子メールをループし続けます。
一方、 $has_level
の値が「falsey」の場合、つまりユーザーがメンバーシップレベルにアクセスできない場合は、端末に警告を記録し、電子メールを$emails_without_level
配列にプッシュして、続行します。メールをループします。
仕上げとレポート
ループが終了したら、結果をコンソールに記録します。 これがドライランの場合は、コンソールに追加のメッセージを記録します。
if ( $dry_run ) { $dry_suffix = 'BUT, nothing really changed because this was a dry run:-).'; }
この$dry-suffix
は、次にログに記録する警告と成功通知に追加されます。
最後に、結果を成功メッセージとしてログに記録し、警告を警告メッセージとしてログに記録します。 私たちはこのようにします:
WP_CLI::success( "{$total_users_removed} User/s been removed, with {$total_warnings} warnings. {$dry_suffix}" ); if ( $total_warnings ) { $emails_not_existing = implode(',', $emails_not_existing); $emails_without_level = implode(',', $emails_without_level); WP_CLI::warning( "These are the emails to double check and make sure things are on the up and up:" . PHP_EOL . "Non-existent emails: " . $emails_not_existing . PHP_EOL . "Emails without the associated level: " . $emails_without_level . PHP_EOL ); }
WP_CLI::success
メソッドとWP_CLI::warning
ヘルパーメソッドを使用していることに注意してください。 これらは、コンソールに情報を記録するためにWP-CLIによって提供されます。 $total_users_removed
、 $total_warnings
、 $dry_suffix
変数など、ここで行う文字列を簡単にログに記録できます。
最後に、スクリプトの実行中に警告が発生した場合は、その情報をコンソールに出力します。 条件付きチェックを実行した後、 $emails_not_existing
および$emails_without_level
配列変数を文字列変数に変換します。 これは、 WP_CLI::warning
ヘルパーメソッドを使用してコンソールに出力できるようにするためです。
説明の追加
コメントが他の人や、数週間、数か月、さらには数年後にコードに戻る将来の自分に役立つことは誰もが知っています。 WP-CLIは、コマンドに注釈を付けることができる短い説明(shortdesc)と長い説明(longdesc)のインターフェイスを提供します。 TOPTAL_WP_CLI_COMMANDS
クラスが定義された後、コマンドの先頭に配置します。
/** * Remove a membership level from a user * * ## OPTIONS * --level=<number> * : Membership level to check for and remove * * --email=<email> * : Email of user to check against * * [--dry-run] * : Run the entire search/replace operation and show report, but don't save changes to the database. * * ## EXAMPLES * * wp toptal remove_user --level=5 [email protected],[email protected], [email protected] --dry-run * * @when after_wp_load */
longdescでは、カスタムコマンドが受け取るものを定義します。 shortdescとlongdescの構文はMarkdownExtraです。 ## OPTIONS
セクションで、受け取ると予想される引数を定義します。 引数が必要な場合は< >
でラップし、オプションの場合は[ ]
でラップします。
これらのオプションは、コマンドの実行時に検証されます。 たとえば、必要な電子メールパラメータを省略すると、次のエラーが発生します。
$ wp toptal remove_user --level=5 --dry-run Error: Parameter errors: missing --email parameter (Email of user to check against)
## EXAMPLES
のセクションには、呼び出されたときにコマンドがどのように見えるかの例が含まれています。
これでカスタムコマンドが完成しました。 ここで最後の要点を見ることができます。
警告と改善の余地
ここで行った作業を確認して、コードをどのように改善、拡張、リファクタリングできるかを確認することが重要です。 このスクリプトには多くの改善点があります。 ここに、行われる可能性のある改善についてのいくつかの所見があります。
時折、このスクリプトが「削除済み」としてログに記録するすべてのユーザーを削除しないことがわかりました。 これは、クエリの実行速度よりも速くスクリプトが実行されていることが原因である可能性があります。 スクリプトが実行される環境とセットアップによって、エクスペリエンスが異なる場合があります。 これを回避する簡単な方法は、同じ入力で繰り返し実行することです。 最終的にはゼロになり、削除されたユーザーがいないことが報告されます。
スクリプトを改善して、ユーザーが実際に削除されたとログに記録する前に、ユーザーが削除されたことを待機して検証することができます。 これにより、スクリプトの実行速度が低下しますが、より正確になり、実行する必要があるのは1回だけです。
同様に、このようなエラーが見つかった場合、スクリプトはエラーをスローして、レベルがユーザーから削除されていないことを警告する可能性があります。
スクリプトを改善するもう1つの領域は、一度に複数のレベルを1つの電子メールアドレスから削除できるようにすることです。 スクリプトは、削除するレベルが1つ以上あり、電子メールが1つ以上あるかどうかを自動検出できます。 レベルごとにCSVファイルが提供されたので、一度に1つのレベルを実行するだけで済みました。
また、コードの一部をリファクタリングして、現在のより詳細な条件付きチェックの代わりに3項演算子を使用することもできます。 デモンストレーションのためにこれを読みやすくすることを選択しましたが、コードを自由に作成してください。
最終ステップでは、最終ステップでコンソールに電子メールを印刷する代わりに、CSVまたはプレーンテキストファイルに電子メールを自動的にエクスポートすることもできます。
最後に、 $level
変数の整数、または$emails
変数の電子メールまたは電子メールのコンマ区切りリストを取得していることを確認するためのチェックはありません。 現在、誰かが整数の代わりに文字列を含めたり、電子メールの代わりにユーザーログイン名を含めたりすると、スクリプトは機能しません(エラーはスローされません)。 整数と電子メールのチェックを追加できます。
さらなる自動化とさらなる読書のためのアイデア
ご覧のとおり、この特定のユースケースでも、WP-CLIは非常に柔軟で強力であるため、作業を迅速かつ効率的に行うことができます。 「毎日および毎週の開発フローでWP-CLIの実装を開始するにはどうすればよいですか?」と疑問に思われるかもしれません。
WP-CLIを使用する方法はいくつかあります。 これが私のお気に入りのいくつかです:
- 管理パネルに移動せずに、テーマ、プラグイン、およびWPコアを更新します。
- SQLクエリをテストする場合は、バックアップ用にデータベースをエクスポートするか、クイックSQLダンプを実行します。
- WordPressサイトを移行します。
- ダミーデータまたはカスタムプラグインスイートのセットアップを使用して、新しいWordPressサイトをインストールします。
- コアファイルに対してチェックサムを実行して、それらが危険にさらされていないことを確認します。 (実際には、これをWPリポジトリのテーマとプラグインに拡張するプロジェクトが進行中です。)
- サイトホストをチェック、更新、および保守するための独自のスクリプトを作成します(これについてはここで説明しました)。
WP-CLIの可能性はほぼ無限です。 前進し続けるためのリソースは次のとおりです。
- メインのWP-CLIサイト:http://wp-cli.org
- WP-CLIコマンド:https://developer.wordpress.org/cli/commands/
- 公式WP-CLIブログ:https://make.wordpress.org/cli/
- WP-CLIハンドブック:https://make.wordpress.org/cli/handbook/
- WooCommerceに? WC-CLIをチェックアウトします:https://github.com/woocommerce/woocommerce/wiki/WC-CLI-Overview#woocommerce-commands
- プロジェクトのメンテナであるDanielBachhuberへのポッドキャストインタビュー:https://howibuilt.it/episode-28-daniel-bachhuber-wp-cli/