mcpField
W
wp-woocommerce-dev

wp-woocommerce-dev

github.com/jorgerosalテスト・品質11176 回インストール20 週間前に更新
リポジトリ

wp-woocommerce-dev について

WooCommerce 拡張機能やストア連携を開発する人向けのコードレビュー技能です。HPOS 対応のデータアクセス、決済コードの安全性、フック、テンプレート、性能パターンを確認します。

主な機能

  1. 01HPOS 互換性の確認
  2. 02WooCommerce CRUD 利用のレビュー
  3. 03決済ゲートウェイの安全策の監査
  4. 04フックとテンプレート上書きの確認
  5. 05クエリとバックグラウンド処理のリスク検出

活用シーン

  1. 01拡張機能の HPOS 対応監査
  2. 02決済ゲートウェイ実装のレビュー
  3. 03テンプレート上書きとフック維持の確認
  4. 04カートや商品クエリの非効率なパターンの検出

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/jorgerosal/wordpress-skills --skill wp-woocommerce-dev

インストール後、Claude Code で/wp-woocommerce-devを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
wc-extension-guide.md
wc-performance-guide.md
wc-template-guide.md

詳細

WooCommerce 開発レビューのスキル

概要

WooCommerce 8.2 以降から最新の 10.x までを対象とした、体系的な WooCommerce 開発レビューです。基本原則: WooCommerce はアーキテクチャを根本的に変更しました。HPOS(High-Performance Order Storage)は WC 8.2(2023 年 10 月)以降、新規ストアでデフォルトとなっており、すべての拡張機能で CRUD API のみを使用する必要があります。最新の WooCommerce 環境で注文に直接投稿アクセスすると、正常に動作しません。

拡張機能では、WC_Data CRUD パターン(wc_get_order()、wc_get_orders()、WC_Order メソッド)、バックグラウンド処理には Action Scheduler、保守性を高めるにはテンプレートのオーバーライドよりフックを優先する方法を使用する必要があります。決済ゲートウェイでは、生のカードデータを保存またはログに記録してはなりません。カートフラグメントは条件付きで読み込む必要があります。テンプレートをオーバーライドする場合は、すべてのアクションフックを維持する必要があります。

このレビューでは、HPOS との互換性、決済ゲートウェイのセキュリティ(コードレベルのみ。PCI 準拠の監査は対象外)、WooCommerce のフック使用状況、テンプレートのオーバーライドの品質、パフォーマンスパターンを検証します。WooCommerce のコンテキスト(拡張機能、テーマ連携、決済ゲートウェイ、配送方法、カスタム商品タイプ、WC Blocks 連携)を自動検出し、レビューの指針を調整します。検出結果はファイルごとにまとめ、行番号、重要度ラベル(CRITICAL/WARNING/INFO)、BAD/GOOD のコード例を含めて報告します。

注: このスキルは、これまでのすべてのスキルに関係します。セキュリティ(決済データの取り扱い)、プラグインアーキテクチャ(拡張機能としての WC)、ブロック(WC Blocks)、テーマ(テンプレートのオーバーライド)、パフォーマンス(カートフラグメント、クエリ)が対象です。関連する情報への参照を随所に記載しています。

使用する場面

次の場合に使用します:

  • WooCommerce 拡張機能のアーキテクチャレビュー
  • HPOS 互換性の監査(declare_compatibility の確認、CRUD のみを使用しているかの検証)
  • 決済ゲートウェイのコードレビュー(WC_Payment_Gateway のパターン、セキュリティ上のアンチパターン)
  • 配送方法のレビュー(WC_Shipping_Method、calculate_shipping)
  • カスタム商品タイプのレビュー(WC_Product の拡張、データストア)
  • WooCommerce フックの使用状況の分析(注文のライフサイクル、商品データ、カート/チェックアウト)
  • テンプレートのオーバーライドの評価(フックの維持、バージョン管理)
  • カートフラグメントのパフォーマンス分析(サイト全体での読み込みを検出)
  • Action Scheduler のパターンのレビュー(wp_cron のアンチパターンとの比較)
  • WooCommerce REST API 拡張機能のレビュー
  • WC Blocks 連携の確認(Store API、Additional Checkout Fields API)
  • Webhook セキュリティのレビュー(署名の検証)

次の場合は使用しないでください:

  • 一般的なプラグインアーキテクチャ(wp-plugin-development を使用)
  • セキュリティのみの監査(包括的な分析には wp-security-review を使用)
  • WC 以外のブロック開発(wp-block-development を使用)
  • WC 連携のないテーマのみのレビュー(wp-theme-development を使用)
  • パフォーマンスのみのレビュー(wp-performance-review を使用)
  • PCI 準拠の監査(対象外。インフラストラクチャレベルのため)
  • ストアのセットアップやホスティング設定(対象外)

コードレビューワークフロー

WooCommerce の体系的なレビューでは、次の 8 ステップのワークフローに従います。

1. ファイル構成から WooCommerce のコンテキストを検出する

拡張機能/プラグイン:

  • WC の依存関係チェックを含むメインのプラグインファイル(プラグインヘッダーに WooCommerce と記載)
  • before_woocommerce_init フックによる HPOS の宣言
  • 最も一般的なコンテキストです。HPOS、CRUD、フックを全面的に監査します。

テーマ連携:

  • テーマ内に woocommerce/ ディレクトリがあり、テンプレートをオーバーライドしている
  • フックを優先する指針に基づき、テンプレートのオーバーライドを重点的に確認
  • テーマのパターンについては wp-theme-development も参照

決済ゲートウェイ:

  • WC_Payment_Gateway を継承するクラス
  • セキュリティを重点的に確認(生のカードデータは決して保存しない、HTTPS を確認)
  • 該当する場合は Webhook の検証

配送方法:

  • WC_Shipping_Method を継承するクラス
  • calculate_shipping() のレビュー、配送ゾーンのサポート、料金計算

カスタム商品タイプ:

  • WC_Product を継承するクラス
  • データストアのレビュー、商品タイプの登録、クラス階層

WC Blocks 連携:

  • Store API の使用状況、チェックアウトブロックの拡張ポイント
  • Additional Checkout Fields API(WC 8.6 以降)
  • 表層的なレビューを行い、ブロックパターンの詳細な確認には wp-block-development を提案
2. HPOS との互換性を確認する(WOO-16)

欠落している場合は重大です:

  • before_woocommerce_init フック内の declare_compatibility() 呼び出し
  • 検索するパターン:FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true ) を含む add_action( 'before_woocommerce_init', ... )

重大な違反:

  • post_type='shop_order' を指定した get_posts() または WP_Query
  • 注文データに対する get_post_meta()/update_post_meta()
  • 注文データを対象とした wp_posts/wp_postmeta への直接的な $wpdb クエリ

警告対象の違反:

  • post_type='product' を指定した WP_Query(将来の互換性を損なう可能性があります。カスタム商品テーブルが計画されています)

適切なパターン:

  • wc_get_order( $order_id )
  • wc_get_orders( array( 'status' => 'completed', 'limit' => 10 ) )
  • $order->get_meta( 'key' )、$order->update_meta_data( 'key', $value )、$order->save()

