WordPressAPIについて

Posted コメントするカテゴリー: WordPress

wordpressが標準装備していて、プラグインのプログラム内から呼び出して使用できるAPIがあります。

数あるAPIの中から、代表的なAPIを実際にプログラムして、使ってみます。

まずは、Options API という値を保持する為のAPIを使ってみます。
これまで作ってきたプラグインの画面遷移時の動きを利用して、画面遷移の間で値が保持できているかを確認してみます。

まず、データ一覧画面で

update_option("test", "a");

という記述を行い、これを登録画面→確認画面で、取得して表示してみます。

次に、登録確認画面側に、以下のように記述します。

$test_value = get_option("test");
echo $test_value; //内容チェック用に強引に出力する

これで、新規登録後の確認画面で「a」という文字列が表示されることが確認できました(画面キャプチャは省略します)。

保持したデータを削除するには

delete_option("test");

という記述で値を消すことができます。

update_optionと同様のAPIにadd_optionというAPIがあります。
これは画面アクセス時に対し、update_optionはまとめてデータ取得するのに対し、add_optionはget_optionを行う度にデータベースへ問い合わせが発生します。(add_optionの第4引数を使用時)

厳密に言えば、add_optionを多用すると、パフォーマンスが下がる原因になるようです。

データ登録時のエラー処理を変更する

Posted コメントするカテゴリー: WordPress

これまでの開発ではデータ登録時のエラー処理は、古典的(?)な書き方で入力チェック→エラー内容表示を行っていました。

wordpressには元々エラー処理用のクラスがあるので、それに置き換えてみようと思います。

まずは、入力画面から登録ボタンを押した際の、確認画面の処理を見直します。

//エラー処理を入れる為のオブジェクト生成
$error = new WP_Error();

//入力値チェック(複数のエラーチェックをここで行う)
if (!strlen($_POST["sample_name"])) {
    $error->add("error", "名前を入力してください");
}
if (!strlen($_POST["sample_text"])) {
    $error->add("error", "テキストを入力してください");
}

//エラーコードがある場合は、登録画面を再表示する
if ($error->get_error_code()) {
    //ここで改めて登録フォームを表示する
}

まず、「$error = new WP_Error();」とすることで、エラー処理用のクラスを呼び、オブジェクトを生成しておきます。

次に、入力値チェックを行います。
入力値のチェック方法は色々あると思いますが、ここでは「strlen」を使って単純に文字列(の長さ)があるか無いかで判定しています。
(チェック用の関数の使い方は、別方法がありますが、ここでは割愛いたします)

最後に、「$error->get_error_code()」でエラーだった場合のコードを取得し、エラー表示を行うか、どうかの判定をします。

エラーだった場合は、改めて登録フォームを表示します。

次に、エラー時の登録フォーム側のプログラムを調整します。

//エラー処理
if ($error->get_error_codes()) {
    echo "<div class='error'>";
    echo "<ul>";
    foreach ($error->get_error_messages() as $value) {
        echo "<li>" . esc_html($value) . "</li>";
    }
    echo "</ul>";
    echo "</div>";
}

$errorオブジェクトを渡し、エラーコードの有無を判定します。
エラーだった場合、エラー内容をエラーの個数分表示しています。

具体的な画面は次のようになります。

入力フォームの初期画面

エラーだった場合の再表示画面

エラーメッセージの表示時のクラス名

<div class='error'>

はwordpressに標準搭載されているcssのクラス名なので、画面のエラー文言の表現が統一されて便利です。

また、

<div class='updated'>

というクラス名もあり、その場合は正常に更新されたケースで使用するとよいです。

登録フォームに対し、CSRF対策を入れる

Posted コメントするカテゴリー: WordPress

これまでに作成したプラグインは、データ登録画面で、入力フォームを表示し、次の画面で内容チェック、その後に完了画面を表示する。という一連の動作になっています。

この時、入力フォームから確認画面へ遷移する際のセキュリティとして、CSRF攻撃がされる場面が想定されます。

このCSRF攻撃に対応する為に、対策を入れます。
具体的には、入力画面のform開始タグの直下に、以下の命令を書きます。

<?php wp_nonce_field("my-nonce-key", "my-form"); ?>

また、確認画面側では、次のように書いて、CSRFのチェックを行います。

//CSRF対策用のチェック
if (isset($_POST["my-form"]) && $_POST["my-form"]) {
    if (check_admin_referer("my-nonce-key", "my-form")) {
        //問題がなければ、ここで処理を続行
        
    }
}

ポイントとなる箇所だけを書きましたが、フォーム内に「wp_nonce_field」を、確認画面のチェック処理で「check_admin_referer」を、それぞれ使うということで、覚えておいてよいかと思います。

メディアアップローダを使わずにファイルのアップロードを行う

Posted コメントするカテゴリー: WordPress

前回の投稿ではメディアアップローダの画面を利用したファイルのアップロードを書きましたが、今回は単純なプログラムによるファイルのアップロードを書きます。

プラグインを作成する方向性としては、無意味な実装になるかもしれませんが、ここは実験がてらやってみます。

