WordPress プラグイン作成 〜アンケート挿入〜

WordPressのプラグインを作成中です。ようやくアンケート挿入が出来上がって来たところです。

アンケート挿入

今回作成しているプラグインの大まかな処理は以下の通りです。

  1. プラグインを有効にした時、アンケートに必要なデータを保存するDB(テーブル)を作成する
  2. ダッシュボードで投稿に挿入するアンケートを作成する
  3. 作成したアンケートを記事が表示する時にDBから作成したアンケート情報を取得する
  4. 取得したアンケート情報をJSONでしHTMLに出力する(scriptタグ)
  5. プラグインから読み込んだJSで画面がロードされた時にJSONからランダムに表示するアンケート情報を取得する
  6. 取得した情報からアンケート入力フォームを作成する

サンプル

作成したデータ(CSV)は以下のようなものです。

question_id, question, answer1, answer2, answer3, answer4, answer5, html_class, html_style, click_count
15, あなたの性別はどちらですか?, 男, 女, , , , respond, , 0
16, あなたの年齢は?, 10才以下, 10代, 20代, 30代, 40以上, site-navigation, , 0
17, あなたの職業は?, 学生, フリーター, 自営業, 社員(非IT関連), 社員(IT関連), main, , 0
18, あなたの趣味は?, 音楽系, ゲーム系(将棋など), アウトドア系, スポーツ系, 学問系(文学や歴史など), reply-title, , 0
19, あなたはブロガーですか?, はい, いいえ, , , , primary, , 0, 
20, あなたは日本人ですか?(Are You Japanese?), はい(Yes), いいえ(No), , , , comments, , 0

これでとりあえずは、アンケートが表示できました。

まとめ

プラグインを有効にした時の処理(index.php)
キモになるのは下の部分です。

add_action('admin_menu', 'addCustomQuestionary' );
add_action('wp_enqueue_scripts', 'insertQuestionary' );
do_action( 'addCustomQuestionary' );

WordPressで使用できるアクションフックに以下のメソッドを登録します。

  1. addCustomQuestionary(ダッシュボードのメニュー)
  2. insertQuestionary(これはアンケート挿入する時)

そしてaddCustomQuestionaryを実行するように設定します。do_action( 'addCustomQuestionary' );

これで、ダッシュボードで作成したアンケート情報を投稿記事に挿入します。
ちょっと長くなりましたが、ここら辺で失礼いたします。

でわでわ。。。

    // HTML挿入用のJSを読み込む
    echo '';


Java関連ページ

WordPressプラグイン作成 〜HTML挿入まで完了〜

WordPressプラグインの作成中です。このプラグインを有効にしたときに、作成したアンケート(HTML)を投稿画面の指定した部分に挿入するのが目標です。

大まかに作成したものを画面のmainクラス(HTMLクラス)の下に配置したのが下のキャプチャーです。

はっきり言って使い物になりません。。。

しかし、作成したアンケートを挿入することができたのでとりあえずは一区切りです。ここまでのソースはgitに登録してあります。

HTML挿入

HTMLを挿入するのに実装したものは以下のものになります。

プラグイン.php
/*
Plugin Name: CustomQuestionaryPlugin
Plugin URI: (プラグインの説明と更新を示すページの URI)(未決定)aaa
Description: アンケートを作成、ブログ記事の中に埋め込むことができ、集計結果をダッシュボードで確認ができる。
Version: 1.0
Author: ZenryokuService
Author URI: https://zenryokuservice.com/
License: GPL2
*/
// 表示する内容
function helloCustomQuestionary() {
}

// アンケートを記事に挿入するスクリプト
function insertQuestionary() {

}

// ダッシュボードに追加するための関数(プラグイン有効時)
function addCustomQuestionary() {
    // ダッシュボードにこの表示が出るように追加する
    add_menu_page( 'Test Plugin', 'CustomQuestionary', 'manage_options' , 'test-plugin' , 'helloCustomQuestionary' );
    // 投稿記事にアンケートを表示するスクリプトをリンクする
    add_action( 'wp_enqueue_scripts', 'insertQuestionary' );
}
// プラグインをダッシュボードに表示する
add_action('admin_menu', 'addCustomQuestionary' );
// プラグイン用のJSを読み込むようにする
add_action('wp_enqueue_scripts', 'insertQuestionary' );
do_action( 'addCustomQuestionary' );
ダッシュボードに表示.php

