検証環境:WordPress 6.9.4 / PHP 8.3.21 / Plugin Check (PCP) 1.9 / Xserver スタンダードプラン / 審査体験は Rapls PDF Image Creator(2025年12月〜2026年1月)のもの
WordPress.orgにプラグインを提出して一発で通すのは難しい。でも、落ちる原因は決まっています。
私がRapls PDF Image Creatorを初めて提出したときは、exec()使用禁止・プレフィックス不足・error_log()のパス露出など7項目を指摘されました。正直「ちゃんと動くのに何がダメなの?」と思いましたが、審査は「動くかどうか」ではなくセキュリティとガイドラインの準拠を見ています。
この記事では、提出準備から差し戻し対応、承認後のSVN公開までを一本の記事にまとめました。全体フローの解説に加えて、実際に指摘された7項目の具体的な修正内容も紹介します。
全体の流れを先に把握する
提出から公開までは「ZIP作成 → Plugin Check → 提出 → 差し戻し対応 → 承認 → SVN公開」の5ステップで、この記事はこの順番で解説します。差し戻しの大半は提出前の準備で防げるため、事前準備に時間をかけるのが結果的に最短ルートです。
- 提出用ZIPを作る
- Plugin Check + セルフチェックで不備を潰す
- 提出フォームからZIPをアップロード
- レビューチームから指摘が来たら修正して再提出
- 承認後、SVNリポジトリに初回リリース
WordPress.orgのプラグイン提出ページ
提出前に必ずやること(ここで9割決まる)
差し戻しの大半は提出前に防げます。公式ガイドライン3本に目を通し、2FA設定済みのWordPress.orgアカウントを用意し、プラグインヘッダー・readme.txt・Plugin Checkの3点を整えてから提出してください。
公式ガイドラインにざっと目を通す
最低限、以下の3つは提出前に読んでおいてください。全文を精読する必要はありませんが、「どういう項目がチェックされるのか」の大枠を掴んでおくだけで差し戻しが大幅に減ります。
- Detailed Plugin Guidelines(審査の詳細ガイドライン・全18項目)
- Plugin Security(セキュリティ要件・差し戻し最多のカテゴリ)
- How Your readme.txt Works(readme.txtの書き方)
私はこれを読まずに提出して、GhostScriptエンジン(exec()で外部コマンドを実行する実装)を丸ごと削除する羽目になりました。最初からガイドラインを読んでおけば、そもそもexec()を使う設計にしなかったはずです。
WordPress.orgアカウントと2FAの準備
2025年現在、プラグイン提出には2FA(2段階認証)が必須です。設定していないと提出ボタンを押しても先に進めません。https://login.wordpress.org/registerでアカウントを作成し、Edit Profile → Security タブからTwo-Factor Authenticationを設定してください。ユーザー名は後から変更できません。readme.txtのContributorsに記載する名前になるので、慎重に決めてください。
プラグインヘッダーを整える
レビュー担当が最初に見るのがメインPHPファイルのヘッダーです。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?php /** * Plugin Name: Your Plugin Name * Plugin URI: https://example.com/your-plugin * Description: A brief description in English (~140 characters). * Version: 1.0.0 * Requires at least: 6.0 * Requires PHP: 7.4 * Author: Your Name * Author URI: https://example.com * License: GPLv2 or later * License URI: https://www.gnu.org/licenses/gpl-2.0.html * Text Domain: your-plugin-slug * Domain Path: /languages */ if ( ! defined( 'ABSPATH' ) ) { exit; } |
差し戻されやすいポイントは以下の4つです。DescriptionとPlugin URI、Author URIは英語で書く(日本語は公開後の翻訳システムで対応)。Versionとreadme.txtのStable tagを完全に一致させる(「1.0」と「1.0.0」の違いでも差し戻し)。Text Domainはフォルダ名(slug)と一致させる。直接アクセス防止(defined('ABSPATH'))を全PHPファイルに入れる。
readme.txtを作成する
readme.txtはプラグインページの元データになる重要ファイルです。以下の雛形をベースに作成してください。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
=== Your Plugin Name === Contributors: yourwporgusername Tags: utility, admin, tool Requires at least: 6.0 Tested up to: 6.7 Stable tag: 1.0.0 Requires PHP: 7.4 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html A short description (max 150 characters, no markup). == Description == Write a detailed description here. == Installation == 1. Go to "Plugins" → "Add New" 2. Search for "Your Plugin Name" 3. Click "Install Now" and then "Activate" == Frequently Asked Questions == = Is this plugin free? = Yes, completely free and open source. == Changelog == = 1.0.0 = * Initial release |
Contributorsには WordPress.orgのユーザー名を書く(任意の名前ではない)。Stable tagはPHPヘッダーのVersionと完全一致させる。Tested up toは実際にテストしたバージョンを書く。Stable tag: trunkは使わない(作業途中のコードが配布されるリスクがある)。作成後はReadme Validatorで必ず検証してください。
Plugin Checkで検査する(提出前の最重要タスク)
Plugin Check(PCP)はWordPress.org公式の検査ツールで、提出時に行われるチェックの大部分を事前に実行できます。カテゴリ「Plugin repo」のERRORをゼロにしてから提出してください。ERRORが残っていると提出自体がブロックされます。
WordPress管理画面 → プラグイン → 新規追加 →「Plugin Check」で検索してインストールし、ツール → Plugin Check でチェックしたいプラグインを選択、カテゴリ「Plugin repo」を選んで実行します。
ERROR(赤)は必ずゼロにしてください。WARNING(黄)は可能な限り対応し、どうしても消せないものは理由を説明できる状態にしておきます。「Plugin repo」に加えて「Security」カテゴリも実行しておくとセキュリティ上の問題を先に発見できます。
Plugin Checkの実行結果。
よく出る指摘と修正方法
私の経験上、Plugin Checkの指摘の大半は以下の5パターンに集約されます。
1. エスケープ不足(最も多い)
|
1 2 3 4 5 6 7 |
// NG: エスケープなし echo $user_input; // OK: 適切なエスケープ関数を使用 echo esc_html( $user_input ); echo esc_url( $url ); echo '<input value="' . esc_attr( $value ) . '">'; |
HTMLに出力する文字列にはesc_html()、URLにはesc_url()、HTML属性値にはesc_attr()。「自分で作ったデータだからエスケープ不要」は通用しません。
2. サニタイズ不足
|
1 2 3 4 5 |
// NG: サニタイズなし $value = $_POST['value']; // OK: サニタイズあり $value = sanitize_text_field( wp_unslash( $_POST['value'] ) ); |
3. Nonceと権限チェックの不足
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// NG: 検証なしで保存 if ( isset( $_POST['save'] ) ) { update_option( 'my_option', $_POST['value'] ); } // OK: Nonce + 権限チェックあり if ( isset( $_POST['save'] ) ) { if ( ! wp_verify_nonce( $_POST['_wpnonce'], 'my_save_action' ) ) { wp_die( 'Security check failed' ); } if ( ! current_user_can( 'manage_options' ) ) { wp_die( 'Permission denied' ); } update_option( 'my_option', sanitize_text_field( $_POST['value'] ) ); } |
4. 直接アクセス防止の不足(全PHPファイルの先頭にif ( ! defined( 'ABSPATH' ) ) { exit; })
5. プレフィックスの問題(関数名・クラス名・定数名に4文字以上のプラグイン固有プレフィックスを付ける)
実際の審査で指摘された7つのポイント(実体験)
私がRapls PDF Image Creatorの審査で指摘されたのは「exec()使用禁止」「プラグイン名が一般的すぎる」「プレフィックス不足」「error_log()のパス露出」「flush_rewrite_rules()が不要」「load_plugin_textdomain()が非推奨」「日本語翻訳スタイルガイド違反」の7項目で、最も工数がかかったのはexec()の全削除でした。
Plugin Checkで検出できる問題以外にも、人間のレビュアーが指摘する項目があります。以下は私が実際に受けた指摘です。
指摘1:exec()/shell_exec()は使用禁止
これが一番痛かった指摘です。PDF→画像変換にGhostScriptエンジンを実装しており、exec()でコマンドを実行していました。
レビュアーからの指摘は明確でした。「exec()、shell_exec()、system()などのシェル実行関数は、セキュリティ上の理由から使用できません。リモートコード実行につながり得る上、多くのホスティング環境で無効化されています。」
せっかく実装したGhostScript対応を丸ごと削除し、ImageMagick(Imagick PHP拡張)一本に絞りました。最初からガイドラインを読んでいれば、この工数は丸ごと不要でした。
指摘2:プラグイン名が一般的すぎる
最初は「PDF Image Creator」という名前で提出しました。「既存プラグインと混同されやすいので、ブランド名や識別子を含めて区別してください」と指摘を受け、「Rapls PDF Image Creator」に変更しました。
指摘3:error_log()のファイルパス露出
|
1 2 3 4 5 6 7 |
// 修正前(危険)——サーバーのファイルパスが露出する error_log('Error in ' . __FILE__ . ': ' . $e->getMessage()); // 修正後(安全)——WP_DEBUGが有効な時だけログを出す if (defined('WP_DEBUG') && WP_DEBUG) { error_log('Rapls PDF Image Creator: ' . $e->getMessage()); } |
指摘4:flush_rewrite_rules()が不要
有効化・無効化時にflush_rewrite_rules()を呼んでいましたが、「このプラグインはカスタム投稿タイプやリライトルールを登録していません。不要な処理は削除してください」と指摘されました。
指摘5:load_plugin_textdomain()は非推奨
WordPress 4.6以降、WordPress.orgでホストされるプラグインは翻訳が自動的に読み込まれるため、load_plugin_textdomain()は不要です。知らずに入れていたので削除しました。
指摘6:日本語翻訳スタイルガイド違反
日本語翻訳ファイルも審査対象です。WordPress日本語チームの翻訳スタイルガイドに従う必要があり、半角英字の前後にスペースを入れるルール(「PDFファイル」→「PDF ファイル」)などで約50箇所を修正しました。
指摘7:ディレクトリ用アセットをZIPに含めない
バナー・アイコン・スクリーンショットはZIPに含めず、承認後にSVNのassets/ディレクトリにアップロードします。
提出用ZIPを作成する
ZIPの直下にプラグインフォルダが1つだけ入っている状態にし、.git・node_modules・.DS_Store・機密情報ファイルを除外してから作成してください。二重フォルダは差し戻しの原因になります。
|
1 2 3 4 5 6 7 8 9 |
your-plugin-slug.zip └── your-plugin-slug/ ├── your-plugin-slug.php ← メインファイル ├── readme.txt ← 必須 ├── includes/ ├── assets/ │ ├── css/ │ └── js/ └── languages/ |
|
1 2 3 4 |
# Mac / Linux でのZIP作成例 cd /path/to/plugins zip -r your-plugin-slug.zip your-plugin-slug \ -x "*.git*" "*.DS_Store" "*__MACOSX*" "*node_modules*" |
提出する
提出ページからZIPをアップロードすると、Plugin Checkが自動実行されてERRORがなければ審査キューに入ります。slugは承認後に変更できないので、スペルミスや商標侵害がないか提出前に必ず確認してください。
プラグイン提出フォーム
slugはプラグインのURL(https://wordpress.org/plugins/your-plugin-slug/)として永久に固定されます。審査の待ち時間は通常1〜10営業日で、混雑時は2週間以上かかることもあります。催促は逆効果になるので、2週間は待ちましょう。
差し戻しが来たときの対応
差し戻しメールが来たらまず翻訳して指摘箇所を抜き出し、セキュリティ関連(Nonce・権限・エスケープ・サニタイズ)を最優先で修正してください。修正後はバージョンを上げてPlugin Checkを再実行し、提出ページから新ZIPをアップロードして修正内容を箇条書きで返信します。
審査で問題が見つかると、plugins@wordpress.orgから英語のメールが届きます。メールをDeepLやGoogle翻訳にかけて、指摘箇所(ファイル名・関数名・行番号)、問題の種類、修正の方向性を整理してください。
私が経験した審査の流れ
Rapls PDF Image Creatorの審査では、以下の流れで進みました。
- 自動プレレビュー(AI):名前/スラッグが一般的すぎる、所有権確認、プレフィックス、Deprecated指摘などが提示される
- 私の対応:プラグイン名をRapls PDF Image Creatorに変更し、所有権を明確化
- 人間のレビュー:exec()が危険として指摘される
- 再提出(v1.0.5):exec()/shell_exec()を完全削除し、Imagickのみに一本化
- 再提出(v1.0.6):Plugin Checkフィードバックを踏まえて翻訳ロード等を整理
- 承認
レビューチームからの差し戻しメール
修正したZIPの再提出方法
指摘を修正してバージョンを上げ(PHPヘッダーとreadme.txtの両方)、Plugin Checkを再実行してERRORゼロを確認してから新しいZIPを作成します。提出ページで自分の申請を開き、新ZIPをアップロードしてレビュー担当にメールで修正内容を連絡します。
返信テンプレート
修正内容を箇条書きで伝えるのがポイントです。長文より、何を直したかがひと目でわかるメールのほうがスムーズに進みます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Hi Plugin Review Team, Thank you for your feedback. I have uploaded the corrected ZIP (version 1.0.1). Changes made: 1) Added esc_html() to all output in admin-page.php (lines 45, 67, 89) 2) Added nonce verification to the settings save function 3) Added current_user_can('manage_options') check 4) Changed function prefix from "mp_" to "my_plugin_" 5) Added sanitize_text_field() to all $_POST inputs Plugin Check re-run: 0 errors confirmed. Best regards, [Your Name] |
指摘の意味がわからない場合は、メールに返信して質問して問題ありません。丁寧に聞けば教えてもらえます。
承認されたらSVNで初回リリース
承認メールに記載されたSVNリポジトリURLにcheckoutし、trunkにファイルを配置してcommit、assetsにバナー・アイコンを配置、tagsにバージョンをコピーすれば公開完了です。assetsはtrunk/assets/ではなくリポジトリ直下のassets/に置いてください。
リポジトリの構造
|
1 2 3 4 5 6 |
your-plugin-slug/ ├── trunk/ ← プラグインの最新コード ├── tags/ ← リリース済みバージョンのスナップショット │ └── 1.0.0/ ├── branches/ ← 通常は使わない └── assets/ ← バナー・アイコン・SS(※trunkの中ではない) |
初回リリースの手順
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# ① リポジトリをチェックアウト svn checkout https://plugins.svn.wordpress.org/your-plugin-slug/ wporg-svn cd wporg-svn # ② trunkにプラグインファイルを配置 cp -r /path/to/your-plugin/* trunk/ svn add trunk/* --force # ③ assetsにバナー・アイコンを配置(※リポジトリ直下のassets/) cp /path/to/banner-772x250.png assets/ cp /path/to/icon-256x256.png assets/ svn add assets/* --force # ④ コミット svn ci -m "Initial release: version 1.0.0" # ⑤ tagsにバージョンを固定 svn cp trunk tags/1.0.0 svn ci -m "Tag version 1.0.0" |
assets/に置きます。trunk/assets/ではありません。私もここを間違えて半日悩みました。配置場所が違ってもエラーメッセージが出ないので気づきにくいのが厄介です。assetsのファイル名と画像サイズは以下の通りです。
| 種類 | ファイル名 | サイズ |
|---|---|---|
| バナー | banner-772×250.png | 772×250px |
| バナー(Retina) | banner-1544×500.png | 1544×500px |
| アイコン | icon-128×128.png | 128×128px |
| アイコン(Retina) | icon-256×256.png | 256×256px |
| スクリーンショット | screenshot-1.png, screenshot-2.png … | 横幅1200px程度推奨 |
公開後のプラグインページ。バナー・アイコン・説明文がassetsから読み込まれている
commitからプラグインページへの反映まで15分〜数時間かかることがあります。CDNキャッシュの影響なので、焦って何度もcommitしないでください。
次のバージョンをリリースするとき
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# 最新状態を取得 cd wporg-svn && svn up # trunkのファイルを更新 cp -r /path/to/updated-plugin/* trunk/ # 削除されたファイルがあれば一括処理 svn status | grep '^!' | awk '{print $2}' | xargs svn delete # コミット svn ci -m "Update to version 1.0.1" # tagsに新バージョンをコピー svn cp trunk tags/1.0.1 svn ci -m "Tag version 1.0.1" |
PHPヘッダーのVersionとreadme.txtのStable tagを新バージョンに更新するのを忘れずに。ここがズレていると更新通知が正しく動きません。
提出前チェックリスト
以下のすべてにチェックが付いたら提出してください。アカウント・ヘッダー・readme.txt・Plugin Check・ZIPの5カテゴリで確認します。
【アカウント】
□ WordPress.orgアカウント作成済み
□ 2FA有効化済み
□ 復旧コードを安全に保管
【プラグインヘッダー】
□ 必須項目をすべて記載(英語で)
□ Text Domain = フォルダ名 = slug が一致
□ 全PHPファイルに直接アクセス防止を追加
□ 同梱物がすべてGPL互換ライセンス
□ exec()/shell_exec()/system()を使っていない
【readme.txt】
□ 英語で記載、標準フォーマットに従っている
□ Readme Validatorでエラーゼロ
□ Stable tag = PHPヘッダーのVersion(完全一致)
□ Tested up toは実際にテストしたバージョン
□ ContributorsがWordPress.orgのユーザー名
【Plugin Check】
□ Plugin repoカテゴリのERRORがゼロ
□ (推奨)SecurityカテゴリもERRORゼロ
【ZIP】
□ 直下にプラグインフォルダが1つ(二重フォルダなし)
□ 不要ファイルを除外(.git, node_modules, .DS_Store等)
□ バナー・アイコン・スクリーンショットを含めていない
□ 機密情報が含まれていない
参考リンク集
この記事で参照した公式ドキュメントの一覧です。審査中に迷ったらまずこれらを確認してください。
まとめ
差し戻しの原因はほぼ決まっています。エスケープ不足・サニタイズ不足・Nonce未検証・権限チェック忘れ・バージョン番号の不一致の5つを潰し、exec()系を使わず、Plugin CheckのERRORをゼロにしてから提出すれば、大半の差し戻しは防げます。
承認後のSVN操作も、assetsの配置場所(trunk/assets/ではなくassets/)とStable tagの仕組みさえ理解すれば難しくありません。
最初の1回は大変ですが、一度公開してしまえばあとはSVNでアップデートするだけです。審査で落ちても、それは成長のチャンスです。私も何度も落ちましたが、その分だけセキュリティ意識とコード品質が確実に上がりました。自分のプラグインが世界中のWordPressサイトで使われる体験は、開発者として格別です。












コメント