WordPressプラグイン審査に通るまでの実体験:exec削除→承認まで全記録

WordPress プラグイン審査 承認までの記録 WordPress
この記事は約11分で読めます。

「PDFをアップロードしたら、自動でサムネイルが生成されたらいいのに」

そんな素朴な思いから始まったプラグイン開発。完成までに何度もWordPress.orgの審査に落ち、コードを書き直し、セキュリティを見直し…。この記事では、Rapls PDF Image Creatorというプラグインを開発し、公式ディレクトリに公開するまでの全工程を、失敗談も含めて赤裸々に綴ります。

きっかけ:PDFのサムネイルが欲しい

私のサイトでは、PDFファイルを頻繁にアップロードします。カタログ、マニュアル、レポート…。

でも、WordPressのメディアライブラリを開くと、PDFはすべて同じアイコン。

メディアライブラリPDF

「このPDF、何だっけ?」

いちいちダウンロードして開かないと中身がわからない。これが地味にストレスでした。

既存のプラグインも探しましたが、どれも微妙に違う。GhostScriptが必要だったり、有料だったり、更新が止まっていたり。

「ないなら作ろう」

エンジニアなら誰もが一度は思うこのセリフ。私もその誘惑に負けました。

開発環境の準備

まずはローカル環境の構築から。私はLocal by Flywheelを使っています。

必要なもの:
- Local by Flywheel(ローカルWordPress環境)
- Cursor(エディタ)
- - PHP 7.4以上
- - ImageMagick(PDF変換用)

プラグインの基本構造はこんな感じで設計しました:

rapls-pdf-image-creator/
├── rapls-pdf-image-creator.php  # メインファイル
├── includes/
│   ├── Plugin.php               # シングルトンのエントリーポイント
│   ├── Generator.php            # PDF→画像変換のコア
│   ├── Settings.php             # 設定値の管理
│   ├── Admin.php                # 管理画面
│   ├── MediaLibrary.php         # メディアライブラリ連携
│   └── Engine/
│       └── ImagickEngine.php    # ImageMagick実装
├── admin/
│   ├── views/                   # 設定画面のテンプレート
│   ├── css/                     # 管理画面用CSS
│   └── js/                      # 管理画面用JS
└── languages/                   # 翻訳ファイル

名前空間(Namespace)を使ってクラスを整理。オートローダーも自前で実装しました。

最初の壁:PDF変換エンジン

PDFを画像に変換する方法は主に2つあります:

  1. ImageMagick(Imagick PHP拡張) – PHPから直接呼び出せる
  2. GhostScript – コマンドラインツール、exec()で実行

最初は両方に対応しようと思っていました。「ユーザーの環境に合わせて選べるようにしよう」と。

でも、これが後で大きな問題になるとは、この時は知る由もありませんでした…。

機能実装:こだわったポイント

1. アップロード時の自動生成

PDFをアップロードしたら、何もしなくてもサムネイルが生成される。これが一番こだわったポイントです。

add_attachmentフックを使って、PDFがアップロードされたタイミングを検知:

add_action('add_attachment', function($attachmentId) {
    $mime = get_post_mime_type($attachmentId);
    if ($mime === 'application/pdf') {
        // サムネイル生成処理
    }
});

メディアライブラリ

2. アイキャッチ画像として設定

生成したサムネイルをPDFの「アイキャッチ画像」として設定できるようにしました。

これでget_post_thumbnail_id()がPDF添付ファイルでも使えるようになります。テーマ開発者にとっては嬉しい機能のはず。

3. 既存PDFの一括処理

プラグインを有効化する前にアップロードしたPDFはどうする?

「一括生成」機能を実装しました。AJAXで1件ずつ処理して、プログレスバーで進捗を表示。

Rapls PDF Image Creator 一括変換

WordPress.org審査:地獄の始まり

※以下のメール文面は、個人情報(メールアドレス等)を伏せたうえで、要点のみ抜粋しています。

