ハイサイ!オースティンやいびーん!
概要
WordPressのプラグインでComposerを設定してパッケージをインストールする方法を紹介します!
その過程で、Composerのオートーローダーも一緒にセットアップします。
背景
こないだ、GoogleでWPユーザーの認証を行えるプラグインを開発していました。Googleでログインする上、古いユーザーのデータベースからデータを移行する機能も必要でした。
それで、独自で認証プラグインを開発することになったのですが、GoogleのPHP APIが必要になってくるのがわかります。そのAPIは、通常、Composerでバージョン管理をしますが、WordPressのプラグインでComposerを使うやり方は明確ではありません。
本記事では筆者が考えた解決法を紹介します!
プラグインのSubModuleをセットアップする
お使いのWordPressアプリケーションのwp-content/plugins
フォルダーに新しいフォルダーを追加します。
そこに、プラグインのメーンファイルにヘッダーを追加します。メーンファイルのファイル名とフォルダー名を同一のkebab-caseの名前に統一してください。
<?php
/**
* Plugin Name: OAuth Plugin
* Description: A plugin which allows third party OAuth in WordPress
* Requires at least: 6.2
* Requires PHP: 8.0.0
* Version: 0.0.0
* Author: Austin J. Mayer
* License: MIT
* Text Domain: am-oauth-plugin
*/
zshで同フォルダー内に入って以下のコマンドを実行します。
git init
git add -A
git commit -m "init commit"
git remote set-url origin https://github.com/your/repo
git push origin master
これで別のレポジトリーとしてこのプラグインのソースコードをバージョン管理できますが、親のレポジトリーにサブモジュールとして登録しないといけません。
筆者のプロジェクトの場合は以下のようにレポジトリーURLと上書きしたいパスを入れました。
cd <レポジトリーのルートフォルダー>
git submodule add https://github.com/tronicboy1/am-oauth-plugin.git ./src/plugins/am-oauth-plugin
こうするとサブモジュールとして機能しています!
Composerをセットアップ
ここからはcomposerを使います。Composerを初めてお使いの方に説明しますが、ComposerはPHPのパッケージをインストールしたり、そのバージョンを管理したりしてくれるソフトウェアです。JavaScriptで言うとNPM、PythonだとPIPに相当するものです。
composerのCLIをインストールする必要があるので、まだの方はHomebrewでインストールすることをお勧めします。Composerのドキュメントでもインストール方法が書いてあります。
brew install composer
そこから、もう一度プラグインのフォルダーに戻ってzshで以下のコマンドを実行します。
composer init
CLIのプロンプトに従って問われる項目を記入していきます。パッケージは今インストールしなくていいです。autoloader
のパスを問われますが、デフォルト値のsrc
で大丈夫です。
終わると以下のようにcomposer.json
が追加されます。
{
"name": "tronicboy1/am-oauth-plugin",
"description": "A plugin which allows third party OAuth in WordPress",
"type": "library",
"license": "MIT",
"autoload": {
"psr-4": {
"Tronicboy1\\AmOauthPlugin\\": "src/"
}
},
"authors": [
{
"name": "Austin John Mayer (井上 オースティン)",
"email": "mayeraus41@gmail.com"
}
],
"require": {}
}
autoload
の項目に注目してほしいです。psr-4
という自動読み込み方策になっていますが、これはsrc
フォルダー内に入っているCamelCase.phpのPHPファイルを読み込んでTronicboy1\AmOauthPlugin
というnamespace・名前空間で使えるようにするものです。これによってrequire_once
を各ファイルにて記述する必要がなくなります。
CamelCase.phpのようなファイルには、同名のクラスを定義する必要があります。そのクラスが別のnamespaceと同じnamespaceで使えるようになります。
試しに必要なファイルを追加してみましょう。最初にam-oauth-plugin.php
にnamespace
とオートロードのrequire
を追加しましょう。
<?php
/**
* Plugin Name: OAuth Plugin
* Description: A plugin which allows third party OAuth in WordPress
* Requires at least: 6.2
* Requires PHP: 8.0.0
* Version: 0.0.0
* Author: Austin J. Mayer
* License: MIT
* Text Domain: am-oauth-plugin
*/
namespace Tronicboy1\AmOauthPlugin;
require 'vendor/autoload.php';
それからsrc
にGoogle認証に必要なファイルを作ります。
ユーザー工場
<?php
namespace Tronicboy1\AmOauthPlugin;
use Exception;
use WP_User;
class UserFactory
{
public function create(string $email, string $password = ''): int
{
$user = new WP_User();
$user->user_email = $email;
$user->user_login = $email;
$user_id = wp_insert_user($user);
if (!is_int($user_id)) {
throw new Exception('UserNotCreated');
}
return $user_id;
}
}
REST APIのコントローラー
<?php
namespace Tronicboy1\AmOauthPlugin;
use WP_REST_Request;
use WP_REST_Response;
class Controller
{
static function init(): void
{
register_rest_route('am-oauth/v1', '/google', [
'methods' => 'POST',
'callback' => 'Tronicboy1\AmOauthPlugin\Controller::google',
'permission_callback' => function () {
return true;
}
]);
}
static function google(WP_REST_Request $request): WP_REST_Response
{
$body = $request->get_json_params();
$text = $body['credential'];
if (!$text) {
return Controller::make400Response('InvalidBody');
}
$factory = new UserFactory();
return Controller::make200Response();
}
static private function make400Response($message = ''): WP_REST_Response
{
$response = new WP_REST_Response($message);
$response->set_status(400);
return $response;
}
static private function make200Response($data = 200): WP_REST_Response
{
$response = new WP_REST_Response($data);
$response->set_status(200);
return $response;
}
}
そして、プラグインメーンファイルのam-oauth-plugin.php
に以下の一行を追加すると、オートーローダーのおかげでうまくいくはずです。
add_action('rest_api_init', __NAMESPACE__ . '\Controller::init');
プラグイン管理画面でこのプラグインを有効にして、WP APIを試してみましょう!
ブラウザで以下のJavaScriptをコンソールで実行してみれば、うまく起動していることが確認できます。
fetch('http://localhost:8080/wp-json/am-oauth/v1/google', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ credential: 'test' })
}).then(console.log);
Googleのパッケージをインストールする
ここまでの説明でComposerが使えるようにできました。自分のソースコードを自動的に読みこむという目当てだけでも使いたくなる、便利なComposerですね。
しかし、本当の目的は第三者パッケージをインストールすることなので、それをしましょう!
以下のコマンドを実行します。
composer require google/apiclient
実行すると、Google PHP APIとそれを実行するために必要になるパッケージをインストールしてくれます。そしてcomposer.lock
を作成して、それぞれのパッケージが相性良くインストールできた状態が別の環境でも再現できるように記録を残してくれるのです。
これをインストールした上でもう一度src/Controller.php
に戻ってGoogleのパッケージを使ってみましょう。
環境変数に僕のAPIコードを設定していますが、とりあえずベタ書きで問題ありません(本番は環境変数に!)。
use Google_Client;
...
static function google(WP_REST_Request $request): WP_REST_Response
{
$body = $request->get_json_params();
$credential = $body['credential'];
if (!$credential) {
return Controller::make400Response('InvalidBody');
}
$client = new Google_Client(['client_id' => getenv('GOOGLE_CLIENT_ID')]);
$factory = new UserFactory();
return Controller::make200Response();
}
これで試してみるとうまくい... あ!エラーが発生!
PHP Fatal error: Composer detected issues in your platform: Your Composer dependencies require a PHP version ">= 8.1.0". You are running 8.0.28.
composer.json
の設定が間違っていましたので、以下のようにconfig
を追加してPHPのバージョンを設定しましょう。
{
"name": "tronicboy1/am-oauth-plugin",
"description": "A plugin which allows third party OAuth in WordPress",
"type": "library",
"license": "MIT",
"autoload": {
"psr-4": {
"Tronicboy1\\AmOauthPlugin\\": "src/"
}
},
"authors": [
{
"name": "Austin John Mayer (井上 オースティン)",
"email": "mayeraus41@gmail.com"
}
],
"require": {
"google/apiclient": "^2.15"
},
"config": {
"platform": {
"php": "8.0.0"
}
}
}
composer.lock
を直す必要があるので以下のコマンドも実行します。
composer update
そうすると、200番が返ってきます。
このあとはGoogleの認証を実装して、フロントエンドでログインできるブロックを実装しますが、それは本記事とは別の課題ですのでここまで!
まとめ
WordPressのプラグインでComposerを使う方法を紹介しましたが、いかがでしょうか?
WordPressは古く、今だと独特極まりない開発環境になりますが、それでも今ももっとも強いCMSであることは変わりないです。うまく付き合っていくしかない。今回の記事はその延長線で考案したものです。
しかし、ComposerのようなモダンなツールとWordPressとの間には相入れない部分があります。
例えば、上記のコードではvendors
をローカルでインストールしているのですが、プラグインとしてインストールする場合、composer install
を実行するわけにはいかないでしょう。
そうなるとどうしたらいいかというと、プラグインとしてバンドルしてリリースする必要があります。
そのやり方もまた別の記事でいずれ書くかもしれません。
とりあえず、WordPressでもComposerが使えるのは非常にありがたいので共有しました!