これは普通のPHPファイルで、サーバーサイド処理をPHPで、クライアント側に表示するものをHTMLで実装します。

<?php サーバーサイド ?>
<h1>Custom Questionary Plugin</h1>



InsertQuery.php

これは、ダッシュボード画面からDBに作成したアンケート情報を登録するためのphpです。
JS側から、非同期リクエストを送信しそれを受けてDB登録処理を行います。

DeleteQuery.php

上と同様に、削除処理を行います。

表示位置に関して


上のように表示している部分は、アンケートのボタンと質問です。
いかんせんダッシュボードではBootStrapを使用していたのですが、WordPressにあるstyle.cssが使用されているので、上のような表示になります。部分的にスタイルを適用できると良いのですが。。。

表示位置を変えるにはHTMLクラスの指定を変えます。

初めはid="main"のタグの後ろ。。。つまりは、記事の一番下にアンケートを追加しました。
上の表示はDBに登録している”hrml_class"(スペルミス)のデータ部に対応するidを持つタグの下に配置するようにしていますのでヘッダーメニューの下に来ました。

アンケートの表示がイマイチですが、とりあえずはアンケート登録〜表示(挿入)までの実装ができました。

でわでわ。。。



Java関連ページ

php BugFix foreach 〜foreachに入らない〜

PHPでのforeach文に処理が入らないケースに関してつまづいたので記載します。

関連記事はこちら

どんなコードで動かないか?

ズバリ下のコードです。

get_results('SELECT * FROM QUESTIONARY', ARRAY_A);
    echo count($result);
    // ここから下はデータがある時のみ表示
    foreach($result as $key => $data) {
        echo '';
        echo '' . $data->question . '';
        echo '' . $data->answer1 . '';
        echo '' . $data->answer2 . '';
        echo '' . $data->answer3 . '';
        echo '' . $data->answer4 . '';
        echo '' . $data->answer5 . '';
        echo '';
    }
?>

$resultの中には配列が入っていることを確認しているのですが、いかんせん。。。動かない。。。

Fix(解決)

foreach文の中の処理が昨日していなかったようです。。。
echo "Hello";と処理を記載したところ問題なく処理が動きました。。。

つまり、$data->プロパティ名の呼び出し方が悪い。
$data['プロパティ名']の形で実装するのが正しいということでした。

修正結果

具体的には以下のようなコードです。

get_results('SELECT * FROM QUESTIONARY', ARRAY_A);
    // ここから下はデータがある時のみ表示
    foreach($result as $key => $data) {
        echo '';
        echo '' . $data['question'] . '';
        echo '' . $data['answer1'] . '';
        echo '' . $data['answer2'] . '';
        echo '' . $data['answer3'] . '';
        echo '' . $data['answer4'] . '';
        echo '' . $data['answer5'] . '';
        echo '';
    }
?>

でわでわ。。。


関連ページ

  1. WordPress プラグイン作成〜DBを使用する〜
  2. PHP PDO 〜MySQLにアクセスする〜
  3. PHP Ajax 〜DBに登録したデータを受信する〜
  4. Google Maps API PHP連携 〜マップ情報をDBに登録する〜
  5. PHP Image File 〜iPhoneやAndroidでの画像送受信の問題〜
  6. AngularJS Routing 〜PHPをWeb APIにする〜
  7. WordPress PHPカスタム〜根本的に見た目を変える〜
  8. WordPress PHPカスタム〜根本的に見た目を変える2〜
  9. Eclipse PHPプラグイン 〜ElipseでWordPress環境を構築〜
  10. WordPress テスト実装 〜heade-test.phpを表示〜
  11. AngularJS + PHP 〜WordPressと連携する〜
  12. AngularJS + PHP 〜AngularJSの実装〜
  13. AngularJS + PHP 〜AngularJSの実装2〜
  14. WordPress 処理解析 ~index.phpを眺める~
  15. WordPress Plugin NewStatPress ~アクセス解析プラグインAPIを使う~
  16. WordPress 処理解析 ~ログイン処理を調べる~
  17. WordPressカスタム〜アンケートボタンを追加する(設計)〜
  18. WordPressカスタム〜プラグインの作成〜
  19. WordPressカスタム〜ダッシュボードのプラグイン画面作成〜
  20. WordPressカスタム〜ダッシュボードのプラグイン画面作成2〜
  21. WordPressカスタム〜ダッシュボードのプラグイン画面作成3〜
  22. WordPress プラグイン作成〜アンケート作成プラグインを作る〜


