投稿日:2023年6月28日

前回記事 のソースコードをこのページに記述します。

必要なファイルです。


my_sql.php
データベースへ接続し、ajax経由でpost_user_info.jsから受け取った情報を元にプラン変更を行います。

mydb.php
データベースへ接続します。

post_user_info.js
プルダウンやボタンクリックから変更するプランを取得し、ajax経由でmy_sql.phpに渡します。

functions.php
データベースから現在のユーザー情報を取得し、内容を非表示フォームに掲載。
固定ページ別にプラン変更のアクションを行います。

ソースコードは以下です。

<?php
require_once("mydb.php"); //mydb.phpを読み込み
$pdo = db_connect(); //mydb.phpに記述されているデータベース接続関数。

$user_id = $_POST['id']; //ajaxで取得したユーザーID
$plan = $_POST['plan']; //ajaxで取得したユーザーのプラン

// ▼▼▼ プラン変更 /////////////////////////////////////////////////////
// ユーザーIDからmeta_keyのプランを経由してumeta_idを取得。%はワイルドカード
$stmt = $pdo->prepare("SELECT umeta_id FROM wp_usermeta WHERE meta_key LIKE '_wpmem_products_%_plan' AND user_id = ?"); //SQLインジェクション対策。プリペアドステートメント「?」プレースホルダ
$stmt->bindValue(1, $user_id, PDO::PARAM_INT);
$stmt->execute();
$umeta_id = $stmt->fetch();

// プラン変更。AプランならBプランへ。BプランならCプランへ。
$stmt_ = $pdo->prepare("UPDATE wp_usermeta SET meta_key = '_wpmem_products_" . $plan . "_plan' WHERE wp_usermeta.umeta_id = ?"); //SQLインジェクション対策。プリペアドステートメント「?」プレースホルダ
$stmt_->bindValue(1, $umeta_id[0], PDO::PARAM_INT);
$stmt_->execute();
// ▲▲▲ プラン変更 /////////////////////////////////////////////////////

$pdo = null; //データベースを閉じる

▲10行目。下図のumeta_idを取得するためのSQLになります。
ユーザーidが2の、meta_keyの値_wpmem_products_b_planから取得します。(下図)
_wpmem_products_%_plan%はワイルドカードになります。
16〜18行目でプラン変更を行います。

<?php
function db_connect()
{
  require_once("../../../../wp-config.php");
  $db_user = DB_USER; //ユーザー名
  $db_pass = DB_PASSWORD; //パスワード
  $db_host = DB_HOST; //ホスト名
  $db_name = DB_NAME; //データベース名
  $db_type = "mysql"; //データベースの種類
  $dns = "$db_type:host=$db_host;dbname=$db_name;charset=utf8";

  try {
    $pdo = new PDO($dns, $db_user, $db_pass);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    echo 'データベースへ接続しました。';
  } catch (PDOException $Exception) {
    die('接続エラー:' . $Exception->getMessage());
  }
  return $pdo;
}

▲データベース接続設定です。
各設定を4つ上の階層のwp-config.phpから取得します。