互換モードへの対応:

  • コードは HPOS とレガシーモードの両方で動作する必要があります
  • CRUD API のみを使用してください。両方の保存モードに対応しています
3. データアクセスパターンを確認する(WOO-02、WOO-17)

商品へのアクセス:

  • 適切:wc_get_product( $id )、WC_Product_Query
  • 警告:post_type='product' を指定した WP_Query(代わりに wc_get_products() を使用してください)
  • 重大:商品テーブルに対する直接的な $wpdb クエリ

注文へのアクセス:

  • 適切:wc_get_order( $id )、wc_get_orders()
  • 重大:post_type='shop_order' を指定した get_posts()
  • 重大:注文データに対する直接的な $wpdb クエリ

WC_Data パターン:

  • すべての WooCommerce CRUD オブジェクトの基底クラスです
  • データストアが永続化方式(投稿ベースまたは HPOS テーブル)を処理します
  • 変更後は必ず ->save() を呼び出してください
4. 決済ゲートウェイが検出された場合(WOO-03、WOO-19、WOO-20)

重大な違反:

  • 生のカード番号/CVV をデータベースまたはセッションに保存する
  • error_log() または debug.log にカードデータを記録する
  • HTTP(非 SSL)経由でカードデータを送信する

警告対象の違反:

  • API 認証情報をコードにハードコードする(設定を使用してください)
  • 決済処理前に is_ssl() チェックがない
  • Webhook の署名検証がない

process_payment() の検証:

  • 'result' と 'redirect' のキーを含む配列を返す必要があります
  • 手動でステータスを変更するのではなく、$order->payment_complete( $transaction_id ) を使用してください
  • 生の $_POST のカードデータには決してアクセスせず、トークン化を使用してください

相互参照:

  • 一般的なセキュリティパターンについては wp-security-review を参照してください
  • このスキルでは、WC 固有の決済に関するアンチパターンのみを扱います
5. WooCommerce フックの使用状況を確認する(WOO-05、WOO-06、WOO-07、WOO-08)

ライフサイクルフック:

  • woocommerce_before_cart、woocommerce_after_cart
  • woocommerce_checkout_process、woocommerce_checkout_create_order
  • woocommerce_thankyou
  • woocommerce_order_status_changed

商品データフック:

  • 管理画面のフィールドには woocommerce_product_options_*
  • 保存には woocommerce_process_product_meta

チェックアウトフィールドのフック:

  • フィールドの追加には woocommerce_checkout_fields
  • 保存には woocommerce_checkout_update_order_meta

カートフック:

  • カスタムカートデータには woocommerce_add_cart_item_data
  • 手数料には woocommerce_cart_calculate_fees
  • 検証には woocommerce_check_cart_items

注文ステータスの遷移:

  • 特定のステータス変更には woocommerce_order_status_{status}
  • 投稿ステータスを直接変更するのではなく、メモを付けて $order->set_status() を使用してください
6. テンプレートのオーバーライドを確認する(WOO-10、WOO-11、WOO-12、WOO-13)

重大な違反:

  • do_action() フックが削除されたテンプレートのオーバーライド
  • プラグインとの連携が壊れ、他の拡張機能がフックを追加できなくなります

警告対象の違反:

  • バージョンが古いテンプレート(@version コメントの不一致)
  • WooCommerce の更新を取り込めず、表示上の問題が発生する可能性があります

情報としての提案:

  • フックが存在する箇所でテンプレートをオーバーライドしている場合は、代わりにフックの使用を提案します

フック優先の考え方:

  • 重要なポイント:テンプレートのオーバーライドよりフックが強く推奨されます
  • テンプレートのオーバーライドは最終手段にしてください
  • 元のテンプレートにある do_action() 呼び出しはすべて必ず維持してください

相互参照:

  • 一般的なテンプレートパターンについては wp-theme-development を参照してください
7. パフォーマンスパターンを確認する(WOO-15、WOO-17、WOO-18)

カートフラグメント(wc-cart-fragments.js):

  • CRITICAL:条件付きの登録解除がなく、サイト全体で読み込まれています
  • WARNING:理由なく WooCommerce 以外のページでも読み込まれています
  • GOOD:カート/チェックアウト/商品ページでのみ条件付きに登録解除しています
  • BETTER:Mini-Cart Block に移行します(最適化機能が組み込まれています)

商品クエリ:

  • CRITICAL:商品に対して wp_posts を直接 SQL クエリしています
  • WARNING:post_type='product' を指定した WP_Query
  • INFO:商品を繰り返し読み込む際のオブジェクトキャッシュがありません

Action Scheduler:

  • WARNING:一括 WooCommerce 操作に wp_cron() を使用しています(信頼性が低く、トラフィックに依存します)
  • GOOD:as_enqueue_async_action()、as_schedule_single_action()
  • WooCommerce に同梱されているため、個別のインストールは不要です

セッション処理:

  • WARNING:カスタムセッションフィルターが 30 日の上限を超えています(WC 10.1 以降)
  • INFO:WC_Session_Handler を介さないカスタムセッション実装があります

相互参照:

  • 包括的なパフォーマンス分析については、wp-performance-review を参照してください
8. 以下の出力形式でレポートする

必要に応じて、関連するスキルも相互参照してください。

  • セキュリティ上の懸念 → /wp-sec-review
  • プラグインのアーキテクチャ → /wp-plugin-review
  • ブロックの問題 → /wp-block-review
  • テーマの問題 → /wp-theme-review
  • パフォーマンスの問題 → /wp-perf-review

ファイルタイプ別のチェック項目

HPOS 互換性(WOO-16)

互換性宣言(ない場合は CRITICAL):

// GOOD: Declare HPOS compatibility
add_action( 'before_woocommerce_init', function() {
    if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
        \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility(
            'custom_order_tables',
            __FILE__,
            true
        );
    }
} );

// BAD: Missing declaration
// Extension silently breaks on HPOS-enabled stores

投稿への直接アクセス(CRITICAL):

  • 商品注文に対する 'post_type' => 'shop_order' を指定した get_posts()
  • new WP_Query( array( 'post_type' => 'shop_order' ) )
  • 注文データに対する get_post_meta( $order_id, ... )
  • 注文データに対する update_post_meta( $order_id, ... )
  • 注文に対する wp_posts への $wpdb->prepare() による直接アクセス

CRUD パターン(GOOD):

// GOOD: HPOS-compatible order access
$order = wc_get_order( $order_id );
$order->update_meta_data( 'custom_field', $value );
$order->save();

// GOOD: Query orders
$orders = wc_get_orders( array(
    'status' => 'completed',
    'limit' => 10,
    'date_created' => '>=' . strtotime( '-30 days' )
) );

// BAD: Direct post access (breaks HPOS)
$orders = get_posts( array(
    'post_type' => 'shop_order',
    'post_status' => 'wc-completed'
) );
update_post_meta( $order_id, 'custom_field', $value );
WooCommerce CRUD パターン(WOO-02、WOO-07)

WC_Data 基底クラス:

  • すべての WooCommerce オブジェクトは WC_Data を拡張します
  • データストアが永続化を処理します(HPOS テーブルと投稿テーブル)
  • 変更は ->save() が呼び出されるまでバッファーされます

注文の CRUD:

// GOOD: Complete order manipulation
$order = wc_get_order( $order_id );
$order->set_status( 'processing', 'Payment received' );
$order->update_meta_data( 'gift_message', $message );
$order->add_order_note( 'Custom note' );
$order->save(); // Single save after all changes

// BAD: Manual post status change
wp_update_post( array(
    'ID' => $order_id,
    'post_status' => 'wc-processing'
) );

商品の CRUD:

// GOOD: WC_Product_Query for product lists
$query = new WC_Product_Query( array(
    'status' => 'publish',
    'limit' => 10,
    'category' => array( 'clothing' ),
    'orderby' => 'date',
    'order' => 'DESC'
) );
$products = $query->get_products();

// WARNING: WP_Query for products (future-breaking)
$products = new WP_Query( array(
    'post_type' => 'product',
    'posts_per_page' => 10
) );

カスタムデータストアの登録:

// GOOD: Register custom data store
add_filter( 'woocommerce_data_stores', 'register_custom_data_store' );
function register_custom_data_store( $data_stores ) {
    $data_stores['custom-order-type'] = 'Custom_Order_Data_Store';
    return $data_stores;
}
決済ゲートウェイの開発(WOO-03、WOO-19)

WC_Payment_Gateway クラスの構造:

// GOOD: Complete payment gateway implementation
class WC_Gateway_Custom extends WC_Payment_Gateway {

    public function __construct() {
        $this->id = 'custom_gateway';
        $this->has_fields = true;
        $this->method_title = __( 'Custom Gateway', 'text-domain' );
        $this->method_description = __( 'Description', 'text-domain' );

        $this->init_form_fields();
        $this->init_settings();

        add_action( 'woocommerce_update_options_payment_gateways_' . $this->id,
            array( $this, 'process_admin_options' ) );
    }

    public function process_payment( $order_id ) {
        $order = wc_get_order( $order_id );

        // CRITICAL: Always check HTTPS in production
        if ( ! is_ssl() && 'yes' !== $this->get_option( 'testmode' ) ) {
            wc_add_notice( __( 'SSL required', 'text-domain' ), 'error' );
            return array( 'result' => 'failure' );
        }

        // GOOD: Use payment_complete() not manual status change
        $order->payment_complete( $transaction_id );

        return array(
            'result' => 'success',
            'redirect' => $this->get_return_url( $order )
        );
    }
}

セキュリティ上の重大なアンチパターン:

// CRITICAL: Never store raw card data
// BAD:
update_post_meta( $order_id, 'card_number', $_POST['card_number'] );
$wpdb->insert( 'payment_tokens', array( 'card' => $_POST['card_number'] ) );

// CRITICAL: Never log card data
// BAD:
error_log( 'Card: ' . $_POST['card_number'] );
wc_get_logger()->debug( 'CVV: ' . $_POST['cvv'] );

// GOOD: Use tokenization
$token = new WC_Payment_Token_CC();
$token->set_token( $gateway_token );
$token->set_gateway_id( $this->id );
$token->set_last4( substr( $card_number, -4 ) );
$token->set_card_type( $card_type );
$token->save();

返金処理:

// GOOD: Implement refund support
public function process_refund( $order_id, $amount = null, $reason = '' ) {
    $order = wc_get_order( $order_id );

    // Process refund via API
    $result = $this->api_refund( $order, $amount );

    if ( $result->success ) {
        $order->add_order_note(
            sprintf( __( 'Refunded %s', 'text-domain' ), $amount )
        );
        return true;
    }

    return false;
}

相互参照:

  • 包括的なセキュリティパターンについては、wp-security-review を参照してください
  • ここでは WC 決済固有のアンチパターンのみを扱います
配送方法

WC_Shipping_Method クラスの構造:

// GOOD: Complete shipping method implementation
class WC_Shipping_Custom extends WC_Shipping_Method {

    public function __construct( $instance_id = 0 ) {
        $this->id = 'custom_shipping';
        $this->instance_id = absint( $instance_id );
        $this->method_title = __( 'Custom Shipping', 'text-domain' );
        $this->method_description = __( 'Description', 'text-domain' );
        $this->supports = array( 'shipping-zones', 'instance-settings' );

        $this->init();
    }

    public function calculate_shipping( $package = array() ) {
        $rate = array(
            'id' => $this->id . $this->instance_id,
            'label' => $this->title,
            'cost' => 10.00,
            'calc_tax' => 'per_order'
        );

        $this->add_rate( $rate );
    }
}
カスタム商品タイプ(WOO-02)

商品タイプの登録:

// GOOD: Register custom product type
add_filter( 'product_type_selector', 'add_custom_product_type' );
function add_custom_product_type( $types ) {
    $types['custom-product'] = __( 'Custom Product', 'text-domain' );
    return $types;
}

// GOOD: Product class extending WC_Product
class WC_Product_Custom extends WC_Product {

    public function __construct( $product = 0 ) {
        $this->product_type = 'custom-product';
        parent::__construct( $product );
    }

    public function get_type() {
        return 'custom-product';
    }
}

// GOOD: Register product class
add_filter( 'woocommerce_product_class', 'load_custom_product_class', 10, 2 );
function load_custom_product_class( $classname, $product_type ) {
    if ( 'custom-product' === $product_type ) {
        $classname = 'WC_Product_Custom';
    }
    return $classname;
}
WooCommerce フックカタログ(WOO-05、WOO-06)

ライフサイクルフック:

// GOOD: Order lifecycle hooks
add_action( 'woocommerce_checkout_process', 'validate_custom_checkout_field' );
add_action( 'woocommerce_checkout_create_order', 'save_custom_order_data', 10, 2 );
add_action( 'woocommerce_thankyou', 'custom_thankyou_action' );
add_action( 'woocommerce_order_status_changed', 'handle_status_change', 10, 4 );

商品データフック:

// GOOD: Product admin hooks
add_action( 'woocommerce_product_options_general_product_data', 'add_custom_field' );
add_action( 'woocommerce_process_product_meta', 'save_custom_field' );

チェックアウトフィールドのフック:

// GOOD: Add checkout field
add_filter( 'woocommerce_checkout_fields', 'add_gift_message_field' );
function add_gift_message_field( $fields ) {
    $fields['order']['gift_message'] = array(
        'type' => 'textarea',
        'label' => __( 'Gift message', 'text-domain' ),
        'required' => false
    );
    return $fields;
}

add_action( 'woocommerce_checkout_update_order_meta', 'save_gift_message' );
function save_gift_message( $order_id ) {
    if ( ! empty( $_POST['gift_message'] ) ) {
        $order = wc_get_order( $order_id );
        $order->update_meta_data( 'gift_message', sanitize_textarea_field( $_POST['gift_message'] ) );
        $order->save();
    }
}
カート操作(WOO-08)

カート項目のデータ:

// GOOD: Add custom cart item data
add_filter( 'woocommerce_add_cart_item_data', 'add_custom_cart_data', 10, 2 );
function add_custom_cart_data( $cart_item_data, $product_id ) {
    if ( isset( $_POST['custom_field'] ) ) {
        $cart_item_data['custom_field'] = sanitize_text_field( $_POST['custom_field'] );
    }
    return $cart_item_data;
}

カート手数料:

// GOOD: Add custom fee
add_action( 'woocommerce_cart_calculate_fees', 'add_custom_fee' );
function add_custom_fee() {
    if ( WC()->cart->get_subtotal() > 100 ) {
        WC()->cart->add_fee( __( 'Handling fee', 'text-domain' ), 5 );
    }
}

カートの検証:

// GOOD: Validate cart contents
add_action( 'woocommerce_check_cart_items', 'validate_cart_items' );
function validate_cart_items() {
    if ( WC()->cart->get_cart_contents_count() < 3 ) {
        wc_add_notice( __( 'Minimum 3 items required', 'text-domain' ), 'error' );
    }
}
注文ステータスの遷移(WOO-07)

カスタム注文ステータス:

// GOOD: Register custom order status
add_action( 'init', 'register_awaiting_shipment_status' );
function register_awaiting_shipment_status() {
    register_post_status( 'wc-awaiting-shipment', array(
        'label' => __( 'Awaiting Shipment', 'text-domain' ),
        'public' => true,
        'show_in_admin_status_list' => true,
        'label_count' => _n_noop(
            'Awaiting shipment <span class="count">(%s)</span>',
            'Awaiting shipment <span class="count">(%s)</span>',
            'text-domain'
        )
    ) );
}

add_filter( 'wc_order_statuses', 'add_awaiting_shipment_to_order_statuses' );
function add_awaiting_shipment_to_order_statuses( $order_statuses ) {
    $order_statuses['wc-awaiting-shipment'] = __( 'Awaiting Shipment', 'text-domain' );
    return $order_statuses;
}

// GOOD: Set order status
$order = wc_get_order( $order_id );
$order->set_status( 'awaiting-shipment', 'Order ready for shipment' );
カートフラグメントのパフォーマンス(WOO-15)

条件付きの登録解除:

// GOOD: Conditional cart fragments loading
add_filter( 'woocommerce_get_script_data', 'conditional_cart_fragments', 10, 2 );
function conditional_cart_fragments( $data, $handle ) {
    if ( 'wc-cart-fragments' === $handle ) {
        // Only load on WC pages
        if ( ! is_woocommerce() && ! is_cart() && ! is_checkout() ) {
            return null;
        }
    }
    return $data;
}

// CRITICAL: Site-wide cart fragments loading
// BAD: No conditional dequeue - loads on every page

Mini-Cart Block の代替案:

// INFO: Recommend Mini-Cart Block migration
// Mini-Cart Block has built-in performance optimizations
// No cart fragments needed
Action Scheduler のパターン

バックグラウンド処理:

// GOOD: Action Scheduler for bulk operations
function schedule_order_export() {
    as_enqueue_async_action(
        'process_order_export',
        array( 'batch_id' => 123 ),
        'wc-exports'
    );
}

add_action( 'process_order_export', 'do_order_export', 10, 1 );
function do_order_export( $batch_id ) {
    $orders = wc_get_orders( array(
        'limit' => 100,
        'offset' => $batch_id * 100
    ) );

    foreach ( $orders as $order ) {
        // Export logic
    }

    // Schedule next batch if needed
    if ( count( $orders ) === 100 ) {
        as_enqueue_async_action(
            'process_order_export',
            array( 'batch_id' => $batch_id + 1 ),
            'wc-exports'
        );
    }
}

// WARNING: wp_cron for heavy WC tasks
// BAD:
wp_schedule_event( time(), 'hourly', 'process_order_export' );
Webhook のセキュリティ(WOO-20)

署名の検証:

// GOOD: Verify webhook signature
function verify_wc_webhook( $payload, $signature, $secret ) {
    $expected = base64_encode( hash_hmac( 'sha256', $payload, $secret, true ) );

    // CRITICAL: Use hash_equals to prevent timing attacks
    return hash_equals( $expected, $signature );
}

// Webhook handler
$payload = file_get_contents( 'php://input' );
$signature = $_SERVER['HTTP_X_WC_WEBHOOK_SIGNATURE'] ?? '';
$delivery_id = $_SERVER['HTTP_X_WC_WEBHOOK_DELIVERY_ID'] ?? '';

// WARNING: Missing signature verification
if ( ! verify_wc_webhook( $payload, $signature, $secret ) ) {
    http_response_code( 401 );
    exit;
}

// GOOD: Check for duplicate delivery
if ( get_transient( 'wc_webhook_' . $delivery_id ) ) {
    http_response_code( 200 );
    exit;
}
set_transient( 'wc_webhook_' . $delivery_id, true, DAY_IN_SECONDS );

// GOOD: Process async via Action Scheduler
as_enqueue_async_action( 'process_wc_webhook', array( 'payload' => $payload ) );
テンプレートオーバーライドのアンチパターン(WOO-10、WOO-11、WOO-12)

フックの維持:

// In child-theme/woocommerce/content-product.php

// GOOD: Preserve all action hooks from original template
do_action( 'woocommerce_before_shop_loop_item' );
do_action( 'woocommerce_before_shop_loop_item_title' );
// Custom content here
do_action( 'woocommerce_shop_loop_item_title' );
do_action( 'woocommerce_after_shop_loop_item_title' );
do_action( 'woocommerce_after_shop_loop_item' );

// CRITICAL: Deleted hooks in template override
// BAD: No do_action() calls - breaks plugin integration

バージョンの追跡:

// GOOD: Template with version comment
/**
 * Product loop template
 *
 * @version 8.9.0
 */

// WARNING: Outdated version
// Template version 3.6.0 when WC is 10.5 - may miss updates

フック優先の方針:

// BETTER: Use hooks instead of template override
add_action( 'woocommerce_shop_loop_item_title', 'add_custom_content', 15 );
function add_custom_content() {
    // Custom content via hook - no template override needed
}

// INFO: Template override where hook exists
// Suggest using hook instead of copying entire template

相互参照:

  • 一般的なテンプレートパターンについては、wp-theme-development を参照してください
表面的なチェック項目

WooCommerce Blocks のチェックアウト統合(WOO-14):

// GOOD: Add checkout field via Additional Checkout Fields API (WC 8.6+)
add_action( 'woocommerce_init', 'register_custom_checkout_field' );
function register_custom_checkout_field() {
    woocommerce_register_additional_checkout_field( array(
        'id' => 'namespace/gift-message',
        'label' => __( 'Gift message', 'text-domain' ),
        'location' => 'order',
        'type' => 'text'
    ) );
}

WooCommerce REST API の拡張(WOO-09):

// INFO: Custom REST endpoint registration
add_action( 'rest_api_init', 'register_custom_endpoint' );
function register_custom_endpoint() {
    register_rest_route( 'wc/v3', '/custom-endpoint', array(
        'methods' => 'GET',
        'callback' => 'custom_endpoint_callback',
        'permission_callback' => function() {
            return current_user_can( 'manage_woocommerce' );
        }
    ) );
}

クーポンの検証(WOO-21):

// GOOD: Custom coupon validation
add_filter( 'woocommerce_coupon_is_valid', 'validate_custom_coupon', 10, 3 );
function validate_custom_coupon( $valid, $coupon, $discount ) {
    if ( WC()->cart->get_cart_contents_count() < 3 ) {
        throw new Exception(
            __( 'Coupon requires at least 3 items', 'text-domain' ),
            109
        );
    }
    return $valid;
}