WordPress $wpdb 使い方〜エラーの出力を行う〜

WordPressプラグインの作成中です。
そして、DBに作成したデータを登録する処理を作成しようとしています。

$wpdb

このオブジェクトを使用してやると、自力でDBコネクションとかトランザクションの管理をしなくて良いです。
そーゆーフレームワークがWordPressです。つまり、WordPressでDBアクセスオブジェクトを用意しているという事です。

そんなわけで、使い方です。

$wpdbの使い方

参考サイト:WordPress Codex(日本語)

ここのページによると、global $wpdbと宣言してから使用しましょうとあります。

しかし、プラグインで使用するときはイベントで起動するfunctionにて宣言する必要があります。
詳細はこちらのページに記載しました。

実装サンプル

リクエストの送信はJSで非同期に送信します。

// 作成したフォームを出力する
function outputForm() {
    if (isCreated == false) {
        alert("Please create form ");
    }
    let dom = document.getElementById("result");
    if (dom == null || typeof dom == 'undefined') {
        alert("Error");
        return;
    }
    let question = document.getElementById("question").innerText;
    let inputs = dom.getElementsByTagName("button");
    let ansArray = [];
    let htmlClass = document.getElementById("insertPos").value;
    let htmlStyle = "";
    for (let i = 0; i < inputs.length; i++) {
        ansArray.push(inputs[i].innerText);
    }
    // 送信するデータ(リクエストパラメータ)
    let data = createSendData(question, ansArray, htmlClass, htmlStyle);
    // DBへデータの登録(汎用的に作成したメソッドなので後ろの引数は全てnullにしている)
    // 下のメソッドは次のように書いても良い(JSの場合) => createXHR("POST", stateChangeMethod);
    let xhr = createXHR(stateChangeMethod, null, null);
    // JSONで送信する
    xhr.open("POST", '');
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.send(JSON.stringify(data));

}

そして、送信するJSONを作成するのに下のメソッドで作成しました。

function createSendData(question, ansArray, htmlClass, htmlStyle) {
    let obj = {};
    obj.question = question;
    for (let i = 0; i < ansArray.length; i++) {
        obj["ans" + i] = ansArray[i];
    }
    obj.hrml_class = htmlClass;
    // 未使用
    obj.html_style = "";
    return obj;
}

大まかにこのような実装です。

サーバーサイド

phpで実装しているものです。

// JSONリクエストを受け取る
$json = file_get_contents('php://input');
$data = json_decode($json);
// (プラグインフォルダにあるので)WordPressはすでに読み込まれている
$vals = json_decode($json, true);

// JSONプロパティの値を取得する

$insertSQL = "insert into questionary('question', 'answer1', 'answer2', 'answer3', 'answer4', 'answer5', 'hrml_class', 'html_style') values (";

$array = get_object_vars($data);
$keys = array('question', 'ans0', 'ans1', 'ans2', 'ans3', 'ans4', 'hrml_class', 'html_style');

for($count = 0; $count < 8; $count++) {
    if (array_key_exists($keys[$count], $array)) {
        $dd = $array[$keys[$count]];
    } else {
        $dd = "";
    }
    if ($dd != "") {
        $insertSQL .= "'" . $dd . "',";
    } else {
        $insertSQL .= "'',";
    }
}
// $insertSQL .= "'" . $vals['htmlClass'] . "','" . $vals['htmlStyle'] . "'";
$insertSQL = substr($insertSQL, 0, -1);
$insertSQL .= ");";

global $wpdb;

$wpdb->query($insertSQL);


wpdbではinsertとかselectなどSQLを組まなくても実行できるようにできていますが、自分はSQLでやったほうが楽だったのでSQLを使用しました。
したがって、使用するメソッドは「query」のみになりました(笑)
wpdbの関数リファレンス

早速エラー!

上のコードで、SQLを実行してもデータが登録できませんでした。
なので下のようなコードでエラーを出力します。
echo $wpdb->last_error;関数ではないので注意です。

そして出力されたエラーは「SQL間違っているよ」でした。
結局できたのは下のようなコードでした。

    // 宣言しないと落ちる
    global $wpdb;
    // テーブルを作成する(ヒアドキュメントはタブが入流ので)