まず、作成中のプラグインのTOP画面にファイルアップロード用のボタンを追加します。

    function disp()
    {
        echo <<< EOL
<form action="" method="post">

    <h2>データ一覧</h2>
    <input type='submit' name='submit[regist]' class='button-primary' value='新規登録' />
    <input type='submit' name='submit[regist_file]' class='button-primary' value='新規登録(ファイルアップロード)' />

    <div class="wrap">

    <table class="wp-list-table widefat striped posts">
        <tr>
            <th nowrap>ID</th>
            <th nowrap>名前</th>
            <th nowrap>テキスト</th>
            <th nowrap>チェック</th>
            <th nowrap>ラジオ</th>
            <th nowrap>セレクト</th>
            <th nowrap>テキストエリア</th>
            <th nowrap>登録日時</th>
            <th nowrap>詳細</th>
            <th nowrap>編集</th>
        </tr>
EOL;

以下、省略します…

すると次のような画面になります。

続いて、ボタンを押下した際の動作を決める関数に、ファイルアップロード用画面と、アップロードボタンを押された際のメソッドを追加します。

function sample_plugin()
{
    if (isset($_REQUEST["submit"]["detail"])) {
        //他の処理は記述を省略します…

    } else if (isset($_REQUEST["submit"]["regist_file"])) {
        //ファイルアップロード用画面
        self::regist_file();
    } else if (isset($_REQUEST["submit"]["regist_file_up"])) {
        //ファイルアップロード処理
        self::regist_file_up();

    } else {
        self::disp();
    }
}

次に、画面上の「新規登録(ファイルアップロード)」ボタンを押した時の処理を書きます。

function regist_file($error_message_flg = null)
{
    echo <<< EOL
<h2>ファイルアップロード</h2>
<div class="wrap">
<div class="wrap">
<table class="wp-list-table widefat striped posts">
    <tr>
        <td>ファイルアップロード</td>
        <td>
            <form method="post" action="" enctype="multipart/form-data">
                CSVを選択してアップロードボタンを押してください<br />
                <input type="file" name="upfilename" />
                <input type="submit" value="アップロード">
                <input type="hidden" name="submit[regist_file_up]" value="on">
            </form>

        </td>
    </tr>
</table>
</div>
<form action="" method="post">
    <input type='submit' name='submit[file_upload]' class='button-primary' value='戻る' />
    <input type="hidden" name="form_id" value="{$form_id}">
    <input type="hidden" name="create_date" value="{$create_date}">
</form>
</div>
EOL;

}

今はデザインやレイアウトについては、割愛して書いています。
画面はこのようになります。

画面上から、ファイルを選択してアップロードボタンを押した後の処理は次のように書きました。

function regist_file_up()
{
    //CSVファイルがアップロードされた場合
    if (is_uploaded_file($_FILES["upfilename"]["tmp_name"])) {
        
        // wordpressが用意している関数
        $upload_dir = wp_upload_dir();
        
        // ファイル名を取得してアップロード処理を行う
        $upload_file_name = $upload_dir['basedir'] . "/" . $_FILES["upfilename"]["name"];
        if (move_uploaded_file($_FILES["upfilename"]["tmp_name"], $upload_file_name)) {
            chmod($upload_file_name, 0777);

            // アップロード&ファイル権限の変更が完了したら成功とする
            $message = "ファイルをアップロードいたしました";
        }
        
    } else {
        $message = "ファイルのアップロードが失敗しました";
    }

    //完了メッセージの出力
    echo <<< EOL
<h2>ファイルアップロード完了</h2>
<form action="" method="post">
<div class="wrap">
    {$message}
</div>
<input type='submit' name='submit[]' class='button-primary' value='戻る' />
</form>
EOL;

}

書き方は一般的なファイルアップロードによる処理と、変わらないですが、「wp_upload_dir();」というwordpressが用意している関数を使っている点がポイントになります。

この関数をコールし、「$upload_dir[‘basedir’]」という値をとることにより、wordpressの「uploads」ディレクトリまでのフルパスを参照できます。

そうすることで、uploadsディレクトリ直下にファイルをアップロードすることができています。

完了後は、次のような画面になります。

これで、ファイルをアップロードが完了します。
工夫や改善の余地はありますが、基本的な流れはできているので、あとはどのように応用するかになります。

ファイルのメディアアップローダを使う

Posted コメントするカテゴリー: WordPress

管理画面側に、wordpressに搭載されているメディアアップローダを組み込んでみます。

そもそも管理画面にファイルをアップロードする機能はphp標準のファイルアップロードの処理を書くことでも実装が可能です。
ただ、その場合はアップロード先ディレクトリをどうするか、仕様を決めておかないといけない為、配慮すべき項目が多くなりがちです。

そこでメディアアップローダを使うことで、アップロードとファイル保存先についてはある程度wordpressまかせにすることができます。

以下、実装手順を記載します。

まず、__construct()等に、必要となるjavascript関連のファイルを読み込みます。

wp_enqueue_script('media-upload');
wp_enqueue_script('thickbox');

次に、スタイルシート関連のファイルも読み込みます。これは同じくコンストラクタ内で問題ありませんが、独自にスタイルシート読み込み用に関数を分けておいてもいいかもしれません。

wp_enqueue_style('thickbox');

続いて、登録画面に対して、ファイルアップロードの為のフォームを記載します。(ここは上記参考サイト様の書き方を引用させていただきました)

<input type="text" id="my_media_1" name="my_media_1" value="" />
<a class="media-upload" href="JavaScript:void(0);" rel="my_media_1">ファイル選択</a>

そして、フォーム内の「ファイル選択」リンクを押下した時に、
メディアアップロードのダイアログを立ち上げる為に、以下のjavascriptを記載します。

<script type="text/javascript">
jQuery("document").ready(function(){
    jQuery(".media-upload").each(function(){
        var rel = jQuery(this).attr("rel");
        jQuery(this).click(function(){
            window.send_to_editor = function(html) {
                imgurl = jQuery("img", html).attr("src");
                jQuery("#"+rel).val(imgurl);
                tb_remove();
            }   
            formfield = jQuery("#"+rel).attr("name");
            tb_show(null, "media-upload.php?post_id=0&type=image&TB_iframe=true");
            return false;
        });
    });
});
</script>

という記載をフォームが表示される画面内のHTMLタグのどこかに記載します。

以上の記述をすることで、フォーム画面からメディアアップロードの画面を出し、そこでファイルを選択して、URL等をフォームにセットすることができます。

以下、これまでに作成してきたサンプルプラグインの「新規登録」画面に対して、ファイルアップロードの項目を追加してみたので、そのキャプチャを貼ります。

赤枠部分が実際に操作をしてみて、ファイルのアップロード(例ではアップロード済みのファイルを選択しました)、ファイル名取得、フォーム項目への設置、という一連の動きになっています。

①新規登録画面へ

②登録画面から「ファイル選択」をクリック

③既にアップロード済みのファイルを選択

④該当のファイル(例では「00.png」を選択)し、詳細画面を表示。その後「ファイルのURL」を取得するボタンを押す

⑤ファイル名が取得できます

⑥同画面の下にある「投稿に挿入」ボタンを押して、元の新規登録フォームへ戻ると、ファイル名がセットされています。

ページャの見直し

Posted コメントするカテゴリー: WordPress

前回のページャを設置した記事をおさらいを含めて、見直してみます。

前回投稿した記事https://propansystem.net/blog/?p=1022では、登録データ数の無関係にページャ表示をしていました。

この場合、1画面内に10記事のデータ数を超えている場合は問題ありませんが、10記事以内のデータの場合にもページャが1ページ分のみ表示されてしまいます。

ページャをクリックしても何も起きず、ページャを表示していまうことで余計に操作しずらくなります。

そこで、データ一覧を出力する箇所のページャ表示部分に件数制限のロジックを入れて、10件未満の場合にはページャを表示しないようにします。

データ一覧を表示する関数部分を抜粋します。

	function disp()
	{
		//データ一覧
		echo <<< EOL
<form action="" method="post">
<h2>データ一覧</h2>
<input type='submit' name='submit[regist]' class='button-primary' value='新規登録' />
<div class="wrap">
<table class="wp-list-table widefat striped posts">
	<tr>
		<th nowrap>ID</th>
		<th nowrap>名前</th>
		<th nowrap>テキスト</th>
		<th nowrap>チェック</th>
		<th nowrap>ラジオ</th>
		<th nowrap>セレクト</th>
		<th nowrap>テキストエリア</th>
		<th nowrap>登録日時</th>
		<th nowrap>詳細</th>
		<th nowrap>編集</th>
	</tr>
EOL;

		//現在ページ取得
		$pageid = filter_input(INPUT_GET, 'pageid');

		//1ページあたりの件数
		$limit = 10;

		//DBオブジェクトを用意
		global $wpdb;

		//全件数取得
		$tbl_name = $wpdb->prefix . 'sample_mst';
		$sql = "SELECT count(*) AS CNT FROM {$tbl_name}";
		$rows = $wpdb->get_results($sql);
		$recordcount = $rows[0]->CNT;

		$offset = $pageid * $limit;

		//offset と limitによる画面表示用のデータ取得
		$sql = "SELECT * FROM {$tbl_name} ORDER BY id limit {$offset}, {$limit};";

		//通常の取得方法(SQL実行結果を、オブジェクトとして取得)
		$rows = $wpdb->get_results($sql);

		foreach($rows as $row) {
			echo "<tr>";
			echo "<td>" . $row->id . "</td>";
			echo "<td>" . $row->sample_name . "</td>";
			echo "<td>" . $row->sample_text . "</td>";
			echo "<td>" . $row->sample_check . "</td>";
			echo "<td>" . $row->sample_radio . "</td>";
			echo "<td>" . $row->sample_select . "</td>";
			echo "<td>" . $row->sample_textarea . "</td>";
			echo "<td>" . $row->create_date . "</td>";
			echo "<td>";
			echo "<input type='submit' name='submit[detail][" . $row->id . "]'";
			echo " class='button-primary' value='詳細' />";
			echo "</td>";
			echo "<td>";
			echo "<input type='submit' name='submit[edit][" . $row->id . "]'";
			echo " class='button-primary' value='編集' />";
			echo "</td>";
			echo "</tr>";
		}
		echo "</table>";
		echo "</div>";
		echo "</form>";

		//データ数が1画面あたりの記事数を超える場合のみ、ページャを表示する
		if ($recordcount > $limit) {
			$args = array(
				'label' => __('Per Page'),
				'default' => 10,
				'option' => 'disp'
			);
			$page_html = self::pagination($recordcount);

			//ページ部分の表示
			echo "<div class='admin_pagination'>";
			echo "<ul>";
			foreach ($page_html as $key => $value) {
				echo "<li>" . $value . "</li>";
			}
			echo "</ul>";
		}

	}

関数の最後で「if ($recordcount > $limit) {」という分岐を行い、
10件に満たない場合の制御をしています。

こうすることにより、データ数が少ない場合は、以下のような表示になります。

画面表示の書き方はもっとシンプルで、わかりやすい書き方はあると思いますが、今は不恰好ですが動作しているので次に進めていきます。

wordpress流の書き方については、今後の研究課題にして追求していく予定です。

クイックリターン関数について

Posted コメントするカテゴリー: WordPress

クイックリターン関数について、調べてみます。
下記のようなコードを例にします。

add_filter("test_filter", "sample_func");
function sample_func() {
    //何らかの処理
    return true;
}

上記のコードは「test_filter」としてフィルターフックを指定し、sample_func関数をコールバックしています。

sample_func関数内で何らかの処理を行う関数の場合、次のような戻り値の時に簡略化して書くことができます。

「true」「false」「array()」(空の配列を返す)「””」「null」「0」

上記の戻り値の場合、

function sample_func() {
    //何らかの処理
    return true;
}

の関数定義を書かずに、

add_filter("test_filter", "__return_true");

のように一行で書くことできます。
下記のそれぞれのケースでは、
「false」「array()」(空の配列を返す)「””」「null」「0」
次のように書けます。

//false
add_filter("test_filter", "__return_false");
//array()
add_filter("test_filter", "__return_empty_array");
//""
add_filter("test_filter", "__return_empty_string");
//null
add_filter("test_filter", "__return_null");
//0
add_filter("test_filter", "__return_zero");

実際にフィルターを使う時に試してみるほうが良さそうです。

プラグインが無効化された時に実行される関数について

Posted コメントするカテゴリー: WordPress

前の投稿ではプラグインを有効化した時に実行される関数についてでしたが、今回はプラグインを無効化した時に実行される関数について調べてみます。

無効化する時に実行される関数は以下になります。

register_deactivation_hook($file, $callback);

第一引数は、有効化した時の関数と同じく、実行されるプログラムのファイル名を指定します。
「__FILE__」等と指定しても問題なく動作します。

第二引数は無効化した時に実行されるコールバック関数を指定します。

例として、以下のように書きます。

register_deactivation_hook(__FILE__, 'test_de_action');

function test_de_action() {
    //ここで何らかの処理
}

関数側がクラスを使っている場合は、次のように書きます。

register_activation_hook(__FILE__, array('test_class', 'test_de_action');
 
class test_class {
    function test_de_action() {
        //ここで何らかの処理
    }
}

有効化と同じように書けるので、有効化の処理が問題なく動作すれば、そのまま無効化も同じように書くことができます。

プラグイン有効化時に実行される関数について

Posted コメントするカテゴリー: WordPress

プラグインの機能として、プラグインをインストールした後に、「有効化」を行うタイミングの時に1度だけ実行される関数が用意されています。

以前、プラグインを作成した際、過去のブログでも取り上げていましたが、もう少し深く調べてみます。

プラグインの有効化のタイミングで実行される関数は、以下のようになります。

register_activation_hook($file, $callback);

第一引数はプラグインのメインPHPファイルのパスを、
第二引数にはプラグインを有効化した時に実行されるコールバック関数を指定します。

例として、次のようになります。

register_activation_hook(__FILE__, 'test_action');

function test_action() {
    //ここで何らかの処理
}

関数側がクラスを使っている場合は、第二引数の書き方が次のように変わります。

register_activation_hook(__FILE__, array('test_class', 'test_action');

class test_class {
    function test_action() {
        //ここで何らかの処理
    }
}

実際にプラグイン作成時に書いた処理なので、動作検証については既に完了しています。
あとは処理の中で何をどうプログラムするのかで様々な操作をすることが可能になるので、そこは設計次第になります。

アクションフックにアクションを登録する

Posted コメントするカテゴリー: WordPress

アクションフックにアクションを登録する方法は以下になります。

※wordpressの公式ドキュメントからの抜粋になりますが、若干説明を簡易にしています。

add_action(アクションを適用するフック名, コールバック関数, 優先順位, フックした関数が受け入れられる引数の数);

この登録したアクションの中身は以下のように記述します。
※これもwordpressの公式ドキュメントから参照したコードです。

function email_friends( $post_ID )  {
   $friends = 'bob@example.org, susie@example.org';
   wp_mail( $friends, "sally's blog updated", 'I just put something on my blog: http://blog.example.com' );

   return $post_ID;
}
add_action( 'publish_post', 'email_friends' );

上記のコードは「ブログを投稿しときに、メール通知を行う」という動作のようです。

add_actionの第一引数で「アクションを呼ぶきっかけとなる動作」を決定しています。
この第一引数には、様々な操作を設定できるようで、公式ドキュメントにまとめられています。

上記URLを見ると「一般的リクエスト中に実行されるアクション」や「管理画面リクエスト中に実行されるアクション」等といったアクションのきっかけがまとめれています。

この情報を使って第一引数を決定し、特定の動作を行う関数を用意する。
というような実装の流れになると思われます。(実際の実装は今後の課題予定とします)

アクションフックについて

Posted コメントするカテゴリー: WordPress

do_action()が実行されている場所をアクションフックと呼びます。

アクションフックはフィルターフックと似ています。
どちらもフック(きっかけ)があった場合に処理が動きます。

アクションフックは、管理画面などで、投稿記事の公開、テーマ変更、などが行われた際に始動されます。

また、フィルターフックについてはwordpressのサイト側を表示する際に、特定の処理を通して表示を変更したい場合、等に利用されます。

アクションについて

Posted コメントするカテゴリー: WordPress

アクションは特定のイベントが発生した際に実行される処理を言います。
例えば、wp_headアクションはよく利用されるアクションです。

テンプレート内でwp_headが呼び出されたら、cssやjsの読み込みを一括して行う。といった処理で利用される例があります。

フィルターフックにフィルターを追加する

Posted コメントするカテゴリー: WordPress

apply_filters()にフィルターを追加するにはadd_filter()関数を使います。

これは実際に書いてみないと分からないので、簡単なサンプルプログラムを作ります。

前回の投稿で、簡単なサンプルを作りました。
それをおさらいしてみます。

フィルターフックを設置する
function sample_func1() {
    return apply_filters("sample_filter", "hoge");
}

//「sample_filter」フックに対して、コールバック関数(sample_call)を指定する
add_filter("sample_filter", "sample_call");
 
//コールバック関数
function sample_call($value) {
    return "fuga";
}

applry_filtersはフィルターフックを設置するための関数です。
第一引数がフック名、第二引数がコールバック関数への引数になります。

フィルターフックについて

Posted コメントするカテゴリー: WordPress

フィルターの使い方について、学びます。

フィルターフックについて

wordpressはHTMLの出力や、各種設定、環境変数、フォーム入力値などは、apply_filters()という関数を経由します。

例えば、ある関数を定義して、それをフィルターフックを設置する場合は、次のように書きます。

function sample_func1() {
	return "test";
}

この関数をフィルターフックを設置します。

function sample_func1() {
	return apply_filters("sample_filter", "hoge");
}

上記のフィルターフックを、プラグインやテーマのfunctions.phpで次のように適用します。

add_filter("sample_filter", "sample_call");

function sample_call($value) {
	return "fuga";
}

実際にこのフィルターフックを利用したプログラムを作成してみます。

管理画面側でjavascript(jquery)を呼び出す

Posted コメントするカテゴリー: WordPress

これまでの管理画面の作りは、ほぼphpのみで実装してきました。

次にこの管理画面にjavascirpt(jquery)を動作させるように設定してみます。

まず、プラグインフォルダの中に、jsファイルを設置する為のディレクトリを作成します。

/ワードプレス設置ディレクトリ/wp-content/plugins/SamplePlugin1

上記のディレクトリに対し、jsディレクトリを作成します。

/ワードプレス設置ディレクトリ/wp-content/plugins/SamplePlugin1/js/

次に、そのディレクトリ内に、javascript用のファイルを設置します。

/ワードプレス設置ディレクトリ/wp-content/plugins/SamplePlugin1/js/sample1_script.js

jsの中は、jqueryが使用できるので、以下のようなサンプルコードを書きます。

(function($){
    alert("hello jquery !");
})(jQuery);

次に、プラグイン本体のphpのコンストラクタの中に、以下の読み込み命令文を書きます。

wp_register_script('sample1js', plugins_url( './js/sample1_script.js', __FILE__ ));
wp_enqueue_script('sample1js');

こうすることで、プラグインの画面にアクセスした時にjsがロードされます。
例では、アラートを表示するだけのシンプルなjsですが、画面にアクセスすると以下のようになります。

アラート表示だけのプログラムなので、あまり意味がないですが、jsが動作することを確認できました。

登録画面を追加する

Posted コメントするカテゴリー: WordPress

前回までのソースコードを元に、新規登録画面の一連の動きを書きます。

	/**
	 * 登録
	 */
	function regist($error_message_flg = null)
	{
		if ($error_message_flg == false) {
			$sample_name = esc_attr($_REQUEST["sample_name"]);
		}

		if (isset($_REQUEST["form_id"])) {
			//確認画面の「戻る」ボタンから遷移してきた場合
			$form_id = esc_attr($_REQUEST["form_id"]);

			$sample_name = esc_attr($_REQUEST["sample_name"]);
			$sample_text = esc_attr($_REQUEST["sample_text"]);
			$sample_check = $_REQUEST["sample_check"];
			$sample_radio = esc_attr($_REQUEST["sample_radio"]);
			$sample_select = esc_attr($_REQUEST["sample_select"]);
			$sample_textarea = esc_attr($_REQUEST["sample_textarea"]);

			//チェックボックスの判定
			foreach ($sample_check as $key => $value) {
				$sample_check_checked[$value] = "checked";
			}
			
			//ラジオボタンの判定
			for ($i=0; $i<3; $i++) {
				if ($sample_radio == $i) {
					$sample_radio_checked[$i] = "checked";
				}
			}
			
			//セレクトボックスの判定
			$sample_select_array = array("a", "b", "c", "d", "e");
			foreach ($sample_select_array as $key => $value) {
				if ($sample_select == $value) {
					$sample_select_selected[$key] = "selected";
				}
			}

			$create_date = esc_attr($_REQUEST["create_date"]);
		} else {
			
			//一覧画面から「編集」ボタンを押下した場合
			
			//押されたボタンのIDを取得する
			if (array_search("編集", $_REQUEST["submit"]["edit"])) {
				$form_id = array_search("編集", $_REQUEST["submit"]["edit"]);
			}

			global $wpdb;
			$tbl_name = $wpdb->prefix . 'sample_mst';
			$sql = "SELECT * FROM {$tbl_name} WHERE id = %d;";
			$prepared = $wpdb->prepare($sql, $form_id);
			$rows = $wpdb->get_results($prepared, ARRAY_A);

			$sample_name = $rows[0]["sample_name"];
			$sample_text  = $rows[0]["sample_text"];
			$sample_check  = $rows[0]["sample_check"];
			$sample_radio  = $rows[0]["sample_radio"];
			$sample_select  = $rows[0]["sample_select"];
			$sample_textarea = $rows[0]["sample_textarea"];

			$sample_check = explode(",", $sample_check);

			//チェックボックスの判定
			foreach ($sample_check as $key => $value) {
				$sample_check_checked[$value] = "checked";
			}
			
			//ラジオボタンの判定
			for ($i=0; $i<3; $i++) {
				if ($sample_radio == $i) {
					$sample_radio_checked[$i] = "checked";
				}
			}
			
			//セレクトボックスの判定
			$sample_select_array = array("a", "b", "c", "d", "e");
			foreach ($sample_select_array as $key => $value) {
				if ($sample_select == $value) {
					$sample_select_selected[$key] = "selected";
				}
			}

			$create_date = $rows[0]["create_date"];

		}

		echo <<< EOL
<form action="" method="post">
<h2>データ登録</h2>
EOL;

		if (strlen($error_message_flg)) {
			echo "<div class='updated fade'><p><strong>";
			echo _e('NAMEを入力してください');
			echo "</strong></p></div>";
		}

		echo <<< EOL

<div class="wrap">

<form action="" method="post">
	<h2>データ編集</h2>

	<div class="wrap">

	<table class="wp-list-table widefat striped posts">
		<tr>
			<td>ID</td>
			<td>{$form_id}</td>
		</tr>
		<tr>
			<td>NAME</td>
			<td>
				<input type="text" name="sample_name" value="{$sample_name}">
			</td>
		</tr>

		<tr>
			<td>テキスト</td>
			<td>
				<input type="text" name="sample_text" value="{$sample_text}">
			</td>
		</tr>
		<tr>
			<td>チェックボックス</td>
			<td>
				チェック値1<input type="checkbox" name="sample_check[]" value="0" {$sample_check_checked[0]}>
				チェック値2<input type="checkbox" name="sample_check[]" value="1" {$sample_check_checked[1]}>
				チェック値3<input type="checkbox" name="sample_check[]" value="2" {$sample_check_checked[2]}>
			</td>
		</tr>
		<tr>
			<td>ラジオボタン</td>
			<td>
				ラジオ値1<input type="radio" name="sample_radio" value="0" {$sample_radio_checked[0]}>
				ラジオ値2<input type="radio" name="sample_radio" value="1" {$sample_radio_checked[1]}>
				ラジオ値3<input type="radio" name="sample_radio" value="2" {$sample_radio_checked[2]}>
			</td>
		</tr>
		<tr>
			<td>セレクトボックス</td>
			<td>
				<select name="sample_select">
					<option value="a" {$sample_select_selected[0]}>選択a</option>
					<option value="b" {$sample_select_selected[1]}>選択b</option>
					<option value="c" {$sample_select_selected[2]}>選択c</option>
					<option value="d" {$sample_select_selected[3]}>選択d</option>
					<option value="e" {$sample_select_selected[4]}>選択e</option>
				</select>
			</td>
		</tr>
		<tr>
			<td>テキストエリア</td>
			<td>
				<textarea name="sample_textarea" cols="30" rows="5">{$sample_textarea}</textarea>
			</td>
		</tr>

		<tr>
			<td>登録日時</td>
			<td>{$create_date}</td>
		</tr>
	</table>

	<input type='submit' name='submit[regist_check]' class='button-primary' value='登録内容を確認する' />
	<input type='submit' name='submit[]' class='button-primary' value='戻る' />

	<input type="hidden" name="form_id" value="{$form_id}">
	<input type="hidden" name="create_date" value="{$create_date}">

	</div>

</form>

EOL;
	}

	/**
	 * 登録確認
	 */
	function regist_check()
	{
		if (!strlen($_REQUEST["sample_name"])) {
			self::regist(false);
			return;
		}
		
		$sample_name = esc_attr($_REQUEST["sample_name"]);

		$sample_name = esc_attr($_REQUEST["sample_name"]);
		$sample_text = esc_attr($_REQUEST["sample_text"]);
		$sample_check = $_REQUEST["sample_check"];
		$sample_radio = esc_attr($_REQUEST["sample_radio"]);
		$sample_select = esc_attr($_REQUEST["sample_select"]);
		$sample_textarea = esc_attr($_REQUEST["sample_textarea"]);

		//チェックボックスの値を処理
		if (is_array($_REQUEST["sample_check"])) {
			foreach ($_REQUEST["sample_check"] as $key => $value) {
				$disp_checkbox .= "チェック値" . $value . "<br />";
				$hidden_checkbox .= '<input type="hidden" name="sample_check[]" value="' . $value . '">';
			}
		}

		//テキストエリア整形(表示用)
		$sample_textarea_disp = nl2br($sample_textarea);

		//データ一覧
		echo <<< EOL
<form action="" method="post">
	<h2>データ編集確認</h2>

	<div class="wrap">

	    <table class="wp-list-table widefat striped posts">
			<tr> 
				<td>ID</td>
				<td>{$form_id}</td>
			</tr>
			<tr> 
				<td>NAME</td>
				<td>{$sample_name}</td>
			</tr>
			<tr> 
				<td>テキスト</td>
				<td>{$sample_text}</td>
			</tr>
			<tr> 
				<td>チェックボックス</td>
				<td>
					{$disp_checkbox}
				</td>
			</tr>
			<tr> 
				<td>ラジオボタン</td>
				<td>{$sample_radio}</td>
			</tr>
			<tr> 
				<td>セレクトボックス</td>
				<td>{$sample_select}</td>
			</tr>
			<tr> 
				<td>テキストエリア</td>
				<td>{$sample_textarea_disp}</td>
			</tr>
		</table>

	<input type="hidden" name="form_id" value="{$form_id}">

	<input type="hidden" name="sample_name" value="{$sample_name}">
	<input type="hidden" name="sample_text" value="{$sample_text}">
	{$hidden_checkbox}
	<input type="hidden" name="sample_radio" value="{$sample_radio}">
	<input type="hidden" name="sample_select" value="{$sample_select}">
	<input type="hidden" name="sample_textarea" value="{$sample_textarea}">

	<input type="hidden" name="create_date" value="{$create_date}">

	</div>

	<input type='submit' name='submit[regist_exec]' class='button-primary' value='登録する' />
	<input type='submit' name='submit[regist]' class='button-primary' value='戻る' />

</form>
EOL;

	}

	/**
	 * 登録実行
	 */
	function regist_exec()
	{
		global $wpdb;

		$sample_name = esc_attr($_REQUEST["sample_name"]);
		$sample_text = esc_attr($_REQUEST["sample_text"]);
		$sample_radio = esc_attr($_REQUEST["sample_radio"]);
		$sample_select = esc_attr($_REQUEST["sample_select"]);
		$sample_textarea = esc_attr($_REQUEST["sample_textarea"]);

		//チェックボックスの値を処理
		if (is_array($_REQUEST["sample_check"])) {
			foreach ($_REQUEST["sample_check"] as $key => $value) {
				$sample_check .= $value . ",";
			}
		}

		//投稿を登録
		$table_name = $wpdb->prefix . 'sample_mst';
		$result = $wpdb->insert(
			$table_name,
			array(
				'sample_name' => $sample_name,
				'sample_text' => $sample_text,
				'sample_check' => $sample_check,
				'sample_radio' => $sample_radio,
				'sample_select' => $sample_select,
				'sample_textarea' => $sample_textarea,
				'create_date' => current_time('mysql')
			)
		);

		//データ一覧
		echo <<< EOL
<form action="" method="post">
<h2>データ登録</h2>
<div class='updated fade'><p><strong>
EOL;

		echo _e('登録が完了しました');

		echo <<<EOL
</strong></p></div>
<input type='submit' name='submit[]' class='button-primary' value='戻る' />
EOL;
		echo "</form>";
	}

更新系ですので、修正の処理を同じような流れになります。
登録フォームがあり、確認画面があり、完了メッセージ画面があります。

詳細画面の項目を追加する

Posted コメントするカテゴリー: WordPress

これまでに追加した項目を編集画面で自由に編集ができるようになりました。

次は詳細画面の項目を追加し、表示項目を合わせようと思います。
改修したソースは以下のようになります。


/**
 * 詳細表示
 */
function detail()
{
	//押されたボタンのIDを取得する
	if (array_search("詳細", $_REQUEST["submit"]["detail"])) {
		$form_id = array_search("詳細", $_REQUEST["submit"]["detail"]);
	}

	//データ一覧
	echo <<< EOL
<form action="" method="post">
<h2>データ詳細</h2>

EOL;

	global $wpdb;

	$tbl_name = $wpdb->prefix . 'sample_mst';
	$sql = "SELECT * FROM {$tbl_name} WHERE id = %d;";
	$prepared = $wpdb->prepare($sql, $form_id);
	$rows = $wpdb->get_results($prepared, ARRAY_A);

	$sample_name = $rows[0]["sample_name"];
	$sample_text  = $rows[0]["sample_text"];
	$sample_check  = $rows[0]["sample_check"];
	$sample_radio  = $rows[0]["sample_radio"];
	$sample_select  = $rows[0]["sample_select"];
	$sample_textarea = $rows[0]["sample_textarea"];

	$create_date = $rows[0]["create_date"];

	echo <<<EOL

<div class="wrap">

<table class="wp-list-table widefat striped posts">
	<tr>
		<td>ID</td>
		<td>{$form_id}</td>
	</tr>

	<tr>
		<td>NAME</td>
		<td>{$sample_name}</td>
	</tr>

	<tr>
		<td>テキスト</td>
		<td>{$sample_text}</td>
	</tr>
	<tr>
		<td>チェック</td>
		<td>{$sample_check}</td>
	</tr>
	<tr>
		<td>ラジオ</td>
		<td>{$sample_radio}</td>
	</tr>
	<tr>
		<td>セレクト</td>
		<td>{$sample_select}</td>
	</tr>
	<tr>
		<td>テキストエリア</td>
		<td>{$sample_textarea}</td>
	</tr>

	<tr>
		<td>登録日時</td>
		<td>{$create_date}</td>
	</tr>
</table>

</div>

<input type="hidden" name="form_id" value="{$form_id}">

<input type='submit' name='submit[delete_check]' class='button-primary' value='削除確認する' />
<input type='submit' name='submit[]' class='button-primary' value='戻る' />
EOL;
	echo "</form>";
}

実行した画面は以下のようになります。

DBの内容をそのまま表示しているので、チェックボックス、ラジオボタン、セレクトボックスの箇所は工夫が必要になります。
何を出力させたいのか、を明確にして形づくるのがよいです。

編集ボタン押下時の処理を書く

Posted コメントするカテゴリー: WordPress

前回までは、一覧画面から該当のデータを選択し、編集フォームにDBの値をセットし、その値を編集して確認画面を出力するところまで実装しました。

次は、編集確認画面から、編集ボタンを押下し、編集処理をするプログラムを書きます。

編集実行時のプログラムは以下のようになります。

/**
 * 編集実行
 */
function edit_exec()
{
	global $wpdb;

	$form_id = esc_attr($_REQUEST["form_id"]);

	$sample_name     = esc_attr($_REQUEST["sample_name"]);
	$sample_text     = esc_attr($_REQUEST["sample_text"]);
	$sample_radio    = esc_attr($_REQUEST["sample_radio"]);
	$sample_select   = esc_attr($_REQUEST["sample_select"]);
	$sample_textarea = esc_attr($_REQUEST["sample_textarea"]);
	$update_date     = date("Y-m-d H:i:s");

	// チェックボックスの値を処理
	if (is_array($_REQUEST["sample_check"])) {
		foreach ($_REQUEST["sample_check"] as $key => $value) {
			$disp_checkbox .= "チェック値" . $value . "<br />";
			$sample_check .= $value . ',';
		}
	}

	// 投稿を更新
	$tbl_name = $wpdb->prefix . 'sample_mst';
	$result = $wpdb->update(
		$tbl_name,
		array(
			'sample_name'     => $sample_name,
			'sample_text'     => $sample_text,
			'sample_check'    => $sample_check,
			'sample_radio'    => $sample_radio,
			'sample_select'   => $sample_select,
			'sample_textarea' => $sample_textarea,
			'update_date'     => $update_date,
		),
		array('id' => $form_id,),
		array(
			'%s',
			'%s',
			'%s',
			'%s',
			'%s',
			'%s'
		),
		array('%d')
	);

	// データ一覧
	echo <<< EOL
<form action="" method="post">
	<h2>データ修正</h2>
	<div class='updated fade'><p><strong>
EOL;
	echo _e('更新が完了しました');
	echo <<<EOL
</strong></p></div>
<input type='submit' name='submit[]' class='button-primary' value='戻る' />
</form>
EOL;
}

この処理を実行すると、DB内には、編集画面で入力された値が格納されます。

$wpdbの使い方は、さらに研究する必要がありますが、今のところ上記の書き方で更新されるので、この書き方で進めます。

また、前回までに書いた編集画面の値のセットの仕方がいまいちな部分があったので、それも合わせて変更しました。

/**
 * 修正
 */
function edit()
{
	if (isset($_REQUEST["form_id"])) {
		// 確認画面の「戻る」ボタンから遷移してきた場合
		$form_id = esc_attr($_REQUEST["form_id"]);

		$sample_name     = esc_attr($_REQUEST["sample_name"]);
		$sample_text     = esc_attr($_REQUEST["sample_text"]);
		$sample_check    = $_REQUEST["sample_check"];
		$sample_radio    = esc_attr($_REQUEST["sample_radio"]);
		$sample_select   = esc_attr($_REQUEST["sample_select"]);
		$sample_textarea = esc_attr($_REQUEST["sample_textarea"]);

		// チェックボックスの判定
		foreach ($sample_check as $key => $value) {
			$sample_check_checked[$value] = "checked";
		}
		
		// ラジオボタンの判定
		for ($i=0; $i<3; $i++) {
			if ($sample_radio == $i) {
				$sample_radio_checked[$i] = "checked";
			}
		}
		
		// セレクトボックスの判定
		$sample_select_array = array("a", "b", "c", "d", "e");
		foreach ($sample_select_array as $key => $value) {
			if ($sample_select == $value) {
				$sample_select_selected[$key] = "selected";
			}
		}

		$create_date = esc_attr($_REQUEST["create_date"]);

	} else {
		
		// 一覧画面から「編集」ボタンを押下した場合
		
		// 押されたボタンのIDを取得する
		if (array_search("編集", $_REQUEST["submit"]["edit"])) {
			$form_id = array_search("編集", $_REQUEST["submit"]["edit"]);
		}

		global $wpdb;
		$tbl_name = $wpdb->prefix . 'sample_mst';
		$sql = "SELECT * FROM {$tbl_name} WHERE id = %d;";
		$prepared = $wpdb->prepare($sql, $form_id);
		$rows = $wpdb->get_results($prepared, ARRAY_A);

		$sample_name     = $rows[0]["sample_name"];
		$sample_text     = $rows[0]["sample_text"];
		$sample_check    = $rows[0]["sample_check"];
		$sample_radio    = $rows[0]["sample_radio"];
		$sample_select   = $rows[0]["sample_select"];
		$sample_textarea = $rows[0]["sample_textarea"];

		$sample_check = explode(",", $sample_check);

		// チェックボックスの判定
		foreach ($sample_check as $key => $value) {
			$sample_check_checked[$value] = "checked";
		}
		
		// ラジオボタンの判定
		for ($i=0; $i<3; $i++) {
			if ($sample_radio == $i) {
				$sample_radio_checked[$i] = "checked";
			}
		}
		
		// セレクトボックスの判定
		$sample_select_array = array("a", "b", "c", "d", "e");
		foreach ($sample_select_array as $key => $value) {
			if ($sample_select == $value) {
				$sample_select_selected[$key] = "selected";
			}
		}

		$create_date = $rows[0]["create_date"];
	}

	// データ一覧
	echo <<< EOL
<form action="" method="post">
	<h2>データ編集</h2>

	<div class="wrap">

	<table class="wp-list-table widefat striped posts">
		<tr>
			<td>ID</td>
			<td>{$form_id}</td>
		</tr>
		<tr>
			<td>NAME</td>
			<td>
				<input type="text" name="sample_name" value="{$sample_name}">
			</td>
		</tr>

		<tr>
			<td>テキスト</td>
			<td>
				<input type="text" name="sample_text" value="{$sample_text}">
			</td>
		</tr>
		<tr>
			<td>チェックボックス</td>
			<td>
				チェック値1<input type="checkbox" name="sample_check[]" value="1" {$sample_check_checked[0]}>
				チェック値2<input type="checkbox" name="sample_check[]" value="2" {$sample_check_checked[1]}>
				チェック値3<input type="checkbox" name="sample_check[]" value="3" {$sample_check_checked[2]}>
			</td>
		</tr>
		<tr>
			<td>ラジオボタン</td>
			<td>
				ラジオ値1<input type="radio" name="sample_radio" value="1" {$sample_radio_checked[0]}>
				ラジオ値2<input type="radio" name="sample_radio" value="2" {$sample_radio_checked[1]}>
				ラジオ値3<input type="radio" name="sample_radio" value="3" {$sample_radio_checked[2]}>
			</td>
		</tr>
		<tr>
			<td>セレクトボックス</td>
			<td>
				<select name="sample_select">
					<option value="a" {$sample_select_selected[0]}>選択a</option>
					<option value="b" {$sample_select_selected[1]}>選択b</option>
					<option value="c" {$sample_select_selected[2]}>選択c</option>
					<option value="d" {$sample_select_selected[3]}>選択d</option>
					<option value="e" {$sample_select_selected[4]}>選択e</option>
				</select>
			</td>
		</tr>
		<tr>
			<td>テキストエリア</td>
			<td>
				<textarea name="sample_textarea" cols="30" rows="5">{$sample_textarea}</textarea>
			</td>
		</tr>

		<tr>
			<td>登録日時</td>
			<td>{$create_date}</td>
		</tr>
	</table>

	<input type='submit' name='submit[edit_check]' class='button-primary' value='編集内容を確認する' />
	<input type='submit' name='submit[]' class='button-primary' value='戻る' />

	<input type="hidden" name="form_id" value="{$form_id}">
	<input type="hidden" name="create_date" value="{$create_date}">

	</div>

</form>
EOL;
}

変更した箇所は、一覧画面から該当のデータを選択した際、チェックボックス、ラジオボタン、セレクトボックスのそれぞれの値がうまくセットされなかったので、次のように記述し、処理を追加しました。

// チェックボックスの判定
foreach ($sample_check as $key => $value) {
	if ($value != "") {
		$sample_check_checked[$key] = "checked";
	}
}

// ラジオボタンの判定
for ($i=0; $i<3; $i++) {
	if ($sample_radio == $i) {
		$sample_radio_checked[$i] = "checked";
	}
}

// セレクトボックスの判定
$sample_select_array = array("a", "b", "c", "d", "e");
foreach ($sample_select_array as $key => $value) {
	if ($sample_select == $value) {
		$sample_select_selected[$key] = "selected";
	}
}

こうすることにより、既存のデータをフォームにセットすることができるようになります。
フォーム関連の書き方はこの限りではないので、もっとうまい書き方や、効率的な書き方、ライブラリを使った書き方など、数多くの方法があると思われます。
そこはおいおいの研究課題にします。

編集の一連の動作は、次のような画面になります。

■編集一覧

■編集ボタン押下後

■値の変更

■編集確認画面

■編集実行画面

これで修正画面の一連の動作ができるようになったので、次は詳細画面、削除画面へとりかかっていきます。

編集画面の確認画面を作成する

Posted コメントするカテゴリー: WordPress

前回作成した修正画面に対して、確認画面を拡張します。

これまでは、確認画面に「sample_text」の項目1つだけしかありませんでしたが、ここに「テキスト」「チェックボックス」「ラジオボタン「セレクトボックス」「テキストエリア」の項目を追加します。

修正画面と、修正確認画面のメソッドを変更したソース全体を記載します。

    /**
     * 修正
     */
    function edit()
    {
        if (isset($_REQUEST["form_id"])) {
            //確認画面の「戻る」ボタンから遷移してきた場合
            $form_id = esc_attr($_REQUEST["form_id"]);

            $sample_name = esc_attr($_REQUEST["sample_name"]);
            $sample_text = esc_attr($_REQUEST["sample_text"]);
            $sample_check = $_REQUEST["sample_check"];
            $sample_radio = esc_attr($_REQUEST["sample_radio"]);
            $sample_select = esc_attr($_REQUEST["sample_select"]);
            $sample_textarea = esc_attr($_REQUEST["sample_textarea"]);

            //チェックボックスの判定
            foreach ($sample_check as $key => $value) {
                if ($value != "") {
                    $sample_check_checked[$key] = "checked";
                }
            }
            
            //ラジオボタンの判定
            for ($i=0; $i<3; $i++) {
                if ($sample_radio == $i) {
                    $sample_radio_checked[$i] = "checked";
                }
            }
            
            //セレクトボックスの判定
            $sample_select_array = array("a", "b", "c", "d", "e");
            foreach ($sample_select_array as $key => $value) {
                if ($sample_select == $value) {
                    $sample_select_selected[$key] = "selected";
                }
            }

            $create_date = esc_attr($_REQUEST["create_date"]);
        } else {
            
            //一覧画面から「編集」ボタンを押下した場合
            
            //押されたボタンのIDを取得する
            if (array_search("編集", $_REQUEST["submit"]["edit"])) {
                $form_id = array_search("編集", $_REQUEST["submit"]["edit"]);
            }

            global $wpdb;
            $tbl_name = $wpdb->prefix . 'sample_mst';
            $sql = "SELECT * FROM {$tbl_name} WHERE id = %d;";
            $prepared = $wpdb->prepare($sql, $form_id);
            $rows = $wpdb->get_results($prepared, ARRAY_A);

            $sample_name = $rows[0]["sample_name"];
            $sample_text  = $rows[0]["sample_text "];
            $sample_check  = $rows[0]["sample_check "];
            $sample_radio  = $rows[0]["sample_radio "];
            $sample_select  = $rows[0]["sample_select "];
            $sample_textarea = $rows[0]["sample_textarea"];

            $create_date = $rows[0]["create_date"];
        }

        //データ一覧
        echo <<< EOL
<form action="" method="post">
    <h2>データ編集</h2>

    <div class="wrap">

    <table class="wp-list-table widefat striped posts">
        <tr>
            <td>ID</td>
            <td>{$form_id}</td>
        </tr>
        <tr>
            <td>NAME</td>
            <td>
                <input type="text" name="sample_name" value="{$sample_name}">
            </td>
        </tr>

        <tr>
            <td>テキスト</td>
            <td>
                <input type="text" name="sample_text" value="{$sample_text}">
            </td>
        </tr>
        <tr>
            <td>チェックボックス</td>
            <td>
                チェック値1<input type="checkbox" name="sample_check[]" value="1" {$sample_check_checked[0]}>
                チェック値2<input type="checkbox" name="sample_check[]" value="2" {$sample_check_checked[1]}>
                チェック値3<input type="checkbox" name="sample_check[]" value="3" {$sample_check_checked[2]}>
            </td>
        </tr>
        <tr>
            <td>ラジオボタン</td>
            <td>
                ラジオ値1<input type="radio" name="sample_radio" value="1" {$sample_radio_checked[0]}>
                ラジオ値2<input type="radio" name="sample_radio" value="2" {$sample_radio_checked[1]}>
                ラジオ値3<input type="radio" name="sample_radio" value="3" {$sample_radio_checked[2]}>
            </td>
        </tr>
        <tr>
            <td>セレクトボックス</td>
            <td>
                <select name="sample_select">
                    <option value="a" {$sample_select_selected[0]}>選択a</option>
                    <option value="b" {$sample_select_selected[1]}>選択b</option>
                    <option value="c" {$sample_select_selected[2]}>選択c</option>
                    <option value="d" {$sample_select_selected[3]}>選択d</option>
                    <option value="e" {$sample_select_selected[4]}>選択e</option>
                </select>
            </td>
        </tr>
        <tr>
            <td>テキストエリア</td>
            <td>
                <textarea name="sample_textarea" cols="30" rows="5">{$sample_textarea}</textarea>
            </td>
        </tr>

        <tr>
            <td>登録日時</td>
            <td>{$create_date}</td>
        </tr>
    </table>

    <input type='submit' name='submit[edit_check]' class='button-primary' value='編集内容を確認する' />
    <input type='submit' name='submit[]' class='button-primary' value='戻る' />

    <input type="hidden" name="form_id" value="{$form_id}">
    <input type="hidden" name="create_date" value="{$create_date}">

    </div>

</form>
EOL;
    }

    /**
     * 編集確認
     */
    function edit_check()
    {
        $form_id = esc_attr($_REQUEST["form_id"]);
        $sample_name = esc_attr($_REQUEST["sample_name"]);

        $sample_text = esc_attr($_REQUEST["sample_text"]);
        $sample_check = esc_attr($_REQUEST["sample_check"]);
        $sample_radio = esc_attr($_REQUEST["sample_radio"]);
        $sample_select = esc_attr($_REQUEST["sample_select"]);
        $sample_textarea = esc_attr($_REQUEST["sample_textarea"]);

        $create_date = esc_attr($_REQUEST["create_date"]);

        if (!strlen($sample_name)) {
            echo _e('NAMEが未入力です');
        }

        //チェックボックスの値を処理
        if (is_array($_REQUEST["sample_check"])) {
            foreach ($_REQUEST["sample_check"] as $key => $value) {
                $disp_checkbox .= "チェック値" . $value . "<br />";
                $hidden_checkbox .= '<input type="hidden" name="sample_check[]" value="' . $value . '">';
            }
        }

        //テキストエリア整形(表示用)
        $sample_textarea_disp = nl2br($sample_textarea);

        //データ一覧
        echo <<< EOL
<form action="" method="post">
    <h2>データ編集確認</h2>

    <div class="wrap">

        <table class="wp-list-table widefat striped posts">
            <tr> 
                <td>ID</td>
                <td>{$form_id}</td>
            </tr>
            <tr> 
                <td>NAME</td>
                <td>{$sample_name}</td>
            </tr>
            <tr> 
                <td>テキスト</td>
                <td>{$sample_text}</td>
            </tr>
            <tr> 
                <td>チェックボックス</td>
                <td>
                    {$disp_checkbox}
                </td>
            </tr>
            <tr> 
                <td>ラジオボタン</td>
                <td>{$sample_radio}</td>
            </tr>
            <tr> 
                <td>セレクトボックス</td>
                <td>{$sample_select}</td>
            </tr>
            <tr> 
                <td>テキストエリア</td>
                <td>{$sample_textarea}</td>
            </tr>
        </table>

    <input type="hidden" name="form_id" value="{$form_id}">

    <input type="hidden" name="sample_name" value="{$sample_name}">
    <input type="hidden" name="sample_text" value="{$sample_text}">
    {$hidden_checkbox}
    <input type="hidden" name="sample_radio" value="{$sample_radio}">
    <input type="hidden" name="sample_select" value="{$sample_select}">
    <input type="hidden" name="sample_textarea" value="{$sample_textarea_disp}">

    <input type="hidden" name="create_date" value="{$create_date}">

    <input type='submit' name='submit[edit_exec]' class='button-primary' value='編集する' />
    <input type='submit' name='submit[edit]' class='button-primary' value='戻る' />

    </div>

</form>
EOL;
    }

値のチェック方法や、受け渡しの方法など、細かい箇所は修正する必要があると思いますが、全体の入力→確認への流れはこのような形で作りました。

これを実行すると、次のような入力画面と確認画面になります。

まず、一覧画面になります。

次に、一覧画面から「編集」を選択したデータを表示します。

編集内容を入力します。

「編集内容を確認する」ボタンを押下すると、確認画面に入力した値が表示されます。

確認画面から「戻る」ボタンを押しても、入力値を保持したまま、前画面へ遷移することもできます。

編集画面の管理項目を追加する

Posted コメントするカテゴリー: WordPress

前回追加したテーブルの値を編集する為に、管理画面の「編集時」の表示を変更します。

これまでは「NAME」という値の編集しかできませんでしたが、
ここに管理項目として「テキスト」「チェックボックス」「ラジオボタン」「セレクトボックス」「テキストエリア」という項目を追加します。

修正時のメソッド全体は以下のようになります。

	/**
	 * 修正
	 */
	function edit()
	{

		if (isset($_REQUEST["form_id"])) {
			$form_id = esc_attr($_REQUEST["form_id"]);
			$sample_name = esc_attr($_REQUEST["sample_name"]);
			$create_date = esc_attr($_REQUEST["create_date"]);
		} else {
			//押されたボタンのIDを取得する
			if (array_search("編集", $_REQUEST["submit"]["edit"])) {
				$form_id = array_search("編集", esc_attr($_REQUEST["submit"]["edit"]));
			}

			global $wpdb;

			$tbl_name = $wpdb->prefix . 'sample_mst';
			$sql = "SELECT * FROM {$tbl_name} WHERE id = %d;";
			$prepared = $wpdb->prepare($sql, $form_id);
			$rows = $wpdb->get_results($prepared, ARRAY_A);

			$sample_name = $rows[0]["sample_name"];

			$sample_text  = $rows[0]["sample_text "];
			$sample_check  = $rows[0]["sample_check "];
			$sample_radio  = $rows[0]["sample_radio "];
			$sample_select  = $rows[0]["sample_select "];
			$sample_textarea = $rows[0]["sample_textarea"];

			$create_date = $rows[0]["create_date"];
		}

		//データ一覧
		echo <<< EOL
<form action="" method="post">
	<h2>データ編集</h2>

	<div class="wrap">

	<table class="wp-list-table widefat striped posts">
		<tr>
			<td>ID</td>
			<td>{$form_id}</td>
		</tr>
		<tr>
			<td>NAME</td>
			<td>
				<input type="text" name="sample_name" value="{$sample_name}">
			</td>
		</tr>

		<tr>
			<td>テキスト</td>
			<td>
				<input type="text" name="sample_text" value="{$sample_text}">
			</td>
		</tr>
		<tr>
			<td>チェックボックス</td>
			<td>
				チェック値1<input type="checkbox" name="sample_check" value="1">
				チェック値2<input type="checkbox" name="sample_check" value="2">
				チェック値3<input type="checkbox" name="sample_check" value="3">
			</td>
		</tr>
		<tr>
			<td>ラジオボタン</td>
			<td>
				ラジオ値1<input type="radio" name="sample_radio" value="1">
				ラジオ値2<input type="radio" name="sample_radio" value="2">
				ラジオ値3<input type="radio" name="sample_radio" value="3">
			</td>
		</tr>
		<tr>
			<td>セレクトボックス</td>
			<td>
				<select name="sample_select">
					<option value="a">選択a</option>
					<option value="b">選択b</option>
					<option value="c">選択c</option>
					<option value="d">選択d</option>
					<option value="e">選択e</option>
				</select>
			</td>
		</tr>
		<tr>
			<td>テキストエリア</td>
			<td>
				<textarea name="sample_textarea" cols="30" rows="5">{$sample_textarea}</textarea>
			</td>
		</tr>

		<tr>
			<td>登録日時</td>
			<td>{$create_date}</td>
		</tr>
	</table>

	<input type='submit' name='submit[edit_check]' class='button-primary' value='編集内容を確認する' />
	<input type='submit' name='submit[]' class='button-primary' value='戻る' />

	<input type="hidden" name="form_id" value="{$form_id}">
	<input type="hidden" name="create_date" value="{$create_date}">

	</div>

</form>
EOL;
	}

上記のように書くと、画面は以下のように表示されます。

この増やした項目に対して、登録や修正を行えるようにしていきます。

管理項目を追加する

Posted コメントするカテゴリー: WordPress

これまで作ってきたプラグインは、項目が「sample_name」という1つの項目だけを取り扱ってきました。

今後は、sample_nameという項目以外にも、チェックボックス、ラジオボタン、セレクトボックス、テキストエリア、を取り扱う管理画面を作ってみるので、プラグインインストール時に実行されるテーブル作製のcreate table文を拡張してみます。

これまでは、以下のcreate文です。

CREATE TABLE {$table_name} (
id				INT NOT NULL AUTO_INCREMENT,
sample_name		VARCHAR(128),
create_date		DATETIME,
PRIMARY KEY(id)
) {$charset_collate};

これを、次のように拡張します。

CREATE TABLE {$table_name} (
id              INT NOT NULL AUTO_INCREMENT,
sample_name     VARCHAR(128),
sample_text     VARCHAR(256),
sample_check    VARCHAR(256),
sample_radio    VARCHAR(256),
sample_select   VARCHAR(256),
sample_textarea text,
create_date     DATETIME,
PRIMARY KEY(id)
) {$charset_collate};

実行されるタイミングはプラグインをインストールした時に一度実行されるので、メソッド全体では次のようになります。

/**
 * プラグインインストール時
 */
function create_tables_sample_mst()
{
    global $wpdb;

    $charset_collate = "";

    //接頭辞の追加(socal_count_cache)
    $table_name = $wpdb->prefix . 'sample_mst';

    //charsetを指定する
    if (!empty($wpdb->charset)) {
        $charset_collate = "DEFAULT CHARACTER SET {$wpdb->charset} ";
    }

    //照合順序を指定する(ある場合、通常デフォルトのutf8_general_ci)
    if (!empty($wpdb->collate)) {
        $charset_collate .= "COLLATE {$wpdb->collate}";
    }

    $sql = <<< EOL
CREATE TABLE {$table_name} (
id              INT NOT NULL AUTO_INCREMENT,
sample_name     VARCHAR(128),
sample_text     VARCHAR(256),
sample_check    VARCHAR(256),
sample_radio    VARCHAR(256),
sample_select   VARCHAR(256),
sample_textarea text,
create_date     DATETIME,
PRIMARY KEY(id)
) {$charset_collate};
EOL;

    //dbDeltaを実行する為に必要
    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    dbDelta($sql);

    $sample_name = 'テストデータ';

    $table_name = $wpdb->prefix . 'sample_mst';

    $wpdb->insert(
        $table_name,
        array(
            'sample_name' => $sample_name,
            'create_date' => current_time('mysql')
        ) 
    );
}

次回以降、この追加した項目に対して、「登録」「修正」「削除」「詳細」ができるように、管理画面を拡張していきます。

管理画面のテーブル件数に応じて、ページングする

Posted 3件のコメントカテゴリー: WordPress

前回まで作った管理テーブルに対し、データ件数が増えてきた場合を想定して、ページング処理を入れます。

前回までの、テーブル一覧部分のコードは以下のとおりです。

	/**
	 * 初期表示
	 */
	function disp()
	{
		//データ一覧
		echo <<< EOL
<form action="" method="post">

	<h2>データ一覧</h2>
	<input type='submit' name='submit[regist]' class='button-primary' value='新規登録' />

	<div class="wrap">

	<table class="wp-list-table widefat striped posts">
		<tr>
			<th nowrap>ID</th>
			<th nowrap>名前</th>
			<th nowrap>登録日時</th>
			<th nowrap>詳細</th>
			<th nowrap>編集</th>
		</tr>
EOL;

		global $wpdb;

		$tbl_name = $wpdb->prefix . 'sample_mst';
		$sql = "SELECT * FROM {$tbl_name} ORDER BY id;";
		$rows = $wpdb->get_results($sql);

		foreach($rows as $row) {
			echo "<tr>";
			echo "<td>" . $row->id . "</td>";
			echo "<td>" . $row->sample_name . "</td>";
			echo "<td>" . $row->create_date . "</td>";
			echo "<td>";
			echo "<input type='submit' name='submit[detail][" . $row->id . "]'";
			echo " class='button-primary' value='詳細' />";
			echo "</td>";
			echo "<td>";
			echo "<input type='submit' name='submit[edit][" . $row->id . "]'";
			echo " class='button-primary' value='編集' />";
			echo "</td>";
			echo "</tr>";
		}
		echo "</table>";
		echo "</div>";
		echo "</form>";
	}

このコードに対し、ページ処理を入れていきます。

まず、現在のページ番号をGETパラメータで受け渡す為、パラメータ取得用の変数を用意し、取得します。

$pageid = filter_input(INPUT_GET, 'pageid');

次に、1ページあたり、何件表示して次のページに移るのか、上限を決定します。

//1ページあたりの件数
$limit = 10;

次に、対象となるデータの総件数を取得します

//DBオブジェクトを用意
global $wpdb;

//全件数取得
$tbl_name = $wpdb->prefix . 'sample_mst';
$sql = "SELECT count(*) AS CNT FROM {$tbl_name}";
$rows = $wpdb->get_results($sql);
$recordcount = $rows[0]->CNT;

ここで、$recordcountという変数に総件数が格納されます。

次に、ページ遷移した時に、データベースからオフセットした値を取得する為に、SQL用にoffset値を決定します。

//offsetの値を決定
$offset = $pageid * $limit;

最後に、データベースにクエリを発行し、データを取得します。
ここのタイミングではlimit件数(10件ごと)にデータを区切って取得しています。

//offset と limitによる画面表示用のデータ取得
$sql = "SELECT * FROM {$tbl_name} ORDER BY id limit {$offset}, {$limit};";

//通常の取得方法(SQL実行結果を、オブジェクトとして取得)
$rows = $wpdb->get_results($sql);

次にページ処理用のメソッドと、それに応じたパラメータを書いておきます。

$args = array(
	'label' => __('Per Page'),
	'default' => 10,
	'option' => 'disp'
);
$page_html = self::pagination($recordcount);

paginationというメソッド名は、function disp()の外側の任意の箇所に記述します。

function pagination($recordcount)
{
	$count = $recordcount;
	$limit = 10;

	//レコード総数がゼロのときは何も出力しない
	if (0 === $count) {
		return '';
	}

	//現在表示中のページ番号(ゼロスタート)
	$intCurrentPage = self::getCurrentPage();

	//ページの最大数
	$intMaxpage = ceil($count / $limit);

	//現在ページの前後3ページを出力
	$intStartpage = (2 < $intCurrentPage) ? $intCurrentPage - 3 : 0;
	$intEndpage = (($intStartpage + 7) < $intMaxpage) ? $intStartpage + 7 : $intMaxpage;

	//url組み立て
	$urlparams = filter_input_array(INPUT_GET);

	$items = [];

	//ページURLの生成
	//最初
	$urlparams['page'] = filter_input(INPUT_GET, 'page');
	$urlparams['pageid'] = 0;
	$items[] = sprintf('<span><a href="?%s">%s</a></span>'
		, http_build_query($urlparams)
		, '最初'
	);

	//表示中のページが先頭ではない時
	if (0 < $intCurrentPage) {
		$urlparams['pageid'] = $intCurrentPage - 1;
		$items[] = sprintf('<span><a href="?%s">%s</a></span>'
			, http_build_query($urlparams)
			, '前へ'
		);
	}

	for ($i = $intStartpage; $i < $intEndpage; $i++) {
		$urlparams['pageid'] = $i;
		$items[] = sprintf('<span%s><a href="?%s">%s</a></span>'
			, ($intCurrentPage == $i) ? ' class="current"' : ''
			, http_build_query($urlparams)
			, $i + 1
		);
	}

	//表示中のページが最後ではない時
	if ($intCurrentPage < ($intMaxpage - 1)) {
		$urlparams['pageid'] = $intCurrentPage + 1;
		$items[] = sprintf('<span><a href="?%s">%s</a></span>'
			, http_build_query($urlparams)
			, '次へ'
		);
	}

	//最後
	$urlparams['pageid'] = $intMaxpage - 1;
	$items[] = sprintf('<span><a href="?%s">%s</a></span>'
		, http_build_query($urlparams)
		, '最後'
	);

	return $items;
}

最終的に、$page_htmlという変数に、ページング出力用の情報が入るので、それを画面出力用に整形して、出力します。

//ページ部分の表示
echo "<div class='admin_pagination'>";
echo "<ul>";
foreach ($page_html as $key => $value) {
	echo "<li>" . $value . "</li>";
}
echo "</ul>";

このままでは、文字列のみのページ表示になるので、cssでスタイルを調整します。

/* ページング処理 */
.admin_pagination ul li {
	display: inline-block;
	padding: 0px 1px 0px 1px;
	margin: 0px 3px 0px 3px;
	background-color: #DBDBDB;
}
.admin_pagination ul li .current a{
	color: #FFFFFF;
	background-color: #666666;
}
.admin_pagination ul a {
	display: block;
	padding: 8px 10px 8px 10px;
}

これで、テーブルに関連するページング処理の表示ができました。

出力結果は以下のようになります。

試しに3ページ目にアクセスする。

このように表示されます。

作っている最中に、気づきが遅かった部分がありました。
$wpdbのオブジェクトに対し、get_resultsメソッドを使ったSQL実行で、
offset、limitの処理を書いた場合、一般的なSQLの書き方では、
思うような抽出結果が得られませんでした。

SELECT * FROM テーブル名 OFFSET 10 LIMIT 5;

などと書くのはNGで、

SELECT * FROM テーブル名 LIMIT 10, 5;

のように書かないと、想定した出力結果が得られませんでした。
wpdbのget_resultsの仕様ページを見たのですが、明確な記載はありませんでした。
気づくまでに時間がかかってしまいました。

(2022/07/21 追記)
下記の箇所に不具合がありましたので、修正したコードに更新しました。
if文の「$intMaxpage」について、ページ遷移の仕方によっては不正な条件判定でしたので「($intMaxpage – 1)」という調整をしています。
根本的な対処とは言えませんが、訂正いたします。

■変更前

	//表示中のページが最後ではない時
	if ($intCurrentPage < $intMaxpage) {
		$urlparams['pageid'] = $intCurrentPage + 1;
		$items[] = sprintf('<span><a href="?%s">%s</a></span>'
			, http_build_query($urlparams)
			, '次へ'
		);
	}

■変更後

	//表示中のページが最後ではない時
	if ($intCurrentPage < ($intMaxpage - 1)) {
		$urlparams['pageid'] = $intCurrentPage + 1;
		$items[] = sprintf('<span><a href="?%s">%s</a></span>'
			, http_build_query($urlparams)
			, '次へ'
		);
	}

(2022/07/22 追記)
記載したソースコードの中で呼ばれているメソッド「getCurrentPage」の中身については、下記のメソッドになります。

/**
 * 現在のページ番号を取得する
 * @return int
 */
function getCurrentPage()
{
    $pageid = esc_attr($_REQUEST["pageid"]);
    return $pageid;
}

管理画面の全体に独自cssを読み込んでstyleを適用する

Posted コメントするカテゴリー: WordPress

管理画面全体に対して、独自に用意したcssファイルを読み込ませます。

有効化しているテーマのディレクトリの直下に、独自cssファイルを配置します。

有効化しているディレクトリの場所は以下のようになります。

/ワードプレス設置ディレクトリ/wp-content/themes/有効化しているディレクトリ/

ここに、独自cssとして、「my_admin_style.css」を用意する(ファイル名は任意でOKです。

/ワードプレス設置ディレクトリ/wp-content/themes/有効化しているディレクトリ/my_admin_style.css

このように配置します。

次に、テーマディレクトリ直下のfunctions.phpを編集します。
ファイルの一番した等に次のように記述します。

//管理画面に独自CSSファイルを読み込ませる
function my_admin_style()
{
    wp_enqueue_style( 'my_admin_style', get_template_directory_uri().'/my_admin_style.css' );
}
add_action( 'admin_enqueue_scripts', 'my_admin_style' );

ここでポイントとなるのは、追加したcssファイル名「my_admin_style」と同じ要素でadd_actionを記述することです。

これで、管理画面を再読み込みすると、cssが適用されます。

管理画面のテーブルにstyleをかけて見やすくする

Posted コメントするカテゴリー: WordPress

管理画面のデータ一覧表示部分のテーブルが味気のないものだったので、簡単なstyleを記述して少し見やすくしました。

style適用前は以下のような画面でしたが、以下のような表示になっています。

この表示にstyleを適用して見やすくします。

まずは、tableタグを次のようなdivタグで囲います。

<div class="wrap">

次に、tableタグに次のようなクラスを記述します。

class="wp-list-table widefat striped posts"

最後にwrapで囲んだdivを閉じます。

tableを使っている箇所でstyleを整えたいところに適宜、記述していくとよいかと思います。

最初に画面を調整した結果、表示する関数全体としては以下のようになりました。

function disp()
{
    //データ一覧
    echo <<< EOL
<form action="" method="post">

<h2>データ一覧</h2>
<input type='submit' name='submit[regist]' class='button-primary' value='新規登録' />

<div class="wrap">

<table class="wp-list-table widefat striped posts">
    <tr>
        <th nowrap>ID</th>
        <th nowrap>名前</th>
        <th nowrap>登録日時</th>
        <th nowrap>詳細</th>
        <th nowrap>編集</th>
    </tr>
EOL;

    global $wpdb;

    $tbl_name = $wpdb->prefix . 'sample_mst';
    $sql = "SELECT * FROM {$tbl_name} ORDER BY id;";
    $rows = $wpdb->get_results($sql);

    foreach($rows as $row) {
        echo "<tr>";
        echo "<td>" . $row->id . "</td>";
        echo "<td>" . $row->sample_name . "</td>";
        echo "<td>" . $row->create_date . "</td>";
        echo "<td>";
        echo "<input type='submit' name='submit[detail][" . $row->id . "]'";
        echo " class='button-primary' value='詳細' />";
        echo "</td>";
        echo "<td>";
        echo "<input type='submit' name='submit[edit][" . $row->id . "]'";
        echo " class='button-primary' value='編集' />";
        echo "</td>";
        echo "</tr>";
    }
    echo "</table>";
    echo "</div>";
    echo "</form>";
}

表示される結果は次のようになります。

少しだけ、おしゃれになりました。

プラグインをショートコード化する

Posted コメントするカテゴリー: WordPress

これまでに作ったプラグインは主に管理画面での操作用に作ってきました。

大まかな動きとしては、DBの登録/修正/削除が管理画面からできていましたが、今度はそれをユーザ画面側に表示することを行います。

ユーザ画面側では、「投稿」「固定ページ」へ自由に表示する為に「ショートコード」という書き方をすることで、DBの値を表示することができます。

これまでに作ったプラグインの中身を表示する為に、以下のような書き方をします。
(便宜上、プラグインプログラムの一番下に書き足します)

/**
 * ショートコード
 */
function samplelistFunction()
{
	//データ一覧
	$disp_html =<<< EOL
<form action="" method="post">
<h2>データ一覧(ショートコードテスト)</h2>
<table>
	<tr>
		<th nowrap>ID</th>
		<th nowrap>名前</th>
		<th nowrap>登録日時</th>
	</tr>
EOL;

	global $wpdb;

	$tbl_name = $wpdb->prefix . 'sample_mst';
	$sql = "SELECT * FROM {$tbl_name} ORDER BY id;";
	$rows = $wpdb->get_results($sql);

	foreach($rows as $row) {

$disp_html .=<<<EOL
	<tr>
		<td>{$row->id}</td>
		<td>{$row->sample_name}</td>
		<td>{$row->create_date}</td>
		<td>
	</tr>
EOL;
	}

	$disp_html .=<<< EOL
	</table>
	</form>
EOL;

	return $disp_html;
}

//「[samplelist]という記述を投稿画面や固定ページに記述する」
add_shortcode('samplelist', 'samplelistFunction');

上記の書き方をすることにより、投稿画面から新規記事投稿時に、本文内にショートコードタグ

[samplelist]

を記述すると、その部分にDBアクセスした一覧表示テーブルを表示することができます。

色々と応用することができますが、まずは表示できるところまでで、一区切りとします。

新規登録時に入力値チェックを行う

Posted コメントするカテゴリー: WordPress

データの更新系を考えてみます。

データを更新する場合、当然のように入力値をチェックしないと、整合性が取れないデータがユーザからの入力されてしまいます。

今回はデータの新規登録時に値をチェックする仕組みを入れてみます。

まずは、データをチェックするタイミングを考えます。
新規登録からデータを登録する「登録内容を確認する」(下記、画像ファイルを参照)というボタンを押した時の動作をきっかけにチェックを入れます。

次にソース上で、そのボタンが押された箇所の処理をみます。

    /**
     * 登録確認
     */
    function regist_check()
    {
        $sample_name = $_REQUEST["sample_name"];

        //データ一覧
        echo <<< EOL
<form action="" method="post">
    <h2>データ登録確認</h2>
<table border="1">
    <tr>
        <td>NAME</td>
        <td>{$sample_name}</td>
    </tr>
</table>

<input type="hidden" name="sample_name" value="{$sample_name}">

<input type='submit' name='submit[regist_exec]' class='button-primary' value='登録する' />
<input type='submit' name='submit[regist]' class='button-primary' value='戻る' />
EOL;
        echo "</form>";
    }

単純に入力画面で入力した文字列をそのまま変数に代入して、確認画面を出していることがわかります。

このままでは空白や、危険な文字列が入力された場合に、意図しない動作になってしまいます。

次のように修正します。

    /**
     * 登録確認
     */
    function regist_check()
    {
        //入力値が空白の場合の処理(ここでは単純に0バイトだったら)
        if (!strlen($_REQUEST["sample_name"])) {
            self::regist(false);
            return;
        }
        
        $sample_name = esc_attr($_REQUEST["sample_name"]);

        //データ一覧
        echo <<< EOL
<form action="" method="post">
    <h2>データ登録確認</h2>
<table border="1">
    <tr>
        <td>NAME</td>
        <td>{$sample_name}</td>
    </tr>
</table>

<input type="hidden" name="sample_name" value="{$sample_name}">

<input type='submit' name='submit[regist_exec]' class='button-primary' value='登録する' />
<input type='submit' name='submit[regist]' class='button-primary' value='戻る' />
EOL;
        echo "</form>";
    }

チェック方法が少し荒っぽいですが、未入力チェックと、< > & ” ‘ (小なり、大なり、アンパサンド、ダブルクォート、シングルクォート) 文字参照をエンコードする関数「esc_attr」を処理に入れています。

また、もし入力された値が空白だった場合「self::regist(false)」という形で、また登録画面を呼び出しています。

引数にfalseを渡し、チェック時に何が起きたのかを新規登録画面へ伝えます。

新規登録画面側の処理は、以下のように修正します。

    /**
     * 登録
     */
    function regist($error_message_flg = null)
    {
        if ($error_message_flg !== false) {
            $sample_name = esc_attr($_REQUEST["sample_name"]);
        }

        echo <<< EOL
<form action="" method="post">
    <h2>データ登録</h2>
EOL;

        //エラーメッセージのフラグがfalseの場合、メッセージを表示する
        if ($error_message_flg == false) {
            echo "<div class='updated fade'><p><strong>";
            echo _e('NAMEを入力してください');
            echo "</strong></p></div>";
        }

        echo <<< EOL
    <table border="1">
        <tr>
            <td>NAME</td>
            <td>
                <input type="text" name="sample_name" value="{$sample_name}">
            </td>
        </tr>
    </table>

    <input type='submit' name='submit[regist_check]' class='button-primary' value='登録内容を確認する' />
    <input type='submit' name='submit[]' class='button-primary' value='戻る' />
</form>
EOL;
    }

このように処理を書くことで、未入力の場合には「NAMEを入力してください」
というメッセージが表示されるようになります。

今回は未入力チェックのみの実装でしたが、その他にも入力項目の種類に合わせたチェック方法を実装する場面が出てきます。
当然のごとくエラーの表示場所や、文言、レイアウトなどはもっと工夫する必要があります。

書き方は数多くあるので、もっと良い書き方を考えて改良する予定です。

管理画面に新規登録画面をつける

Posted コメントするカテゴリー: WordPress

前回までのプログラムに、新規登録画面を追加します。

まずは、「登録画面」「登録確認画面」「登録完了画面」の処理の為に分岐を作っておきます。
そしてそれぞれ違うメソッドを呼ぶように関数を追加。

	/**
	 * 管理画面のHTMLの生成と表示
	 */
	function sample_plugin()
	{
		if (isset($_REQUEST["submit"]["detail"])) {
			//詳細
			self::detail();
		} else if (isset($_REQUEST["submit"]["edit"])) {
			//修正
			self::edit();
		} else if (isset($_REQUEST["submit"]["edit_check"])) {
			//修正確認
			self::edit_check();
		} else if (isset($_REQUEST["submit"]["edit_exec"])) {
			//修正実行
			self::edit_exec();
		} else if (isset($_REQUEST["submit"]["delete_check"])) {
			//削除確認
			self::delete_check();
		} else if (isset($_REQUEST["submit"]["delete_exec"])) {
			//削除実行
			self::delete_exec();
		} else if (isset($_REQUEST["submit"]["regist"])) {
			//新規登録
			self::regist();
		} else if (isset($_REQUEST["submit"]["regist_check"])) {
			//新規登録確認
			self::regist_check();
		} else if (isset($_REQUEST["submit"]["regist_exec"])) {
			//新規登録
			self::regist_exec();
		} else {
			//初期表示
			self::disp();
		}
	}

次に、プログラム内の任意の箇所に、以下の関数を追加します。

	/**
	 * 登録
	 */
	function regist()
	{
		if (isset($_REQUEST["sample_name"])) {
			$sample_name = $_REQUEST["sample_name"];
		}

		echo <<< EOL
<form action="" method="post">
	<h2>データ登録</h2>
	<table border="1">
		<tr>
			<td>NAME</td>
			<td>
				<input type="text" name="sample_name" value="{$sample_name}">
			</td>
		</tr>
	</table>

	<input type='submit' name='submit[regist_check]' class='button-primary' value='登録内容を確認する' />
	<input type='submit' name='submit[]' class='button-primary' value='戻る' />
</form>
EOL;
	}

	/**
	 * 登録確認
	 */
	function regist_check()
	{
		$sample_name = $_REQUEST["sample_name"];

		//データ一覧
		echo <<< EOL
<form action="" method="post">
	<h2>データ登録確認</h2>
EOL;

		echo <<<EOL
<table border="1">
	<tr>
		<td>NAME</td>
		<td>{$sample_name}</td>
	</tr>
</table>

<input type="hidden" name="sample_name" value="{$sample_name}">

<input type='submit' name='submit[regist_exec]' class='button-primary' value='登録する' />
<input type='submit' name='submit[regist]' class='button-primary' value='戻る' />
EOL;
		echo "</form>";
	}


	/**
	 * 登録実行
	 */
	function regist_exec()
	{
		global $wpdb;

		$sample_name = $_REQUEST["sample_name"];

		//投稿を登録
		$table_name = $wpdb->prefix . 'sample_mst';
		$result = $wpdb->insert(
			$table_name,
			array(
				'sample_name' => $sample_name,
				'create_date' => current_time('mysql')
			)
		);

		//データ一覧
		echo <<< EOL
<form action="" method="post">
	<h2>データ登録</h2>
	<div class='updated fade'><p><strong>
EOL;
		echo _e('登録が完了しました');
		echo <<<EOL
</strong></p></div>
<input type='submit' name='submit[]' class='button-primary' value='戻る' />
EOL;
		echo "</form>";
	}

これで、新規登録ボタンを押した後に、登録フォーム→確認画面→完了画面へ遷移し、最後にDB内にデータを保存する流れができます。

■新規登録ボタン追加

■登録フォームの表示

■確認画面の表示

■完了画面の表示

ちなみに入力値チェックは確認画面のタイミングで書く必要がありますので、次の課題として進めます。

かなり簡単な登録画面(項目も1個のみ)ですが、文字列の登録が管理画面上から可能になりました。

詳細画面にデータ削除機能をつける

Posted コメントするカテゴリー: WordPress

作成中のプログラムに、削除機能をつけてみます。

まずは、function sample_plugin()に対して、削除確認画面と、
削除実行画面のメソッドをつけます。

	/**
	 * 管理画面のHTMLの生成と表示
	 */
	function sample_plugin()
	{
		if (isset($_REQUEST["submit"]["detail"])) {
			//詳細
			self::detail();
		} else if (isset($_REQUEST["submit"]["edit"])) {
			//修正
			self::edit();
		} else if (isset($_REQUEST["submit"]["edit_check"])) {
			//修正確認
			self::edit_check();
		} else if (isset($_REQUEST["submit"]["edit_exec"])) {
			//修正実行
			self::edit_exec();
		} else if (isset($_REQUEST["submit"]["delete_check"])) {
			//削除確認
			self::delete_check();
		} else if (isset($_REQUEST["submit"]["delete_exec"])) {
			//削除実行
			self::delete_exec();
		} else {
			//初期表示
			self::disp();
		}
	}

次に関数delete_checkとdelete_execをそれぞれ新規作成します。

削除確認画面は以下のように書きます。
これは修正確認画面の応用なので、書き方によっては同一にできるかと思います。

	/**
	 * 削除確認
	 */
	function delete_check()
	{
		$form_id = $_REQUEST["form_id"];

		global $wpdb;

		$tbl_name = $wpdb->prefix . 'sample_mst';
		$sql = "SELECT * FROM {$tbl_name} WHERE id = %d;";
		$prepared = $wpdb->prepare($sql, $form_id);
		$rows = $wpdb->get_results($prepared, ARRAY_A);

		//データ一覧
		echo <<< EOL
<form action="" method="post">
	<h2>データ削除確認</h2>
	<table border="1">
		<tr>
			<td>ID</td>
			<td>{$form_id}</td>
		</tr>
		<tr>
			<td>NAME</td>
			<td>{$rows[0]["sample_name"]}</td>
		</tr>
		<tr>
			<td>登録日時</td>
			<td>{$rows[0]["create_date"]}</td>
		</tr>
	</table>

	<input type="hidden" name="form_id" value="{$form_id}">

	<input type='submit' name='submit[delete_exec]' class='button-primary' value='削除する' />
	<input type='submit' name='submit[edit]' class='button-primary' value='戻る' />
EOL;
		echo "</form>";
	}

次に削除実行の関数を追加します。

	/**
	 * 削除実行
	 */
	function delete_exec()
	{
		$form_id = $_REQUEST["form_id"];

		//データを削除
		global $wpdb;
		$tbl_name = $wpdb->prefix . 'sample_mst';
		$sql = "DELETE FROM {$tbl_name} WHERE id = %s;";
		$dlt = $wpdb->query($wpdb->prepare($sql, $form_id));

		//データ一覧
		echo <<< EOL
<form action="" method="post">
	<h2>データ編集認</h2>
EOL;

		echo "<div class='updated fade'><p><strong>";
		echo _e('削除が完了しました');
		echo "</strong></p></div>";

		echo <<<EOL
<input type='submit' name='submit[]' class='button-primary' value='戻る' />
EOL;
		echo "</form>";
	}

上記の機能を書くことで、データ一覧画面から詳細画面→削除確認画面→削除実行の流れができています。
書き方は千差万別でもっと効率のよい書き方もあると思います。
そこは今度プラグインの調整を続けていく際に強化していきます。

管理画面にデータ編集機能をつける

Posted コメントするカテゴリー: WordPress

前回作った詳細一覧に対し、「編集」ボタンをつけて、
1レコードづつデータ編集できるようにする。

各ボタンごとにメソッドを分けて処理を書いたので、ソースは少し長めになります。
ボタンごとにname属性に違う記述(やりたい役割ごとに名称を変える)し、
そのname属性をもとにfunction sample_plugin()の中で呼び出すメソッドを分けています。

なにも押下されなかった場合は、初期表示となり、その後、詳細表示(一覧)、
編集、編集確認、編集完了、というそれぞれのメソッドを用意しています。

もっと良い書き方があると思いますが、ひとまず更新はできているのでブログ記事化します。

	/**
	 * 管理画面のHTMLの生成と表示
	 */
	function sample_plugin()
	{
		if (isset($_REQUEST["submit"]["detail"])) {
			//詳細
			self::detail();
		} else if (isset($_REQUEST["submit"]["edit"])) {
			//修正
			self::edit();
		} else if (isset($_REQUEST["submit"]["edit_check"])) {
			//修正確認
			self::edit_check();
		} else if (isset($_REQUEST["submit"]["edit_exec"])) {
			//修正実行
			self::edit_exec();
		} else {
			//初期表示
			self::disp();
		}
	}

	/**
	 * 初期表示
	 */
	function disp()
	{
		//データ一覧
		echo <<< EOL
<form action="" method="post">
	<h2>データ一覧</h2>
	<table>
		<tr>
			<th nowrap>ID</th>
			<th nowrap>名前</th>
			<th nowrap>登録日時</th>
			<th nowrap>詳細</th>
			<th nowrap>編集</th>
		</tr>
EOL;

		global $wpdb;

		$tbl_name = $wpdb->prefix . 'sample_mst';
		$sql = "SELECT * FROM {$tbl_name} ORDER BY id;";
		$rows = $wpdb->get_results($sql);

		foreach($rows as $row) {
			echo "<tr>";
			echo "<td>" . $row->id . "</td>";
			echo "<td>" . $row->sample_name . "</td>";
			echo "<td>" . $row->create_date . "</td>";
			echo "<td>";
			echo "<input type='submit' name='submit[detail][" . $row->id . "]'";
			echo " class='button-primary' value='詳細' />";
			echo "</td>";
			echo "<td>";
			echo "<input type='submit' name='submit[edit][" . $row->id . "]'";
			echo " class='button-primary' value='編集' />";
			echo "</td>";
			echo "</tr>";
		}
		echo "</table>";
		echo "</form>";
	}

	/**
	 * 詳細表示
	 */
	function detail()
	{
		//押されたボタンのIDを取得する
		if (array_search("詳細", $_REQUEST["submit"]["detail"])) {
			$form_id = array_search("詳細", $_REQUEST["submit"]["detail"]);
		}

		//データ一覧
		echo <<< EOL
<form action="" method="post">
	<h2>データ詳細</h2>
EOL;

		global $wpdb;

		$tbl_name = $wpdb->prefix . 'sample_mst';
		$sql = "SELECT * FROM {$tbl_name} WHERE id = %d;";
		$prepared = $wpdb->prepare($sql, $form_id);
		$rows = $wpdb->get_results($prepared, ARRAY_A);

		echo <<<EOL
<table border="1">
	<tr>
		<td>ID</td>
		<td>{$rows[0]["id"]}</td>
	</tr>
	<tr>
		<td>NAME</td>
		<td>{$rows[0]["sample_name"]}</td>
	</tr>
	<tr>
		<td>登録日時</td>
		<td>{$rows[0]["create_date"]}</td>
	</tr>
</table>
<input type='submit' name='submit[]' class='button-primary' value='戻る' />
EOL;
		echo "</form>";
	}

	/**
	 * 修正
	 */
	function edit()
	{
		if (isset($_REQUEST["form_id"])) {
			$form_id = $_REQUEST["form_id"];
			$sample_name = $_REQUEST["sample_name"];
			$create_date = $_REQUEST["create_date"];
		} else {
			//押されたボタンのIDを取得する
			if (array_search("編集", $_REQUEST["submit"]["edit"])) {
				$form_id = array_search("編集", $_REQUEST["submit"]["edit"]);
			}

			global $wpdb;

			$tbl_name = $wpdb->prefix . 'sample_mst';
			$sql = "SELECT * FROM {$tbl_name} WHERE id = %d;";
			$prepared = $wpdb->prepare($sql, $form_id);
			$rows = $wpdb->get_results($prepared, ARRAY_A);

			$sample_name = $rows[0]["sample_name"];
			$create_date = $rows[0]["create_date"];
		}

		//データ一覧
		echo <<< EOL
<form action="" method="post">
	<h2>データ編集</h2>
EOL;


		echo <<<EOL
<table border="1">
	<tr>
		<td>ID</td>
		<td>{$form_id}</td>
	</tr>
	<tr>
		<td>NAME</td>
		<td>
			<input type="text" name="sample_name" value="{$sample_name}">
		</td>
	</tr>
	<tr>
		<td>登録日時</td>
		<td>{$create_date}</td>
	</tr>
</table>

<input type="hidden" name="form_id" value="{$form_id}">
<input type="hidden" name="create_date" value="{$create_date}">

<input type='submit' name='submit[edit_check]' class='button-primary' value='編集内容を確認する' />
<input type='submit' name='submit[]' class='button-primary' value='戻る' />
EOL;
		echo "</form>";
	}

	/**
	 * 編集確認
	 */
	function edit_check()
	{
		$form_id = $_REQUEST["form_id"];
		$sample_name = $_REQUEST["sample_name"];
		$create_date = $_REQUEST["create_date"];

		//データ一覧
		echo <<< EOL
<form action="" method="post">
	<h2>データ編集確認</h2>
EOL;

		echo <<<EOL
<table border="1">
	<tr>
		<td>ID</td>
		<td>{$form_id}</td>
	</tr>
	<tr>
		<td>NAME</td>
		<td>{$sample_name}</td>
	</tr>
</table>

<input type="hidden" name="form_id" value="{$form_id}">
<input type="hidden" name="sample_name" value="{$sample_name}">
<input type="hidden" name="create_date" value="{$create_date}">

<input type='submit' name='submit[edit_exec]' class='button-primary' value='編集する' />
<input type='submit' name='submit[edit]' class='button-primary' value='戻る' />
EOL;
		echo "</form>";
	}

	/**
	 * 編集実行
	 */
	function edit_exec()
	{
		global $wpdb;

		$form_id = $_REQUEST["form_id"];
		$sample_name = $_REQUEST["sample_name"];
		$update_date = date("Y-m-d H:i:s");

		//投稿を更新
		$tbl_name = $wpdb->prefix . 'sample_mst';
		$result = $wpdb->update(
			$tbl_name,
			array('sample_name' => $sample_name,),
			array('id' => $form_id,),
			array('%s'),
			array('%d')
		);

		//データ一覧
		echo <<< EOL
<form action="" method="post">
	<h2>データ編集認</h2>
EOL;

		echo "<div class='updated fade'><p><strong>";
		echo _e('更新が完了しました');
		echo "</strong></p></div>";

		echo <<<EOL
<input type='submit' name='submit[]' class='button-primary' value='戻る' />
EOL;
		echo "</form>";
	}

上記のコードを実行した時の画面を張っておきます。
一覧表示から、編集、確認、完了という、一般的な編集処理ができます。

見た目のレイアウト調整については別な機会にまとめて、整理しようと思っています。
まずは確実に動くものを仕上げていきます。

■一覧画面

■ID「3」のデータの「編集」ボタンを押した時

■NAMEを「9876」に変更して「編集内容を確認する」ボタンを押した時

■「編集する」ボタンを押して、編集完了した時

管理画面に詳細画面を追加する

Posted コメントするカテゴリー: WordPress

先日追加した「function sample_plugin()」には、テーブルの値をだた一覧表示しただけでしたので、今回はその一覧から詳細画面を表示する。という部分を作ってみます。

まず、sample_plugin()という関数は以下のように書いていました。

	/**
	 * 管理画面のHTMLの生成と表示
	 */
	function sample_plugin()
	{
		echo <<< EOL
<h1>sample_plugin メインページ</h1>
ここにHTMLテンプレートを生成していきます。
EOL;

		//データ一覧
		echo <<< EOL
		<h2>データ一覧</h2>
		<table>
			<tr>
				<th nowrap>ID</th>
				<th nowrap>名前</th>
				<th nowrap>登録日時</th>
				<th nowrap>詳細</th>
			</tr>
EOL;

		global $wpdb;
		$tbl_name = $wpdb->prefix . 'sample_mst';
		$sql = "SELECT * FROM {$tbl_name} ORDER BY id;";
		$rows = $wpdb->get_results($sql);

		foreach($rows as $row) {
			echo "<tr>";
			echo "<td nowrap>" . $row->id . "</td>";
			echo "<td nowrap>" . $row->sample_name . "</td>";
			echo "<td nowrap>" . $row->create_date . "</td>";
			echo "<td nowrap>";
			echo "<input type='submit' name='submit[detail][" . $row->id . "]'";
			echo " class='button-primary' value='詳細' />";
			echo "</tr>";
		}
		echo "</table>";
	}

上記の部分を、別な関数に移し、ボタンによって表示する情報を切り替えるように改造します。

ボタンごとに画面を切り替える為、function sample_plugin()を以下のように変更しました。

/**
 * 管理画面のHTMLの生成と表示
 */
function sample_plugin()
{
	if (isset($_REQUEST["submit"]["detail"])) {
		self::detail(); //詳細
	} else if (isset($_REQUEST["submit"]["edit"])) {
		self::edit(); //修正
	} else {
		self::disp(); //初期表示
	}
}

「$_REQUEST[“submit”][“detail”]」という部分が、HTML上にあるボタンのname属性によって切り替えるポイントとなります。(詳細か編集か初期表示かを分けています)
もっと良い方法があるかもしれませんが、間違いなく動作するので、一旦これで進めます。

次に「詳細画面」を表示する為の関数function detail()を新規に書きます。

	/**
	 * 詳細表示
	 */
	function detail()
	{
		//押されたボタンのIDを取得する
		if (array_search("詳細", $_REQUEST["submit"]["detail"])) {
			$form_id = array_search("詳細", $_REQUEST["submit"]["detail"]);
		}

		//データ一覧
		echo <<< EOL
<form action="" method="post">
	<h2>データ詳細</h2>
EOL;

		global $wpdb;

		$tbl_name = $wpdb->prefix . 'sample_mst';
		$sql = "SELECT * FROM {$tbl_name} WHERE id = %d;";
		$prepared = $wpdb->prepare($sql, $form_id);
		$rows = $wpdb->get_results($prepared, ARRAY_A);

		echo <<<EOL
<table border="1">
	<tr>
		<td>ID</td>
		<td>{$rows[0]["id"]}</td>
	</tr>
	<tr>
		<td>NAME</td>
		<td>{$rows[0]["sample_name"]}</td>
	</tr>
	<tr>
		<td>登録日時</td>
		<td>{$rows[0]["create_date"]}</td>
	</tr>
</table>
<input type='submit' name='submit[]' class='button-primary' value='戻る' />
EOL;
		echo "</form>";
	}

上記の関数を用意することで、一覧表示の「詳細」ボタンを押した後に、詳細画面へ遷移し、各データの詳細を表示することが可能になります。

応用次第では、管理画面の色々な場面で編集用の画面が作れるようになります。