[WordPress]Ajaxを使ってカスタムフィールドを更新する

  • 更新日:
  • 公開日:

Ajaxを使用してカスタムフィールドを更新(操作)するスニペットのメモです。

PHPだけではログインをしなければデータの操作ができませんが、Ajaxを使うことでログイン無しでも操作が可能です。

Ajaxを使ってカスタムフィールドを更新

用意するコードは以下になります。

  1. Ajax用URLをJavaScript変数として出力(PHP)
  2. カスタムフィールドを保存する処理(PHP)
  3. AjaxでPHP側にデータ送信、PHP関数実行(JavaScript、PHP)

1と2はfunctions.phpへ、3はテンプレートファイルへ記述することを前提としいます。

Ajax用URLをJavaScript変数として出力

/**
 * Ajaxで使用するWordPressのAjax用URLを変数として出力
 */
function get_wp_ajax_root() {
    ?>
    <script>
      let wp_ajax_root = '<?php echo admin_url( 'admin-ajax.php' ); ?>';
    </script>
    <?php
}
add_action( 'wp_head', 'get_wp_ajax_root' );

7行目でWordPressのAjax用URLを変数に代入しています。マルチサイトでも問題ないURLとなります。

カスタムフィールドを保存する処理

/**
 * Ajaxでカスタムフィールドを更新
 */
function update_custom_field_by_ajax() {
    // $_POSTで渡ってくる値を取得
    $post_id    = isset( $_POST['post_id'] )  ? $_POST['post_id'] : null;
    $meta_key   = isset( $_POST['meta_key'] )  ? $_POST['meta_key'] : null;
    $new_value  = isset( $_POST['value'] )  ? $_POST['value'] : null;

    // 現在のカスタムフィールド値を取得
    // 値を元に保存処理を変更したい場合に使用します。
    $current_value = get_post_meta( $post_id, $meta_key );

    // カスタムフィールドの更新に成功したら"success"、失敗したら"error"をコンソールに出力
    if ( update_post_meta( $post_id, $meta_key, $new_value ) ) {
        echo 'success';

    } else {
        echo 'error';
    }

    die();
}
/*
 * wp_ajax_アクション名:ログインしているユーザーのみ有効
 * wp_ajax_nopriv_アクション名:ログインしていないユーザーのみ有効
 */
add_action( 'wp_ajax_update_custom_field', 'update_custom_field_by_ajax' );
add_action( 'wp_ajax_nopriv_update_custom_field', 'update_custom_field_by_ajax' );

アクションフック名が肝となります。以下2つのアクションフックにカスタムフィールドの保存関数を登録しています。

  1. wp_ajax_アクション名
  2. wp_ajax_nopriv_アクション名

1はログインしているユーザーのみ有効となるフックで、2はログインしていないユーザーのみ有効となるフックになります。「ログインしている」「ログインしていない」どちらにも対応するには両方のアクションフックに関数を登録しましょう。

指定するアクション名は任意で、今回は「update_custom_field」と指定しています。このアクション名はJavaScriptでのAjaxでも使用します。

AjaxでPHP側にデータ送信、PHP関数実行

(function($){
    'use strict';

    /**
     * WordPressのAjax処理用クラス
     *
     * @param wp_ajax_root WordPressのAjax用URL
     */
    let WPAjaxUtil = function (wp_ajax_root) {
        this.wp_ajax_root = wp_ajax_root;
    };

    /**
     * Ajax処理でカスタムフィールドを更新
     *
     * @param postId    カスタムフィールドの投稿ID
     * @param metaKey   カスタムフィールドのキー名
     * @param value     カスタム不イールドの値
     */
    WPAjaxUtil.prototype.updatePostMeta = function (postId, metaKey, value) {
        $.ajax({
            type: 'POST',
            url: this.wp_ajax_root,
            data: {
                'action' : 'update_custom_field',
                'post_id': postId,
                'meta_key': metaKey,
                'value': value
            },
            success: function( response ){
                console.log( response );
            }
        });
    };
})(jQuery);

カスタムフィールドを更新するだけであればこのクラスとメソッド内容で問題ありませんが、各々変更する必要があるのは25行目です。 「action」というキーがあるので、こちらにアクションフックで指定したアクション名を記述します。先程の通りであれば「update_custom_field」ですね。