セッション処理(WOO-18):

// WARNING: Custom session filter exceeding 30-day cap (WC 10.1+)
// BAD:
add_filter( 'wc_session_expiration', function() {
    return 60 * DAY_IN_SECONDS; // Exceeds 30-day cap
} );

// GOOD: Respect 30-day cap
add_filter( 'wc_session_expiration', function() {
    return 30 * DAY_IN_SECONDS; // Maximum allowed
} );

迅速な検出のための検索パターン(WOO-22)

WooCommerce をすばやくスキャンするには、以下の rg コマンドとシェルチェックを使用してください。重要度別に整理しています。

CRITICAL パターン
# HPOS declaration candidates
# If this returns nothing in a WooCommerce extension, the plugin likely lacks HPOS declaration.
rg -n "declare_compatibility\s*\(\s*['\"]custom_order_tables['\"]" . -g '*.php'

# get_posts/WP_Query with shop_order
rg -n "post_type.*shop_order|shop_order.*post_type" . -g '*.php'

# Direct $wpdb queries against wp_posts for orders
rg -n "\$wpdb.*wp_posts.*shop_order" . -g '*.php'

# Raw card data storage/logging
rg -n "card_number|card_cvv|cvv.*meta|card.*error_log" . -g '*.php'

# Template overrides without do_action() calls
find . -path "*/woocommerce/*.php" -exec rg -L "do_action|apply_filters" {} \;

# Webhook signature handling candidates (manually confirm verification logic)
rg -n "X-WC-Webhook-Signature|hash_hmac|verify" . -g '*.php'
WARNING パターン
# WP_Query with post_type=product (compare these result sets manually)
rg -n "WP_Query|get_posts" . -g '*.php'
rg -n "post_type.*product|product.*post_type" . -g '*.php'

# Site-wide cart-fragments loading without conditional dequeue (manual context check)
rg -n "wc-cart-fragments|woocommerce_get_script_data|is_woocommerce|is_cart" . -g '*.php'

# wp_cron for bulk WC operations (manual context check)
rg -n "wp_schedule_event|wp_cron|wc_|order|product" . -g '*.php'

# Hardcoded API credentials
rg -n "api_key.*=.*['\"][A-Za-z0-9]{20,}" . -g '*.php'

# get_post_meta/update_post_meta for order fields
rg -n "get_post_meta.*order_id|update_post_meta.*order_id" . -g '*.php'

# Session filters exceeding 30-day cap (manual follow-up on returned values)
rg -n "wc_session_expiration|wc_session_expiring" . -g '*.php'
INFO パターン
# Template overrides where hooks exist
find . -path "*/woocommerce/*.php" -type f

# Missing object caching for repeated product loads
rg -n "wc_get_product" . -g '*.php'

# Action Scheduler candidates
rg -n "foreach.*wc_get_orders|foreach.*wc_get_products" . -g '*.php'

# WC Blocks integration opportunities
rg -n "woocommerce_register_additional_checkout_field|Store API" . -g '*.php'

注: WC 固有のパターンには、一般的な WP とは異なるコンテキストが必要です。注文以外の投稿タイプに対する get_posts() は有効です。標準の投稿/固定ページに対する WP_Query も有効です。WC 固有の投稿タイプと組み合わせている場合にのみ指摘してください。

WooCommerce コンテキストの検出

ファイル構成とパターンに基づく、コンテキストを考慮したレビューの注記です。

拡張機能/プラグイン

検出方法: WC 依存関係チェックと HPOS 宣言を含むメインのプラグインファイル レビューの重点: HPOS、CRUD、フックの包括的な監査 最も一般的なコンテキスト

テーマ統合

検出方法: テーマ内にテンプレートのオーバーライドを含む woocommerce/ ディレクトリがある レビューの重点: テンプレートオーバーライドの品質、フックの保持 相互参照: テーマのパターンについては wp-theme-development

決済ゲートウェイ

検出方法: WC_Payment_Gateway を継承するクラス レビューの重点: セキュリティレビューの強化(カード情報を生のまま保存しない、HTTPS チェック、Webhook の検証) 相互参照: 一般的なセキュリティについては wp-security-review

配送方法

検出方法: WC_Shipping_Method を継承するクラス レビューの重点: calculate_shipping() のレビュー、配送ゾーンのサポート、料金計算

カスタム商品タイプ

検出方法: WC_Product を継承するクラス レビューの重点: データストアのレビュー、商品タイプの登録、クラス階層

WC Blocks の統合

検出方法: Store API の使用、チェックアウトブロックの拡張ポイント レビューの重点: 表面的なレビュー、Additional Checkout Fields API 相互参照: ブロックの詳細なパターンについては wp-block-development

クイックリファレンス:WooCommerce 開発パターン(WOO-23)

関心事ごとに整理した、一般的な WooCommerce のパターンです。すべての例は WordPress PHP コーディング規約(括弧内にスペースを入れる、[] ではなく array() を使う、Yoda 条件)に従っています。

HPOS 互換性の宣言

❌ 悪い例:HPOS 宣言がない

<?php
// Extension silently breaks on HPOS-enabled stores

✅ 良い例:before_woocommerce_init フックで互換性を宣言

<?php
add_action( 'before_woocommerce_init', function() {
    if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
        \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility(
            'custom_order_tables',
            __FILE__,
            true
        );
    }
} );
注文データへのアクセス

❌ 悪い例:投稿への直接アクセス(HPOS が機能しなくなる)

<?php
$orders = get_posts( array(
    'post_type' => 'shop_order',
    'post_status' => 'wc-completed'
) );
update_post_meta( $order_id, 'custom_field', $value );

✅ 良い例:HPOS 互換の CRUD

<?php
$orders = wc_get_orders( array(
    'status' => 'completed',
    'limit' => 10
) );

$order = wc_get_order( $order_id );
$order->update_meta_data( 'custom_field', $value );
$order->save();
注文メタデータの操作

❌ 悪い例:メタデータ関数を直接使用

<?php
update_post_meta( $order_id, 'delivery_date', '2026-02-15' );
$date = get_post_meta( $order_id, 'delivery_date', true );

✅ 良い例:WC_Order のメソッド

<?php
$order = wc_get_order( $order_id );
$order->update_meta_data( 'delivery_date', '2026-02-15' );
$order->save();

$date = $order->get_meta( 'delivery_date', true );
商品データへのアクセス

❌ 悪い例:商品の取得に WP_Query を使用(将来の互換性を損なう)

<?php
$products = new WP_Query( array(
    'post_type' => 'product',
    'posts_per_page' => 10
) );

✅ 良い例:WC_Product_Query

<?php
$query = new WC_Product_Query( array(
    'status' => 'publish',
    'limit' => 10,
    'category' => array( 'clothing' ),
    'orderby' => 'date',
    'order' => 'DESC'
) );
$products = $query->get_products();
決済ゲートウェイ

❌ 悪い例:カード情報を生のまま保存し、HTTPS チェックがない

<?php
public function process_payment( $order_id ) {
    // CRITICAL: Never store raw card data
    update_post_meta( $order_id, 'card_number', $_POST['card_number'] );

    // Process payment
    $order = wc_get_order( $order_id );
    $order->update_status( 'processing' ); // Manual status change

    return array(
        'result' => 'success',
        'redirect' => $this->get_return_url( $order )
    );
}

