決済用プラグインの制作~(2)フォームページでフォームデータをAjaxで送信させるJavaScriptを読み込ませる

2020年1月18日

ファイル構造

  • wp-content(dir)
    • plugins(dir)
      • my-original-plugin(dir)
        • my-original-plugin.php・・・定数追加
        • script(dir)
          • form-ajax.js・・・フォームデータのAjax処理周りを担当
        • class(dir)
          • class.wpmop.php・・・form-ajax.jsを読み込ませたり、form-ajax.jsにわたす変数を作成・出力したりするファイルclass.wpmop-scripts.phpをinclude。またAjaxで送られてきたデータを処理するajax_payment()関数の設定をする。
          • class.wpmop-script.php・・・jsやcssなどのファイルや、適切なパラメータを必要とするページで読み込ませる処理を担当

form-ajax.js

このファイルは、送信ボタンを押した後WordPressのシステムにAjaxを通じでフォーム内容を送信し、処理結果を受け取る JavaScript です。

WordPressでAjaxを行う場合にいくつか決まり事があります。

1.フォーム要素input[name=’action’]の値として、Ajaxのアクション名を入れて送信すること

これは、Ajax処理ができるようにしたい | WordPressのプラグインを作ろうで紹介したアクションフック名wp_ajax_, wp_ajax_nopriv_のあとに続く名前と一致させる必要があります。

2.Ajaxの送信先は、http(s)://hogehoge.com/wp-admin/admin-ajax.phpであること

3.WordPressでフォームの遣り取りをするときには、nonceを使用すること(使わなくても可能であるが、セキュリティを向上させるために必要)参考:WordPress Nonce – WordPress Codex 日本語版

1~3をすべて満たすようにform-ajax.jsに直接設定してもよいのですが、可能ならば上記内容はPHP側で準備してJavaScriptの変数として出力し、form-ajax.jsではそのJavaScriptの変数を使うようにするとメンテナンス上都合が良いものとなります。

PHP側でJavaScriptの変数を出力するやり方は後ほど行うとして、form-ajax.jsではその変数を使用することを前提として以下のように書いておきます。

jQuery(function($){
    $('#ProductForm').submit(function(event){
        //フォームのデフォルトの送信処理を止める
        event.preventDefault();

    /*
       $('#ProductForm')の中に、以下の項目を追加します。
       1. ExtraInfo.NONCEHTML:PHP側で作成しJavaScriptの変数として出力したnonce用のHTML
    2. ExtraInfo.ACTIONNAME:PHP側で作成しJavaScriptの変数として出力したAjaxで利用するアクション名
    */
       var $ProductForm = $('#ProductForm').append(ExtraInfo.NONCEHTML + '<input type="hidden" name="action" value="' + ExtraInfo.ACTIONNAME + '" >');

        /*
        ajax送信で決まりきった書き方です。
    ・送信先(url)として、PHP側で作成しJavaScriptの変数として出力したExtraInfo.AJAXURLを指定しておきます。
    ・本来ならば値のバリデーションを行うべきだけれども、ここはとりあえずそのままserialize()関数を使用して送信。
        */
        $.ajax({
            url: ExtraInfo.AJAXURL, 
            type: 'POST', 
            data: $ProductForm.serialize() 
        }).done( function( data ){ 
            //ajax送信後、出力されたものをChromeのconsoleに出力させる. 
            console.log(data); 
        }).fail(function( XMLHttpRequest, textStatus, error ){
        }); 
    }); 
});

my-original-plugin.phpファイル

ここでは、nonceを作る関数wp_nonce_field()関数で必要な引数の値を定数で設定しておきます。

<?php 
/* 
Plugin Name: My Original Plugin Plugin 
URI: Description: This Plugin id developed for My Original Plugin 
Version: 0.0.1 
Author: webmaster@GRITT.JP 
Text Domain: mop 
*/ 

//以下、プラグイン内でよく使うと思われる定数の定義 
define( 'WPMOP_VER', '0.0.1' ); 
define( 'WPMOP_URL', plugins_url( '', __FILE__ ) ); 
define( 'WPMOP_DIR', plugin_dir_path( __FILE__ ) ); 
define( 'WPMOP_CLASS_PATH', rtrim( plugin_dir_path( __FILE__ ), '/' ) . '/class/' ); 

//↓↓↓↓↓新規追加ここから
define( 'WPMOP_NONCE_NAME', 'wpmop_nonce_name' );
define( 'WPMOP_NONCE_ACTION', 'wpmop_nonce_action' . WPMOP_VER );
//↑↑↑↑↑新規追加ここまで

//以下、使用するファイルの読み込み。 
include_once( WPMOP_CLASS_PATH . 'class.wpmop.php' ); 

//以下、クラスのインスタンス化 
global $wpmop; 
$wpmop = new WPMOP();

class.wpmop.phpファイル

このファイルでは、form-ajax.jsを読み込ませたり、form-ajax.jsにわたす変数を作成・出力したりするファイルclass.wpmop-scripts.phpをincludeしておきます。またAjaxで送られてきたデータを処理するajax_payment()関数も設定しておきます。

