WordPress プラグイン開発を Docker と VS Code で行う

# この記事で出来るもの
　VS Code で XDebug を使い、 PHPUnit でテストが出来る WordPress プラグイン開発用の Dockerfile と docker-compose.yml と VS Code の設定ファイルと php.ini が出来上がります。

## 環境
- Mac OS 15.5
- Docker Desktop 2.3.0.3
- VS Code 1.47.1
 - PHP Debug 1.13.0 ( Felix Becker 氏の作 )

　ディレクトリ構成は下記の通りだとします。ちなみに、プラグインディレクトリはアンダースコア区切りではなく、ハイフン区切りかキャメルケースを使いましょう。PHPUnitでハマります。
　また、既に yourPlugin.php には適切なヘッダー情報が書いてあるとします。適切なヘッダー情報がよく分からなかったら、 [ここ](#your-plugin-directoryyourpluginphp)をコピペして用意しておきましょう。

```
current_directory
|_.vscode
 |_launch.json
|_docker-compose.yml
|_Dockerfile
|_php.ini
|_your-plugin-directory/
 |_yourPlugin.php
 |_tests/
  |_testYourPlugin.php
```

### PHPUnit でハマるポイント
参考 : [why is phpunit not taking directory which have a underscore '_'](https://stackoverflow.com/questions/19526494/why-is-phpunit-not-taking-directory-which-have-a-underscore)
上記への回答 : [underscore chars in directory name](https://github.com/sebastianbergmann/phpunit/issues/1438)

# Dockerfile & docker-compose.yml
　Docker のベースイメージは、 [Docker Official が提供するもの](https://hub.docker.com/_/wordpress/)です。これに XDebug と PHPUnit をインストールし、 [Docker Compose クイックスタート](http://docs.docker.jp/compose/wordpress.html)にある docker-compose.yml を改変します。

## Dockerfile

```Dockerfile:Dockerfile
FROM wordpress:latest

RUN pecl install xdebug && \
    docker-php-ext-enable xdebug

RUN curl -L https://phar.phpunit.de/phpunit-7.5.9.phar >> phpunit-7.5.9.phar && \
    chmod +x phpunit-7.5.9.phar && \
    mv phpunit-7.5.9.phar /usr/local/bin/phpunit
```

## docker-compose.yml

```yml:docker-compose.yml
version: '3'

services:
  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress

  wordpress:
    depends_on:
      - db
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./your-plugin-directory:/var/www/html/wp-content/plugins/your-plugin-directory
      - ./php.ini:/usr/local/etc/php/php.ini
    ports:
      - "8000:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
volumes:
    db_data:
```

　ここで一旦適当に `touch php.ini` してから `docker-compose build` をしましょう。
　出てきたログの中に php.ini に書き込む zend_extension の設定が書かれているので、注意してください。
　PHPUnit をグローバルにすべきではないと言う声も聞こえてきそうですが、ここは Docker の中でプラグインひとつを開発するための環境なので、あまり気にしていません。

# php.ini と launch.json

　php.ini と .vscode/launch.json を書くことで、 VS Code で PHP Debug を使ったデバッグが出来る様になります。

## php.ini

```ini:php.ini
; Docker Image をビルドすると、
; You should add "zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20180731/xdebug.so" to php.ini
; と言われるので素直に書きます。
; ここは人によって異なる可能性があるので注意が必要です。
zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20180731/xdebug.so
[xdebug]
xdebug.remote_enable=1
xdebug.remote_autostart=1
; ホスト側のIP
; host.docker.internalはdockerのhostマシンのIPを解決してくれます。
; hostマシン以外のIPの場合は適宜IPを調べて設定してください。
xdebug.remote_host=host.docker.internal
; 空いているport番号（xdebugのデフォルトは9000）。
xdebug.remote_port=9000
; xdebugの出力するログの場所。今回は適当に/tmp配下に。
xdebug.remote_log=/tmp/xdebug.log
```

## ./vscode/launch.json

`${workspaceRoot}` を設定するのがキモです。

```json:./vscode/launch.json
{
  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "type": "php",
      "name": "Docker debug",
      "request": "launch",
      "port": 9000,
      "pathMappings": {
        "/var/www/html/wp-content/plugins/your-plugin":"${workspaceRoot}/your-plugin"
      }
    }
  ]
}
```

　ここで `docker-comopse up -d` して、ブラウザから `localhost:8000` にアクセスすることで Wordpress のセットアップが始まります。いつものセットアップが終わった後、管理ページにログインをしてプラグインを見に行くと、既にプラグインがインストールされているはずです。

# 確認

## XDebug
　ちゃんと XDebug が使えるか確認します。そのために、プラグインディレクトリに下記の様なプラグインの雛形を作りましょう。

### your-plugin-directory/yourPlugin.php

```php:your-plugin-directory/yourPlugin.php
<?php
/*
Plugin Name: Your Plugin
Description: プラグインの雛形です。
Version:     0.0.1
Author:      rotelstift
Text Domain: your-plugin
License:     GPL2

*/

class Your_Plugin {
	private const MENU_SLUG = 'your_plugin';

	public function __construct() {
		add_action( 'admin_menu', array( $this, 'add_pages' ) );
	}

	public function add_pages() {
		add_menu_page( 'Your Plugin Option', 'Your Plugin', 'activate_plugins', self::MENU_SLUG, array( $this, 'your_plugin_option_page' ) );
	}

	public function your_plugin_option_page() {
		echo 'This is your plugin.';
	}
}

$your_plugin = new Your_Plugin;
```

　このプラグインを有効化すると、管理ページサイドメニューの一番下に Your Plugin というリンクが追加されるはずです。
　そして、 VS Code のデバッガから echoのある行にブレークポイントを設定してデバッガをスタートさせてから、 Your Plugin のリンクをクリックしましょう。ちゃんとデバッガが動いていれば、 VS Code に処理が移るはずです。

## PHPUnit

　PHPUnit が動くかどうかのテストは簡単です。以下のコマンドを打ちましょう。

```bash
docker-compose run --rm wordpress phpunit --version
```

　これでバージョン情報が表示されれば問題ありません。
　しかし、テストファイルを指定するときに若干の難があります。その難を回避するためには、以下の様にコマンドを打ってください。

```bash
docker-compose run --rm wordpress /bin/bash -c "cd wp-content/plugins/your-plugin && phpunit tests/*"
```

```bash
# 以下の二つはなぜかエラーになる
docker-compose run --rm wordpress phpunit your-plugin/tests/*
docker-compose run --rm wordpress phpunit wp-content/plugins/your-plugin/tests/*
```

　サンプル用のテストファイルは[こちらのリンク先](https://phpunit.readthedocs.io/ja/latest/writing-tests-for-phpunit.html)のものを使えばいいでしょう。

# 参考資料

- [Dockerで構築したPHP環境をxdebugでデバッグ（vscode）](https://qiita.com/gigosa/items/90431be7a6a79db78480)
- [WordPressのプラグインを開発しよう（初級編）](https://www.webopixel.net/wordpress/631.html)
- [管理メニューの追加 - WordPress Codex 日本語版](https://wpdocs.osdn.jp/%E7%AE%A1%E7%90%86%E3%83%A1%E3%83%8B%E3%83%A5%E3%83%BC%E3%81%AE%E8%BF%BD%E5%8A%A0)
- [2. PHPUnit 用のテストの書き方 - PHPUnit latest Manual](https://phpunit.readthedocs.io/ja/latest/writing-tests-for-phpunit.html)
- [Header Requirements | Plugin Developer Handbook | WordPress Developer Resources](https://developer.wordpress.org/plugins/plugin-basics/header-requirements/)