メールのやり取り(時系列の要点)

  1. 自動プレレビュー(AI):名前/スラッグが一般的すぎる、所有権(メールドメイン)確認、プレフィックス、ディレクトリアセット同梱、Deprecated 指摘などが提示される
  2. 私の対応:プラグイン名を Rapls PDF Image Creator に変更し、スラッグも rapls-pdf-image-creator へ。所有権についても「raplsworks は自分のサイト」である旨を明確化
  3. 人のレビュー:Ghostscript エンジンで exec() を使っている点が危険として指摘される(ホスト側でブロックされる/悪用され得る)
  4. 再提出(v1.0.5)exec()/shell_exec() を完全削除し、Ghostscript エンジンを廃止。Imagick のみに一本化
  5. 再提出(v1.0.6):Plugin Check フィードバックを踏まえ、翻訳ロード等を整理。加えて「外部通信なし・追跡なし・nonce/権限チェック・適切なサニタイズ」など、審査チームが確認しやすい形で補足

メールで実際に来た主な指摘(要点)

  • 名前/スラッグが一般的すぎる:既存プラグインと混同されやすいので、ブランド/識別子を含めて区別する
  • 所有権の確認:プラグインの関連URLと、提出アカウントのメールドメインが一致しない場合は説明が必要(第三者なりすまし防止のため)
  • exec()/shell_exec() は危険:リモートコード実行につながり得る/多くのホストで無効化されているため、削除が求められる
  • プレフィックス不足:関数・グローバル・保存データ(option/meta/transient など)に衝突回避のプレフィックス(4文字以上)が必要
  • ディレクトリ用アセットは ZIP に入れない:バナー/アイコン/スクショ等は承認後に SVN の assets へアップロード(ZIP同梱は避ける)
  • Deprecated 関数:将来的に壊れる可能性があるため、代替手段へ置き換える

私が再提出コメントで書いたこと(コピペできる“短い型”)

返信は長文にせず、レビュアーが「確認すべき点」をすぐ拾えるように、次の順で短くまとめました。

Thank you for reviewing my submission.

- Removed all exec()/shell_exec() usage and the Ghostscript-based engine.
- The plugin now uses Imagick only (no OS command execution).
- No external API calls / tracking / remote assets (no CDN).
- Admin/AJAX actions include capability checks and nonce verification.
- Output is sanitized appropriately; logging runs only when WP_DEBUG is enabled.

Thank you again for your guidance.

プラグインが完成し、意気揚々とWordPress.orgに提出。

数日後、メールが届きました。

Your plugin has been reviewed and we have concerns…

却下。

ここから、審査との長い戦いが始まりました。

指摘1: プラグイン名が一般的すぎる

最初は「PDF Image Creator」という名前でした。

プラグイン名にユニークなプレフィックスを付けてください。

「Rapls PDF Image Creator」に変更。Raplsは私のブランド名です。

指摘2: exec()は使用禁止

これが一番痛かった。

GhostScriptエンジンはexec()関数でコマンドを実行していました。

exec()、shell_exec()、system()などのシェル実行関数は、セキュリティ上の理由から使用できません。

せっかく実装したGhostScript対応を、泣く泣く削除。ImageMagick一本に絞りました。

指摘3: プレフィックスの統一

関数名、定数、オプション名…すべてに一貫したプレフィックスが必要でした。

// 修正前
function get_pdf_thumbnail() { ... }
define('PLUGIN_VERSION', '1.0.0');

// 修正後
function rapls_pic_get_thumbnail() { ... }
define('RAPLS_PIC_VERSION', '1.0.0');

指摘4: flush_rewrite_rules()の削除

有効化・無効化時にflush_rewrite_rules()を呼んでいましたが、これも指摘を受けました。

このプラグインはカスタム投稿タイプやリライトルールを登録していません。不要な処理は削除してください。

確かに、意味もなく入れていました。反省。

指摘5: error_log()のファイルパス露出

デバッグ用に入れていたerror_log()が問題に。

// 修正前(危険)
error_log('Error in ' . __FILE__ . ': ' . $e->getMessage());