これでカスタムフィールドをAjaxで保存する機構が用意できました。 最後にJavaScriptでカスタムフィールドをAjax処理で保存するプログラムを作成します。例としてIPアドレスを取得して保存しています。(投稿IDを取得する必要があるのでテンプレートに記述する前提のコードです)

(function($){
    'use strict';

    /**
     * 特定の要素をクリックしたらIPアドレスをカスタムフィールドに保存
     */
    $('#button').on('click', function() {
        // IPアドレスを取得
        let ipAddress = '<?php echo filter_input( INPUT_SERVER, 'REMOTE_ADDR' ); ?>';

        let metaKey     = 'ip_address'; // キー名
        let value       = ipAddress; // キー値
        let postId      = <?php the_ID(); ?>; // 投稿ID

        // Ajax処理用クラスに登録してあるメソッドでカスタムフィールドを更新
        new WPAjaxUtil(wp_ajax_root).updatePostMeta(postId, metaKey, value);
    });
})(jQuery);

以上がAjaxでカスタムフィールドを更新する方法で、参考サイトのプログラムを踏襲しています。

JavaScriptを外部ファイル化した手法

これらJavaScriptプログラムを外部ファイルにし、PHPからJavaScriptへ値渡しする形が良い手法かと思います。JavaScriptを外部ファイル化した場合の参考コードを記載します。

JavaScriptを外部ファイル化し、wp_localize_script()で値を渡す

JavaScriptファイルを「update-custom-field-by-ajax.js」という名前(任意)で「theme-name/js」ディレクトリに配置し、以下をfunctions.phpに記載して読み込みます。

function my_enqueue_scripts() {
    global $post; // 投稿IDを取得するため投稿オブジェクトをグローバル化

    wp_enqueue_script( 'update-custom-field-by-ajax',
        get_theme_file_uri() . '/js/update-custom-field-by-ajax.js',
        array( 'jquery' ),
        '1.0',
        true
    );

    wp_localize_script(
        'update-custom-field-by-ajax',
        'wpData', // JavaScriptで参照する場合のオブジェクト名
        array(
            'ajaxUrl'   => admin_url( 'admin-ajax.php' ),
            'ipAddress' => filter_input( INPUT_SERVER, 'REMOTE_ADDR' ),
            'postId'      => $post->ID
        )
    );
}
add_action( 'wp_enqueue_scripts', 'my_enqueue_scripts' );

wp_localize_script()でPHPの値を渡しているので、一番最初に行った「Ajax用URLを変数に設定して出力」するPHPコードは不要となります。

これによって、JavaScriptの実行処理は以下のようになります。

/**
 * 特定の要素をクリックしたらIPアドレスをカスタムフィールドに保存
 */
$('#button').on('click', function() {
    // IPアドレスを取得
    let ipAddress = wpData.ipAddress;

    let metaKey     = 'ip_address';
    let value       = ipAddress;
    let postId      = wpData.postId;

    // Ajax処理用クラスに登録してあるメソッドでカスタムフィールドを更新
    new WPAjaxUtil(wpData.ajaxUrl).updatePostMeta(postId, metaKey, value);
});

「wpData」というオブジェクト名でPHPの値を渡しているので、以下のようにアクセスできます。

  • IPアドレス:wpData.ipAddress(6行目)
  • 投稿ID:wpData.postId(10行目)
  • Ajax用URL:wpData.ajaxUrl( 13行目)

残りのカスタムフィールドを保存するPHP関数やAjax用クラス、メソッドはそのままで使用します。

参考: WordPress AjaxでAdvanced Custom Fields(カスタムフィールド)を更新するAPIを公開(REST) | | Java from Japan Plugin API/Action Reference/wp ajax (action) « WordPress Codex Plugin API/Action Reference/wp ajax nopriv (action) « WordPress Codex

書いた人

Symbol Mark

Ryoichi(しつ)

除菌ティッシュを買い込んで使いきれずによく乾かす人。

療養目的で退職し、どうやって生きていくか模索中。最近は勉強目的でLaravelやVue.js弄ったり、趣味で音で遊んでます。

※2019年10月16日現在ブログリニューアル中です。崩れなどが発生していたらすみません。

うぇぶ: @s_ryone