$sql = <<<EOM
CREATE TABLE IF NOT EXISTS MYSQL.QUESTIONARY(
question_id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
question varchar(60),
answer1 varchar(60),
answer2 varchar(60),
answer3 varchar(60),
answer4 varchar(60),
answer5 varchar(60),
hrml_class varchar(15),
html_style varchar(15),
click_count bigint NOT NULL DEFAULT 0);
EOM;
    $wpdb->query( $sql );
    // Footerの文言削除
    add_filter('admin_footer_text', '__return_empty_string');
    // 画面作成用のPHPファイルを読み込みます。
    require_once(plugin_dir_path( __FILE__ ) . '/manage.php');
}

ポイント

  1. 登録時にデータを投入しないカラム「click_count」に関して、CREATE TABLE時に「DEFAULT」を定義していないとエラーになる。
  2. PHPではエラーを意図的に出力する必要がある。

以上のところでした。


    // 宣言しないと落ちる
    global $wpdb;
    // テーブルを作成する(ヒアドキュメントはタブが入流ので)
$sql = <<<EOM
CREATE TABLE IF NOT EXISTS MYSQL.QUESTIONARY(
question_id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
question varchar(60),
answer1 varchar(60),
answer2 varchar(60),
answer3 varchar(60),
answer4 varchar(60),
answer5 varchar(60),
hrml_class varchar(15),
html_style varchar(15),
click_count bigint NOT NULL DEFAULT 0);
EOM;
    $wpdb->query( $sql );
    // Footerの文言削除
    add_filter('admin_footer_text', '__return_empty_string');
    // 画面作成用のPHPファイルを読み込みます。
    require_once(plugin_dir_path( __FILE__ ) . '/manage.php');
    }

でわでわ。。。


関連ページ

  1. WordPress プラグイン作成〜DBを使用する〜
  2. PHP PDO 〜MySQLにアクセスする〜
  3. PHP Ajax 〜DBに登録したデータを受信する〜
  4. Google Maps API PHP連携 〜マップ情報をDBに登録する〜
  5. PHP Image File 〜iPhoneやAndroidでの画像送受信の問題〜
  6. AngularJS Routing 〜PHPをWeb APIにする〜
  7. WordPress PHPカスタム〜根本的に見た目を変える〜
  8. WordPress PHPカスタム〜根本的に見た目を変える2〜
  9. Eclipse PHPプラグイン 〜ElipseでWordPress環境を構築〜
  10. WordPress テスト実装 〜heade-test.phpを表示〜
  11. AngularJS + PHP 〜WordPressと連携する〜
  12. AngularJS + PHP 〜AngularJSの実装〜
  13. AngularJS + PHP 〜AngularJSの実装2〜
  14. WordPress 処理解析 ~index.phpを眺める~
  15. WordPress Plugin NewStatPress ~アクセス解析プラグインAPIを使う~
  16. WordPress 処理解析 ~ログイン処理を調べる~
  17. WordPressカスタム〜アンケートボタンを追加する(設計)〜
  18. WordPressカスタム〜プラグインの作成〜
  19. WordPressカスタム〜ダッシュボードのプラグイン画面作成〜
  20. WordPressカスタム〜ダッシュボードのプラグイン画面作成2〜
  21. WordPressカスタム〜ダッシュボードのプラグイン画面作成3〜
  22. WordPress プラグイン作成〜アンケート作成プラグインを作る〜

WordPress フッター削除

WordPressプラグインの作成中にフッターの表示部分「バージョンX.X.X」の部分が入力項目に被り。。。
早い話がじゃマナになったので削除することにしました。

調べてみると、以下のような方法があるようです。

  1. プラグインで削除
  2. 設定で削除(英語なので翻訳が必要)
  3. 自力で削除

そして、上のどれも自分のやりたいこととちょいと違ったのでそれを解決するのに少し強引な方法を使用しました。
下のように、「バージョン〜」と言う表示があるのですが、それが邪魔になるのは「項目追加」を行ったときなので。。。。

邪魔になるタイミングで対象になるDOM(エレメント)を削除しました。

// 質問の回答項目を追加
function addRow(button) {
    // WPフッターが邪魔なので削除する
    let delDom = document.getElementById("wpfooter");
    delDom.parentNode.removeChild(delDom); ...

上のようなコードで削除できました。仕様としてはイマイチなものです。。。

でわでわ。。。