✅ 良い例:トークン化、HTTPS チェック、payment_complete()

<?php
public function process_payment( $order_id ) {
    $order = wc_get_order( $order_id );

    // Check HTTPS in production
    if ( ! is_ssl() && 'yes' !== $this->get_option( 'testmode' ) ) {
        wc_add_notice( __( 'SSL required', 'text-domain' ), 'error' );
        return array( 'result' => 'failure' );
    }

    // Process via API (use tokenization, never store raw cards)
    $result = $this->api_charge( $order );

    if ( $result->success ) {
        // Use payment_complete() not manual status change
        $order->payment_complete( $result->transaction_id );

        return array(
            'result' => 'success',
            'redirect' => $this->get_return_url( $order )
        );
    }

    return array( 'result' => 'failure' );
}
配送方法

✅ 良い例:完全な配送方法

<?php
class WC_Shipping_Custom extends WC_Shipping_Method {

    public function __construct( $instance_id = 0 ) {
        $this->id = 'custom_shipping';
        $this->instance_id = absint( $instance_id );
        $this->method_title = __( 'Custom Shipping', 'text-domain' );
        $this->supports = array( 'shipping-zones', 'instance-settings' );

        $this->init();
    }

    public function calculate_shipping( $package = array() ) {
        $rate = array(
            'id' => $this->id . $this->instance_id,
            'label' => $this->title,
            'cost' => 10.00,
            'calc_tax' => 'per_order'
        );

        $this->add_rate( $rate );
    }
}
カスタム商品タイプ

✅ 良い例:カスタム商品タイプを登録して実装する

<?php
// Register product type
add_filter( 'product_type_selector', 'add_custom_product_type' );
function add_custom_product_type( $types ) {
    $types['custom-product'] = __( 'Custom Product', 'text-domain' );
    return $types;
}

// Product class
class WC_Product_Custom extends WC_Product {

    public function __construct( $product = 0 ) {
        $this->product_type = 'custom-product';
        parent::__construct( $product );
    }

    public function get_type() {
        return 'custom-product';
    }
}

// Register product class
add_filter( 'woocommerce_product_class', 'load_custom_product_class', 10, 2 );
function load_custom_product_class( $classname, $product_type ) {
    if ( 'custom-product' === $product_type ) {
        $classname = 'WC_Product_Custom';
    }
    return $classname;
}
カート操作

✅ 良い例:カート項目データを追加する

<?php
add_filter( 'woocommerce_add_cart_item_data', 'add_custom_cart_data', 10, 2 );
function add_custom_cart_data( $cart_item_data, $product_id ) {
    if ( isset( $_POST['custom_field'] ) ) {
        $cart_item_data['custom_field'] = sanitize_text_field( $_POST['custom_field'] );
    }
    return $cart_item_data;
}

✅ 良い例:カート手数料を追加する

<?php
add_action( 'woocommerce_cart_calculate_fees', 'add_custom_fee' );
function add_custom_fee() {
    if ( WC()->cart->get_subtotal() > 100 ) {
        WC()->cart->add_fee( __( 'Handling fee', 'text-domain' ), 5 );
    }
}
注文ステータスの遷移

❌ 悪い例:投稿ステータスを手動で変更する

<?php
wp_update_post( array(
    'ID' => $order_id,
    'post_status' => 'wc-processing'
) );

✅ 良い例:WC_Order::set_status() を使用する

<?php
$order = wc_get_order( $order_id );
$order->set_status( 'processing', 'Payment received' );
// Automatically saved

✅ 良い例:決済フローには payment_complete() を使用する

<?php
$order = wc_get_order( $order_id );
$order->payment_complete( $transaction_id );
フックを保持したテンプレートオーバーライド

❌ 悪い例:テンプレートのオーバーライドでフックを削除する

<?php
// In child-theme/woocommerce/content-product.php
// CRITICAL: No do_action() calls - breaks plugin integration
?>
<li class="product">
    <h2><?php the_title(); ?></h2>
    <div class="price"><?php echo $product->get_price_html(); ?></div>
</li>

✅ 良い例:すべてのアクションフックを保持する

<?php
// In child-theme/woocommerce/content-product.php
do_action( 'woocommerce_before_shop_loop_item' );
do_action( 'woocommerce_before_shop_loop_item_title' );
?>
<h2><?php the_title(); ?></h2>
<?php
do_action( 'woocommerce_shop_loop_item_title' );
do_action( 'woocommerce_after_shop_loop_item_title' );
do_action( 'woocommerce_after_shop_loop_item' );

✅ さらに良い例:テンプレートをオーバーライドせず、フックを使用する

<?php
add_action( 'woocommerce_shop_loop_item_title', 'add_custom_content', 15 );
function add_custom_content() {
    // Custom content via hook - no template override needed
}
カートフラグメントの最適化

❌ 悪い例:サイト全体でカートフラグメントを読み込む

<?php
// No conditional dequeue - loads on every page
// CRITICAL performance issue

✅ 良い例:条件付きで読み込みを解除する

<?php
add_filter( 'woocommerce_get_script_data', 'conditional_cart_fragments', 10, 2 );
function conditional_cart_fragments( $data, $handle ) {
    if ( 'wc-cart-fragments' === $handle ) {
        if ( ! is_woocommerce() && ! is_cart() && ! is_checkout() ) {
            return null;
        }
    }
    return $data;
}

✅ さらに良い例:Mini-Cart Block に移行する

// Mini-Cart Block has built-in performance optimizations
// No cart fragments needed
Action Scheduler

❌ 悪い例:WC の一括操作に wp_cron を使用する

<?php
wp_schedule_event( time(), 'hourly', 'process_order_export' );

add_action( 'process_order_export', 'do_export' );
function do_export() {
    // Unreliable, traffic-dependent, no retry
}

✅ 良い例:一括操作に Action Scheduler を使用する

<?php
function schedule_order_export() {
    as_enqueue_async_action(
        'process_order_export',
        array( 'batch_id' => 0 ),
        'wc-exports'
    );
}

add_action( 'process_order_export', 'do_order_export', 10, 1 );
function do_order_export( $batch_id ) {
    $orders = wc_get_orders( array(
        'limit' => 100,
        'offset' => $batch_id * 100
    ) );

    foreach ( $orders as $order ) {
        // Export logic
    }

    // Schedule next batch if needed
    if ( 100 === count( $orders ) ) {
        as_enqueue_async_action(
            'process_order_export',
            array( 'batch_id' => $batch_id + 1 ),
            'wc-exports'
        );
    }
}
Webhook のセキュリティ

❌ 悪い例:署名検証がない

<?php
// Webhook handler
$payload = file_get_contents( 'php://input' );
$data = json_decode( $payload );

// WARNING: No signature verification - allows forged webhooks
process_webhook( $data );

✅ 良い例:hash_equals() を使用した HMAC-SHA256 検証

<?php
function verify_wc_webhook( $payload, $signature, $secret ) {
    $expected = base64_encode( hash_hmac( 'sha256', $payload, $secret, true ) );
    return hash_equals( $expected, $signature );
}

