8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

WordPressプラグイン開発:Composerでパッケージをインストールする方法

Posted at

ハイサイ!オースティンやいびーん!

概要

WordPressのプラグインでComposerを設定してパッケージをインストールする方法を紹介します!

その過程で、Composerのオートーローダーも一緒にセットアップします。

背景

こないだ、GoogleでWPユーザーの認証を行えるプラグインを開発していました。Googleでログインする上、古いユーザーのデータベースからデータを移行する機能も必要でした。

それで、独自で認証プラグインを開発することになったのですが、GoogleのPHP APIが必要になってくるのがわかります。そのAPIは、通常、Composerでバージョン管理をしますが、WordPressのプラグインでComposerを使うやり方は明確ではありません。

本記事では筆者が考えた解決法を紹介します!

プラグインのSubModuleをセットアップする

お使いのWordPressアプリケーションのwp-content/pluginsフォルダーに新しいフォルダーを追加します。

そこに、プラグインのメーンファイルにヘッダーを追加します。メーンファイルのファイル名とフォルダー名を同一のkebab-caseの名前に統一してください。

wp-content/plugins/am-oauth-plugin/am-oauth-plugin.php
<?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が追加されます。

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.phpnamespaceとオートロードのrequireを追加しましょう。

am-oauth-plugin.php
<?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認証に必要なファイルを作ります。

ユーザー工場

src/UserFactory.php
<?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のコントローラー

src/Controller.php
<?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を試してみましょう!

Screenshot 2023-05-20 at 7.47.59.png

ブラウザで以下の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);

Screenshot 2023-05-20 at 7.51.13.png

Googleのパッケージをインストールする

ここまでの説明でComposerが使えるようにできました。自分のソースコードを自動的に読みこむという目当てだけでも使いたくなる、便利なComposerですね。

しかし、本当の目的は第三者パッケージをインストールすることなので、それをしましょう!

以下のコマンドを実行します。

composer require google/apiclient

実行すると、Google PHP APIとそれを実行するために必要になるパッケージをインストールしてくれます。そしてcomposer.lockを作成して、それぞれのパッケージが相性良くインストールできた状態が別の環境でも再現できるように記録を残してくれるのです。

これをインストールした上でもう一度src/Controller.phpに戻ってGoogleのパッケージを使ってみましょう。

環境変数に僕のAPIコードを設定していますが、とりあえずベタ書きで問題ありません(本番は環境変数に!)。

src/Controller.php
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のバージョンを設定しましょう。

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": {
    "google/apiclient": "^2.15"
  },
  "config": {
    "platform": {
        "php": "8.0.0"
    }
  }
}

composer.lockを直す必要があるので以下のコマンドも実行します。

composer update 

そうすると、200番が返ってきます。

Screenshot 2023-05-20 at 8.09.16.png

このあとはGoogleの認証を実装して、フロントエンドでログインできるブロックを実装しますが、それは本記事とは別の課題ですのでここまで!

まとめ

WordPressのプラグインでComposerを使う方法を紹介しましたが、いかがでしょうか?

WordPressは古く、今だと独特極まりない開発環境になりますが、それでも今ももっとも強いCMSであることは変わりないです。うまく付き合っていくしかない。今回の記事はその延長線で考案したものです。

しかし、ComposerのようなモダンなツールとWordPressとの間には相入れない部分があります。

例えば、上記のコードではvendorsをローカルでインストールしているのですが、プラグインとしてインストールする場合、composer installを実行するわけにはいかないでしょう。

そうなるとどうしたらいいかというと、プラグインとしてバンドルしてリリースする必要があります。

そのやり方もまた別の記事でいずれ書くかもしれません。

とりあえず、WordPressでもComposerが使えるのは非常にありがたいので共有しました!

8
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?