このajax_payment()関数では取り急ぎ、送られてきたデータをvar_dump()でそのまま出力します。

<?php

//↓↓↓↓↓新規追加ここから

//class.wpmop-scripts.phpファイルを読み込ませる
include_once( WPMOP_CLASS_PATH . 'class.wpmop-scripts.php' );

//↑↑↑↑↑新規追加ここまで

class WPMOP {

//↓↓↓↓↓新規追加ここから

    //フロントページで読み込ませるスクリプトを登録させる
    add_action( 'wp_enqueue_scripts', 'WPMOPSCRIPTS::front_page_scripts' );
    //ajax用の関数を設定 フォームでname="action"の値をpayment_ajaxにする
    add_action( 'wp_ajax_nopriv_payment_ajax', array( &$this, 'ajax_payment' ) );
    add_action( 'wp_ajax_payment_ajax', array( &$this, 'ajax_payment' ) );
//↑↑↑↑↑新規追加ここまで

    public function __construct()
    {
        add_action( 'admin_menu', array( &$this, 'my_admin_page_settings' ) );
    }
    
    public function my_admin_page_settings()
    {
        //管理画面にメニューを追加
        add_menu_page(
            'My Original Pluginメインページ',
            'My Original Plugin',
            'manage_options',
            'wpmop',
            array( &$this, 'wpmop_mainpage' ),
            '',
            99
        );

        //追加した「My Original Plugin」メニューにサブメニューを追加
        add_submenu_page(
            'wpmop',
            'サブメニュー1ページ',
            'サブメニュー1',
            'manage_options',
            'wpmop-submenu1',
            array( &$this, 'wpmop_subpage01' )
        );
    }

    //追加した管理メニューページのコンテンツ
    public function wpmop_mainpage() {
        ?>
<div class="PluginContainer ">
    <h2 class="Plugin__head">My Original Pluginメインページ</h2>    
</div>
<?php
    }    

    //追加した管理メニューサブページのコンテンツ
    public function wpmop_subpage01() {
        ?>
<div class="PluginContainer ">
    <h2 class="Plugin__head">My Original Pluginサブページ1</h2>    
</div>
<?php
    }  

//↓↓↓↓↓新規追加ここから
    
    public function ajax_payment()
    {
    //とりあえず、ajax_payment関数が呼び出されたら'ok'を出力
        var_dump( $_POST );
        die();
    }
//↑↑↑↑↑新規追加ここまで

}

class.wpmop-scripts.phpファイル

このファイルでは、class.wpmop.php で、アクションフック wp_enqueue_scriptsに追加したJavaScriptを読み込ませる関数の設定を行います。

具体的には、

・決済用フォームがあるページにアクセスが来たら、form-ajax.jsファイルをwp_enqueue_script()関数を使用し出力する

・上記ファイルの出力に合わせて、jsファイル内で利用する変数を設定・出力する

の2つを行っています。

<?php
class WPMOPSCRIPTS {
    
    public static function front_page_scripts()
    {
        //フォームのページ(payment-plugin-sample-productpage)にアクセスされた時に以下の作業を行う
        if( is_page( 'payment-plugin-sample-productpage' ) ){
            
            //form-ajaxというハンドル名で、jsを読み込ませるhtmlを出力
            wp_enqueue_script( 'form-ajax', WPMOP_URL . '/script/form-ajax.js', array( 'jquery' ) );

            /*
            ハンドル名form-ajaxのJavaScriptで使える変数(オブジェクト・配列)を追加する
            追加するデータは、
            NONCEHTML:セキュリテイ向上のためWordPressではフォームを送信する際、nonceフィールドを利用することが推奨されている。
            nonceフィールドを出力するためのwp_nonce_field()関数を使って、PHPファイル上でそのHTMLを準備し、JSで使用できるようにしておく
            AJAXURL:ajaxデータの送信先は決まっているので、admin_url()関数を使って、PHPファイル上で準備しておく
            ACTIONNAME:フォームのinput[name="action"]の値に、class.wpmop.phpで追記した、add_action( 'wp_ajax_payment_ajax', array( &$this, 'ajax_payment' ) );
       の「payment_ajax」を入れる必要がある。そのため、PHPファイル上で準備しておく
            */
            wp_localize_script( 
                'form-ajax', //紐付けるスクリプトのハンドル名
                'ExtraInfo', //JavaScriptオブジェクト名
                array(
                    'NONCEHTML' => wp_nonce_field( WPMOP_NONCE_ACTION, WPMOP_NONCE_NAME , true, false ),
                    'AJAXURL' => admin_url('admin-ajax.php'),
                    'ACTIONNAME' => 'payment_ajax'
                    )
            );
        }
    }
}

テスト送信

実際に送信すると、consoleのログ部分でこのように出力されます。

次からは、この送信されたデータをPHP側でバリデーションし(最終的にはJavaScriptで送信前にもバリデーションしますが今回はそこは割愛します)、SBペイメントサービスにデータを送ってみたいと思います。