// Webhook handler
$payload = file_get_contents( 'php://input' );
$signature = $_SERVER['HTTP_X_WC_WEBHOOK_SIGNATURE'] ?? '';
$delivery_id = $_SERVER['HTTP_X_WC_WEBHOOK_DELIVERY_ID'] ?? '';

if ( ! verify_wc_webhook( $payload, $signature, $secret ) ) {
    http_response_code( 401 );
    exit;
}

// Check for duplicate delivery
if ( get_transient( 'wc_webhook_' . $delivery_id ) ) {
    http_response_code( 200 );
    exit;
}
set_transient( 'wc_webhook_' . $delivery_id, true, DAY_IN_SECONDS );

// Process async
as_enqueue_async_action( 'process_wc_webhook', array( 'payload' => $payload ) );
WooCommerce Blocks のチェックアウト

✅ 良い例:Additional Checkout Fields API(WC 8.6+)

<?php
add_action( 'woocommerce_init', 'register_custom_checkout_field' );
function register_custom_checkout_field() {
    woocommerce_register_additional_checkout_field( array(
        'id' => 'namespace/gift-message',
        'label' => __( 'Gift message', 'text-domain' ),
        'location' => 'order',
        'type' => 'text',
        'attributes' => array(
            'maxLength' => 200
        )
    ) );
}

// Access field value
$order = wc_get_order( $order_id );
$gift_message = $order->get_meta( 'namespace/gift-message' );
REST API 拡張

✅ 良い例:認証付きのカスタム REST エンドポイント

<?php
add_action( 'rest_api_init', 'register_custom_endpoint' );
function register_custom_endpoint() {
    register_rest_route( 'wc/v3', '/custom-endpoint', array(
        'methods' => 'GET',
        'callback' => 'custom_endpoint_callback',
        'permission_callback' => function() {
            return current_user_can( 'manage_woocommerce' );
        }
    ) );
}
クーポンの検証

✅ 良い例:カスタムクーポン検証

<?php
add_filter( 'woocommerce_coupon_is_valid', 'validate_custom_coupon', 10, 3 );
function validate_custom_coupon( $valid, $coupon, $discount ) {
    if ( WC()->cart->get_cart_contents_count() < 3 ) {
        throw new Exception(
            __( 'Coupon requires at least 3 items', 'text-domain' ),
            109
        );
    }
    return $valid;
}
セッションの処理

❌ 悪い例:30 日の上限を超える

<?php
add_filter( 'wc_session_expiration', function() {
    return 60 * DAY_IN_SECONDS; // Exceeds cap
} );

✅ 良い例:30 日の上限を守る(WC 10.1+)

<?php
add_filter( 'wc_session_expiration', function() {
    return 30 * DAY_IN_SECONDS; // Maximum allowed
} );
メールのカスタマイズ

✅ 良い例:WC_Email クラスを拡張する

<?php
class WC_Email_Custom extends WC_Email {

    public function __construct() {
        $this->id = 'custom_email';
        $this->title = __( 'Custom Email', 'text-domain' );
        $this->description = __( 'Email description', 'text-domain' );

        $this->template_html = 'emails/custom-email.php';
        $this->template_plain = 'emails/plain/custom-email.php';

        parent::__construct();
    }

    public function trigger( $order_id ) {
        $this->object = wc_get_order( $order_id );

        if ( ! $this->is_enabled() || ! $this->get_recipient() ) {
            return;
        }

        $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
    }
}

重大度の定義(WOO-24)

重大度定義例
CRITICAL最新の WC ストアで拡張機能が動作しなくなる、またはセキュリティ上の脆弱性があるHPOS 互換性宣言がない、注文への直接的な投稿アクセス(shop_order を指定した get_posts/WP_Query)、注文/商品に対する直接的なデータベースクエリ、カード情報の生データの保存/ログ記録(DB または error_log への card_number の記録)、アクションフックを削除したテンプレートのオーバーライド、Webhook 署名の検証がない、HTTP 経由でのカード情報の送信
WARNING拡張機能は動作するものの、品質/互換性/パフォーマンスに問題がある商品に対する WP_Query(将来のバージョンで動作しなくなる可能性)、サイト全体でのカートフラグメントの読み込み、古いテンプレートのオーバーライド(バージョンの不一致)、コードへの API 認証情報のハードコード、WooCommerce の一括処理に wp_cron() を使用、セッション期間が30日を超える、注文フィールドに get_post_meta/update_post_meta を使用、決済処理で HTTPS を確認していない
INFOベストプラクティスの改善、または最適化の機会フックがあるテンプレートのオーバーライド(代わりにフックを提案)、軽量なタスクで wp_cron の代わりに Action Scheduler を使用、商品を繰り返し読み込む際のオブジェクトキャッシュ、WC Blocks との統合機会、Additional Checkout Fields API の使用、商品オブジェクトのキャッシュ(WC 10.5 以降、実験的)

出力形式(WOO-24)

検出事項は FILE ごとにまとめ(PHP ファイルは実際のファイルパス順)、行番号と重大度ラベルを付けて報告してください。各検出事項には BAD/GOOD のコード例を使用してください。

# WooCommerce Review: my-wc-extension

## FILE: includes/class-order-handler.php

### Line 45: CRITICAL - Direct post access for orders
get_posts() with post_type='shop_order' breaks on HPOS-enabled stores. Use wc_get_orders() instead.