jQuery(function ($) {
  $('#submit,#submit_c,#submit_e').click(function () {
    let userId = $('#userId').text();//ユーザーID
    // ▼▼▼ プルダウンメニューからプランを取得
    let selectPlanType = $('#planUpdate').val();
    if (selectPlanType=='Bプラン') {
      planType = 'b';
    } else if(selectPlanType=='Cプラン'){
      planType = 'c';
    } else if(selectPlanType=='Dプラン'){
      planType = 'd';
    } else if(selectPlanType=='Eプラン'){
      planType = 'e';
    }

    // ▼▼▼ 「Cプランへ変更」ボタンクリックからプラン取得
    if($('#formWrapCbtn').css('display') == 'block'){
      $('#postType').text('c');
      planType = 'c';
    }

    // ▼▼▼「Eプランへ変更」ボタンクリックからプラン取得
    if($('#formWrapEbtn').css('display') == 'block'){
      $('#postType').text('e');
      planType = 'e';
    }

    // ▼▼▼ ajaxで「my_sql.php」へユーザーIDと変更プランを送る
    $.ajax({
        type: 'POST',
        url: "../wp-content/themes/lightning-child/connect_db/my_sql.php",// ディレクトリwp-adminから見ているので、←こう書かないとディレクトリが取得できない。
      data: {
          'id':userId, //userId
          'plan': planType, //plan
        },
        success: function () {
        }
    });

    // ▼▼▼ ajaxで「functions.php」へユーザーIDと変更プランを送る
    $.ajax({
        type: 'POST',
        url: "../wp-content/themes/lightning-child/functions.php",// ディレクトリwp-adminから見ているので、←こう書かないとディレクトリが取得できない。
      data: {
          'id':userId, //userId
        },
        success: function () {
        }
    });
    // ▼▼▼ 「メールは送信されました。」の表示を読ませた後、変更内容に切り替えるため、5秒後にリロードする
    setTimeout(function () {
      location.reload();
      return;
    }, 5000);
  });
});

▲プルダウンメニュー、ボタンクリックで取得したプラン変更の内容を、ajaxを使ってmy_sql.phpとfunctions.phpに渡します。