// 修正後(安全)
if (defined('WP_DEBUG') && WP_DEBUG) {
    error_log('Rapls PDF Image Creator: ' . $e->getMessage());
}

サーバーのファイルパスが露出するのはセキュリティリスク。WP_DEBUGが有効な時だけログを出すように修正しました。

指摘6: load_plugin_textdomain()は不要

翻訳の読み込み処理を入れていましたが…

WordPress 4.6以降、WordPress.orgでホストされるプラグインは翻訳が自動的に読み込まれます。load_plugin_textdomain()は非推奨です。

知らなかった…。削除しました。

指摘7: 日本語翻訳のスタイル

日本語翻訳ファイルも審査対象でした。

WordPress日本語チームの翻訳スタイルガイドに従う必要があります。

// 修正前
"PDFファイルからサムネイルを生成"

// 修正後(半角英字の前後にスペース)
"PDF ファイルからサムネイルを生成"

細かいですが、約50箇所を修正しました。

最終的なコード品質

審査を通過するために、以下の点を徹底しました:

セキュリティ

  • すべての入力値をサニタイズ(sanitize_text_field()absint()など)
  • すべての出力をエスケープ(esc_html()esc_attr()esc_url()
  • AJAX処理には必ずnonce検証と権限チェック
  • カスタムHTMLにはwp_kses_post()でサニタイズ

コーディング規約

  • WordPress Coding Standardsに準拠
  • PHPDoc形式のコメント
  • 適切な名前空間とクラス設計

互換性

  • PHP 7.4以上で動作(readonlyプロパティやmatch式は使わない)
  • WordPress 5.0以上で動作

ついに承認!

承認メール(個人情報を伏せたスクリーンショット)

何度もの修正を経て、ついにメールが届きました。

Congratulations, your plugin hosting request for Rapls PDF Image Creator has been approved.

WordPress Plugin Directory 承認メール

正直、泣きそうになりました。

公開後の反省と学び

良かったこと

  • 審査プロセスを通じて、セキュリティ意識が大幅に向上した
  • WordPressのコーディング規約を深く理解できた
  • 「動けばいい」から「正しく動く」へ意識が変わった

反省点

  • 最初からWordPress.orgのガイドラインを読んでおくべきだった
  • GhostScript対応に時間をかけすぎた(結局削除)
  • 翻訳スタイルガイドの存在を知らなかった

これからプラグインを開発する人へ

  1. まずガイドラインを読むPlugin Guidelinesは必読
  2. Plugin Check プラグインを使う – 提出前に自動チェックできる
  3. exec()系は諦める – 外部コマンド実行は審査に通らない
  4. プレフィックスは最初から統一 – 後から変更するのは大変
  5. セキュリティは妥協しない – サニタイズ・エスケープ・nonce検証

プラグインのダウンロード

Rapls PDF Image Creatorは、WordPress公式ディレクトリから無料でダウンロードできます。

Rapls PDF Image Creator プラグインページ

PDFを扱うサイトを運営している方は、ぜひ試してみてください。


開発者向け:テンプレート関数

テーマ開発者の方向けに、テンプレート関数も用意しています:

<?php
// サムネイルがあるか確認
if (rapls_pic_has_thumbnail($pdf_id)) {
    // サムネイル画像を表示
    echo rapls_pic_get_thumbnail_image($pdf_id, 'medium');
}
?>

ショートコードも4種類用意しているので、コードを書かなくても使えます。

さいごに

プラグイン開発は、想像以上に学びの多い経験でした。

特にWordPress.orgの審査は厳しいですが、その分、公開されているプラグインの品質が担保されています。ユーザーとして、これは安心材料ですよね。

もし「自分でもプラグインを作ってみたい」と思っている方がいれば、ぜひ挑戦してみてください。審査で落ちても、それは成長のチャンス。私も何度も落ちました(笑)

質問があれば、コメント欄でお気軽にどうぞ!


この記事が役に立ったら、シェアしていただけると嬉しいです。

開発を続けるモチベーションになります。

Buy me a coffeeで応援していただけると、さらに嬉しいです!

コメント

タイトルとURLをコピーしました