❌ **BAD:**
```php
$orders = get_posts( array(
    'post_type' => 'shop_order',
    'post_status' => 'wc-completed'
) );

✅ GOOD:

$orders = wc_get_orders( array(
    'status' => 'completed',
    'limit' => 10
) );
67行目:CRITICAL - 注文データに直接メタ関数を使用

注文データに update_post_meta() を使用すると、HPOS との互換性が損なわれます。WC_Order のメソッドを使用してください。

❌ BAD:

update_post_meta( $order_id, 'custom_field', $value );

✅ GOOD:

$order = wc_get_order( $order_id );
$order->update_meta_data( 'custom_field', $value );
$order->save();

FILE: my-wc-extension.php

1行目:CRITICAL - HPOS 宣言がない

拡張機能は HPOS との互換性ステータスを宣言する必要があります。before_woocommerce_init フックを追加してください。

❌ BAD:

<?php
// No HPOS declaration - extension silently incompatible

✅ GOOD:

<?php
add_action( 'before_woocommerce_init', function() {
    if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
        \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility(
            'custom_order_tables',
            __FILE__,
            true
        );
    }
} );

FILE: includes/class-gateway.php

89行目:CRITICAL - カード情報の生データをログに記録

カード情報のログ記録は PCI 違反であり、セキュリティ侵害につながります。決済情報をログに記録しないでください。

❌ BAD:

error_log( 'Processing card: ' . $_POST['card_number'] );

✅ GOOD:

// Never log card data
// Use tokenization, log transaction IDs only
$this->log( 'Processing transaction: ' . $transaction_id );
102行目:WARNING - HTTPS の確認がない

本番モードで決済を処理する前に is_ssl() を確認してください。

❌ BAD:

public function process_payment( $order_id ) {
    // Process payment without SSL check
}

✅ GOOD:

public function process_payment( $order_id ) {
    if ( ! is_ssl() && 'yes' !== $this->get_option( 'testmode' ) ) {
        wc_add_notice( __( 'SSL required', 'text-domain' ), 'error' );
        return array( 'result' => 'failure' );
    }
    // Process payment
}

FILE: includes/class-cart-fragments.php

23行目:WARNING - サイト全体でカートフラグメントを読み込み

すべてのページでカートフラグメントを読み込むと、パフォーマンスの問題が発生します。条件付きで読み込みを解除してください。

❌ BAD:

// No conditional dequeue - loads on all pages

✅ GOOD:

add_filter( 'woocommerce_get_script_data', 'conditional_cart_fragments', 10, 2 );
function conditional_cart_fragments( $data, $handle ) {
    if ( 'wc-cart-fragments' === $handle ) {
        if ( ! is_woocommerce() && ! is_cart() && ! is_checkout() ) {
            return null;
        }
    }
    return $data;
}

SUMMARY

問題の合計:7

  • CRITICAL:4(必ず修正してください。HPOS ストアで拡張機能が動作しない、またはセキュリティ違反が発生します)
  • WARNING:2(品質/パフォーマンスの問題)
  • INFO:1(ベストプラクティスの改善)

HPOS 互換性リスク: HIGH - 最新の WooCommerce ストアで拡張機能が動作しなくなります
セキュリティに関する注意: 決済セキュリティの問題が検出されました。包括的なセキュリティ分析を行うには、/wp-sec-review を実行してください。
パフォーマンスに関する注意: カートフラグメントのパフォーマンス問題が検出されました。包括的なパフォーマンス分析を行うには、/wp-perf-review を実行してください。


## Common Mistakes (WOO-25)

Patterns that look like issues but are NOT problems:

| Pattern | Why It's NOT a Problem | Context |
|---------|------------------------|---------|
| **get_posts() for custom post types (not orders)** | Valid when post type is not 'shop_order'. Only shop_order queries break HPOS. | Extensions can use get_posts() for their own post types |
| **WP_Query for standard posts/pages** | Valid for non-product queries. Only product queries flagged as WARNING. | Blog posts, custom post types are fine with WP_Query |
| **get_post_meta() for custom post types (not orders)** | Valid when not accessing order data. Only order meta breaks HPOS. | Custom post type meta operations work normally |
| **Template overrides in child themes** | Legitimate when hooks are preserved. Only flag if do_action() calls deleted. | Intentional customization with proper hook preservation |
| **wc-cart-fragments.js on cart/checkout/product pages** | Expected on WC pages. Only flag site-wide loading. | Conditional loading to WC pages is correct |
| **wp_cron() for lightweight non-WC tasks** | Acceptable for simple scheduled tasks. Only flag for heavy WC operations. | Daily cleanup, simple notifications are fine |
| **WC_Session usage within 30-day window** | Normal behavior. Only flag custom filters exceeding cap. | Standard session handling works correctly |
| **error_log() in non-payment code** | Acceptable debugging. Only flag in payment processing context. | General logging is fine, just not card data |
| **Direct $wpdb for custom tables (NOT WC core tables)** | Valid for extension's own tables. Only flag queries against wp_posts/wp_postmeta for WC data. | Custom table queries don't affect HPOS |
| **process_payment() accessing $_POST for custom fields** | Valid for non-card data (shipping notes, gift messages). Only flag raw card data access. | Custom checkout field handling is expected |
| **Template overrides without @version comment** | Missing metadata, not necessarily outdated. Only flag significant version mismatches. | Version tracking helps but absence isn't critical |
| **apiVersion 2 in WC Blocks integration** | Block-related, not WC-specific. Defer to wp-block-development. | Block patterns handled by block skill |

## Version Compatibility Reference

Quick reference for WooCommerce version requirements:

| Feature | WooCommerce Version | Notes |
|---------|---------------------|-------|
| WC_Data CRUD API | 3.0+ | Base class for all CRUD objects |
| wc_get_order(), wc_get_product() | 3.0+ | Preferred data access methods |
| Product attribute lookup table | 6.3+ | Indexed product attributes for filtering |
| Cart fragments no longer global by default | 7.8+ | Requires opt-in for site-wide loading |
| HPOS (Custom Order Tables) default | 8.2+ | New stores use HPOS by default |
| HPOS compatibility declaration required | 8.2+ | declare_compatibility() mandatory |
| Additional Checkout Fields API | 8.6+ | Block checkout field registration |
| Session 30-day cap enforced | 10.1+ | Maximum session duration limit |
| wc_enqueue_js() deprecated | 10.4+ | Use wp_add_inline_script() instead |
| Product object caching (experimental) | 10.5+ | Opt-in performance feature |
| Variation price caching improvements | 10.5+ | Automatic performance optimization |
| Batch analytics imports (100/12hrs) | 10.5+ | Background processing improvements |

## Deep-Dive References

For advanced WooCommerce development patterns, load these companion reference documents:

| Task | Reference to Load |
|------|-------------------|
| HPOS compatibility migration, payment gateway development (WC_Payment_Gateway lifecycle, process_payment flow, refund handling, security patterns), shipping methods (WC_Shipping_Method, calculate_shipping, zones), custom product types (register_product_type, data stores), order handling (WC_Order CRUD, status transitions), cart operations (cart item data, fees, validation), REST API extensions, Action Scheduler patterns, webhook security | `references/wc-extension-guide.md` |
| Template hierarchy (archive-product, content-product, single-product, cart, checkout, myaccount), override procedures (child theme woocommerce/ directory, version tracking), hooks-first philosophy (when to use hooks vs overrides, preserving action hooks), shop/product/cart/checkout theming, WooCommerce Blocks compatibility notes, email templates | `references/wc-template-guide.md` |
| Cart fragments analysis (problem, solutions, Mini-Cart Block), WC_Product_Query optimization, HPOS performance benefits, session handling (30-day cap, cleanup), Action Scheduler for background processing, transient and object caching strategies, variation price caching, product attribute lookup table, database optimization | `references/wc-performance-guide.md` |

**Note:** Reference docs provide deep-dive content. This SKILL.md is self-sufficient for standard WooCommerce reviews.

**Security crossover:** When encountering security-relevant patterns (payment data handling, REST API authentication, AJAX nonce verification, capability checks), this skill provides brief reminders but defers to wp-security-review for comprehensive security analysis. For detailed security patterns, use `/wp-sec-review` command.

**Plugin crossover:** When encountering plugin-level patterns (WC dependency checking, activation/deactivation, hooks architecture, REST API registration), this skill provides brief mentions but defers to wp-plugin-development for plugin architecture depth. For detailed plugin review, use `/wp-plugin-review` command.

**Block crossover:** When encountering WooCommerce Blocks integration (Store API, checkout block extension points, Additional Checkout Fields API), this skill provides brief mentions but defers to wp-block-development for block development depth. For detailed block patterns, use `/wp-block-review` command.

**Theme crossover:** When encountering template overrides in themes (woocommerce/ directory, template hierarchy, version tracking), this skill provides brief mentions but defers to wp-theme-development for theme development depth. For detailed theme review, use `/wp-theme-review` command.

**Performance crossover:** When encountering cart fragments, query optimization, caching strategies, this skill provides brief mentions but defers to wp-performance-review for comprehensive performance analysis. For detailed performance patterns, use `/wp-perf-review` command.

コメント