///////////////////////////////////////////////////////////
// ▼▼▼ ユーザー情報を取得、プランを変更するアクションフック
function change_plan(){
    wp_enqueue_script('post_user_info', get_stylesheet_directory_uri() .'/connect_db/post_user_info.js');

    // ▼▼▼ 各プランの固定ページだったら
    if(is_page(19)||is_page(21)||is_page(23)||is_page(52)||is_page(54)){
        $user_data = wp_get_current_user(); //ログインユーザーから取得
        echo '<div id="userInfoWrap" hidden>'; //非表示用ラッパー
        echo '<p id="userId">'.$user_data->ID.'</p>'; //ユーザーID取得
        echo '<p id="userName">'.$user_data->user_login.'</p>'; //ユーザー名取得
        echo '<p id="userEmail">'.$user_data->user_email.'</p>'; //email取得

        // ▼▼▼ データベースに接続
        $db_user = "xxxxxxx"; //ユーザー名
        $db_pass = "xxxxxxxxxxxxx"; //パスワード
        $db_host = "mysqxxx.xxxx.xxxxx.ne.jp"; //ホスト名
        $db_name = "xxxxxx_xxxxx"; //データベース名
        $db_type = "mysql"; //データベースの種類
        $dns = "$db_type:host=$db_host;dbname=$db_name;charset=utf8";

        try {
            $pdo = new PDO($dns, $db_user, $db_pass);
            $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

            // データベースから現在のプラン名を取得
            $stmt = $pdo->prepare("SELECT meta_key FROM wp_usermeta WHERE meta_key LIKE '_wpmem_products_%_plan' AND user_id = ?");  //SQLインジェクション対策。プリペアドステートメント「?」プレースホルダ。%は任意の1文字
            $stmt->bindValue(1, $user_data->ID, PDO::PARAM_STR);
            $stmt->execute();
            $current_plan = $stmt->fetch();
            $current_user_plan = htmlspecialchars($current_plan[0], ENT_QUOTES, 'UTF-8');
        } catch (PDOException $Exception) {
            die('接続エラー:' . $Exception->getMessage());
        }
        echo '<p id="userCurrentPlan">'.$current_user_plan.'</p>'; //現在のプラン名を取得
?>

    <script>
        // ユーザー情報取得用のフォーム項目(非表示)出力
        jQuery(function($){
            let userName = $('#userName').text();
            let userEmail = $('#userEmail').text();
            $('#yourName').val(userName); //プルダウンメニュー用、ユーザー名を取得
            $('#yourEmail').val(userEmail); //プルダウンメニュー用、emailを取得
            $('#yourName02').val(userName); //ボタン用、ユーザー名を取得
            $('#yourEmail02').val(userEmail); //ボタン用、emailを取得
        })
    </script>

<!-- ////////////////////////////////////// -->
<!-- ▼▼▼ 固定ページAプランページ -->
<?php
    if(is_page(19)){ //固定ページAプラン
        echo '<p id="postType">a</p>';
        echo '</div>'; //<div id="userInfoWrap" hidden>の閉じタグ
?>
    <script>
        jQuery(function($){
            // 現在のプランを取得表示
            if($('#userCurrentPlan').text()=='_wpmem_products_a_plan'){ //Aプランユーザーだったら
                $('#postType').text('a');
                $('.yourPlan').text('A');
                if($('#formWrap').css('display') == 'block'){ //プルダウンメニューが表示されていたら
                    $('#formWrapCbtn').css('display','none'); //「Cプランへ変更」ボタンは非表示
                }
            }else if($('#userCurrentPlan').text()=='_wpmem_products_b_plan'){ //Bプランユーザーだったら
                $('#postType').text('b');
                $('.yourPlan').text('B');
                $('#formWrap').css('display','none'); //プルダウンメニュー非表示
            }else if($('#userCurrentPlan').text()=='_wpmem_products_c_plan'){ //Cプランユーザーだったら
                $('#postType').text('c');
                $('.yourPlan').text('C');
                $('#formWrap, #formWrapCbtn').css('display','none'); //プルダウンメニュー、「Cプランへ変更」ボタン非表示
            }else if($('#userCurrentPlan').text()=='_wpmem_products_d_plan'){ //Dプランユーザーだったら
                $('#postType').text('d');
                $('.yourPlan').text('D');
                $('#formWrap, #formWrapCbtn').css('display','none'); //プルダウンメニュー、「Cプランへ変更」ボタン非表示
            }else if($('#userCurrentPlan').text()=='_wpmem_products_e_plan'){ //Eプランユーザーだったら
                $('#postType').text('e');
                $('.yourPlan').text('E');
                $('#formWrap, #formWrapCbtn').css('display','none'); //プルダウンメニュー、「Cプランへ変更」ボタン非表示
            }
        });
    </script>
<?php } ?>

<!-- ////////////////////////////////////// -->
<!-- ▼▼▼ 固定ページBプランページ -->
<?php
    if(is_page(21)){ //固定ページBプラン
        echo '<p id="postType">b</p>';
        echo '</div>'; //<div id="userInfoWrap" hidden>の閉じタグ
?>
    <script>
        jQuery(function($){
            if($('#userCurrentPlan').text()=="_wpmem_products_c_plan"||$('#userCurrentPlan').text()=="_wpmem_products_d_plan"||$('#userCurrentPlan').text()=="_wpmem_products_e_plan"){
                $('#formWrap').css('display','none');
            }
            // 現在のプランを取得表示
            if($('#userCurrentPlan').text()=='_wpmem_products_b_plan'){
                $('#postType').text('b');
                $('.yourPlan').text('B');
            }else if($('#userCurrentPlan').text()=='_wpmem_products_c_plan'){
                $('#postType').text('c');
                $('.yourPlan').text('C');
                $('#formWrapCbtn').css('display','none'); //「Cプランへ変更」ボタン非表示
            }else if($('#userCurrentPlan').text()=='_wpmem_products_d_plan'){
                $('#postType').text('d');
                $('.yourPlan').text('D');
                $('#formWrapCbtn').css('display','none'); //「Cプランへ変更」ボタン非表示
            }else if($('#userCurrentPlan').text()=='_wpmem_products_e_plan'){
                $('#postType').text('e');
                $('.yourPlan').text('E');
                $('#formWrapCbtn').css('display','none'); //「Cプランへ変更」ボタン非表示
            }
        });
    </script>
<?php } ?>

<!-- ////////////////////////////////////// -->
<!-- ▼▼▼ 固定ページCプランページ -->
<?php
    if(is_page(23)){ //固定ページCプラン
        echo '<p id="postType">d</p>';
        echo '</div>'; //<div id="userInfoWrap" hidden>の閉じタグ
?>
    <script>
        jQuery(function($){
            if($('#userCurrentPlan').text()=="_wpmem_products_d_plan"||$('#userCurrentPlan').text()=="_wpmem_products_e_plan"){
                $('#formWrap').css('display','none');
            }
            // 現在のプランを取得表示
            if($('#userCurrentPlan').text()=='_wpmem_products_c_plan'){
                $('#postType').text('c');
                $('.yourPlan').text('C');
                if($('#formWrap').css('display') == 'block'){ //プルダウンメニューが表示されていたら
                    $('#formWrapEbtn').css('display','none'); //「Eプランへ変更」ボタン非表示
                }
            }else if($('#userCurrentPlan').text()=='_wpmem_products_d_plan'){
                $('#postType').text('d');
                $('.yourPlan').text('D');
            }else if($('#userCurrentPlan').text()=='_wpmem_products_e_plan'){
                $('#postType').text('e');
                $('.yourPlan').text('E');
                $('#formWrapEbtn').css('display','none'); //「Eプランへ変更」ボタン非表示
            }
        });
    </script>
<?php } ?>

<!-- ////////////////////////////////////// -->
<!-- ▼▼▼ 固定ページDプランページ -->
<?php
    if(is_page(52)){ //固定ページDプラン
        echo '<p id="postType">e</p>';
        echo '</div>'; //<div id="userInfoWrap" hidden>の閉じタグ
?>
    <script>
        jQuery(function($){
            // 現在のプランを取得表示
            if($('#userCurrentPlan').text()=='_wpmem_products_d_plan'){
                $('#postType').text('d');
                $('.yourPlan').text('D');
            }else if($('#userCurrentPlan').text()=='_wpmem_products_e_plan'){
                $('#postType').text('e');
                $('.yourPlan').text('E');
                $('#formWrapEbtn').css('display','none'); //「Eプランへ変更」ボタン非表示
            }
        });
    </script>
<?php } ?>

<!-- ////////////////////////////////////// -->
<!-- ▼▼▼ 固定ページEプランページ -->
<?php
    if(is_page(54)){ //固定ページEプラン
        echo '<p id="postType">e</p>';
        echo '</div>'; //<div id="userInfoWrap" hidden>の閉じタグ
?>
    <script>
        jQuery(function($){
            if($('#userCurrentPlan').text()=="_wpmem_products_e_plan"){
                $('#formWrap').css('display','none');
            }

            // 現在のプランを取得表示
            if($('#userCurrentPlan').text()=='_wpmem_products_e_plan'){
                $('.yourPlan').text('E');
            }
        });
    </script>
<?php } ?>
<?php
    }
}
add_action('lightning_site_body_before', 'change_plan'); //アクションフック

▲6〜11行目。各プランの固定ページで現在のユーザー情報を非表示フォームに掲載します。
9行目のdivでフォームを包含し、hiddenで非表示にしています。
ユーザー名とemailはプラン変更時の通知メール配信のため必要です。
13〜34はデータベース接続。IDやパスワードをwp-config.phpから取得する記述をしたdb_connect()関数をincludeするとエラーになる(上手くいかなかった)ので改めて設定を記述しています。
40〜50行目。ユーザーと管理者へのメール送信のための記述です。
59行目〜が各プランごとの必要はプルダウンメニュー、ボタンの設定です。
現在のプランごとに、必要なプルダウンメニューとボタンを、条件によって表示、非表示を切り替えます。
198行目。lightning_site_body_beforeはテーマ Lightningアクションフックになります。

一連の動きをYouTubeにアップしました。
どうぞ、ご覧ください。

まとめ

今回はプランを上げるだけの機能になります。
要件を詰めてゆけば、プランを下げたり、退会する機能も必要になってくると思います。
もう少し検証を続けたいと思います。

最後になりますが、本記事のソースコードはご自由にお使いいただいて構いませんが、何かトラブルが生じても責任は負いませんのでご了承ください。

最後まで読んでいただきありがとうございました。

関連サイト
Pocket