製品とカテゴリーを登録できるようにする – WordPressプラグインの作成 16

投稿者: | 2018年3月18日

ヘルプ項目を新規作成・編集する画面で、製品とカテゴリーを新規登録できるようにしています。製品、及びカテゴリーの新規登録が機能するよう、コードを書いていきます。

validate_edit関数の作成

編集画面でPOST送信すると、validate_edit関数が実行されるようになっています(前回、そうしました)。[製品の登録]、及び[カテゴリーの登録]ボタンを押すとPOST送信が行われるため、validate_edit関数に実際の登録処理を記述します。
validate_edit関数は、Fow_OnlineHelp_Adminクラスに追加します。コードは以下のとおりです。

    /**
     * ヘルプの編集画面のバリデーション
     * @param   string  $command    submitボタンの値
     */
    public function validate_edit($command)
    {
        global $onlinehelp_db;

        // 入力されたデータの取得
        $help['help_id'] = intval(filter_input(INPUT_POST, 'help_id', FILTER_VALIDATE_INT, ['default' => 0, 'min_range' => 0]));
        $help['title'] = filter_input(INPUT_POST, 'title');
        $help['helpbody'] = filter_input(INPUT_POST, 'helpbody');
        $help['tags'] = filter_input(INPUT_POST, 'tags');
        $help['relations'] = filter_input(INPUT_POST, 'relations');
        $help['product_id'] = intval(filter_input(INPUT_POST, 'product_id', FILTER_VALIDATE_INT, ['default' => 0, 'min_range' => 0]));
        $help['cat_id'] = intval(filter_input(INPUT_POST, 'cat_id', FILTER_VALIDATE_INT, ['default' => 0, 'min_range' => 0]));

        // submitの確認
        switch ($command) {
            case 'add-product':
                // 新規の製品名を登録する
                $new_product = filter_input(INPUT_POST, 'new_product');
                if (mb_strlen($new_product) > 0) {
                    $onlinehelp_db->insert_product($new_product);
                }

                $this->edit_data = $help;
                break;

            case 'add-category':
                // 新規のカテゴリーを登録する
                $new_category = filter_input(INPUT_POST, 'new_category');
                if (mb_strlen($new_category) > 0) {
                    $onlinehelp_db->insert_category($new_category);
                }

                $this->edit_data = $help;
                break;
        }
    }

validate_edit関数内で edit_data というフィールドを参照していますので、Fow_OnlineHelp_Admin クラスにこのフィールドを追加します(21行目)。

    /**
     * フィールド
     */
    private $edit_data;
    private $form = '';

print_admin_page関数の修正

ユーザーが製品名やカテゴリー名を入力して登録ボタンを押すと、validate_edit関数が実行され、データベースに製品名やカテゴリー名が登録されます。そのあと、再びヘルプの編集画面に戻ることになります。画面の表示は print_admin_page 関数が担っているため、ここに編集画面を再表示するコードを追加します。
print_admin_page関数に、以下のコードを追加します(77-81行目)。

        // formの値によって表示するビューを変える
        switch ($this->form) {
            case 'new':
                // 編集データの作成
                $help = $onlinehelp_lib->get_empty_help();
                require_once FOW_OH_PLUGIN_DIR . '/views/edit.php';
                break;

            case 'edit':
                // 編集データの取得
                $help = $this->edit_data;
                require_once FOW_OH_PLUGIN_DIR . '/views/edit.php';
                break;

            default:
                $items = $onlinehelp_db->fetch_helps(0, 0, $this->settings['sorted'], $this->settings['sorted-order']);

insert_category関数の作成

カテゴリーをデータベースに登録する処理は、insert_category関数で行います。データベースに直接アクセスしますので、Fow_OnlineHelp_DBクラスに追加します。コードは以下のとおりです。

    /**
     * データベースにカテゴリーを登録する
     * @param   string  $category   登録するカテゴリー
     * @return  mixed   (登録成功)登録したカテゴリーのID (登録失敗)false
     */
    public function insert_category($category)
    {
        global $wpdb;

        $table = $wpdb->prefix . Fow_OnlineHelp_Lib::FOW_OH_TABLES['category'];
        $data = [
            'cat_name' => sanitize_text_field($category),
            'created_at' => date_i18n('Y-m-d H:i:s'),
        ];

        $format = [
            '%s',
            '%s',
        ];

        if ($wpdb->insert($table, $data, $format) === false) {
            return false;
        } else {
            return $wpdb->insert_id;
        }
    }

この関数で特に注目してほしいのは、104行目です。
ウェブで取得したデータは、基本的に安全ではないと考える必要があります。悪意を持つ者が不正なデータを送信し、データベースのデータを不正に取得しようとしたり、障害を発生させようとしたりすることがあります。クロスサイトスクリプティングやSQLインジェクションという言葉を聞いたことがあると思います。
これらの攻撃を防ぐため、取得したデータは検証や無害化(サニタイズ)の必要があります。104行目で使用している sanitize_text_field 関数は、WordPressで用意されている無害化のための関数の一つで、文字列に含まれるHTMLタグや改行、余分な空白などを除去してくれます。
また、データベースへのデータ登録には $wpdbinsert 関数を使用しますが、この関数は登録するデータをエスケープ(安全な文字列へ変換)してくれます。

もう一つの注目点は、105行目の date_i18n 関数です。
date_i18n 関数は、現在の日時を文字列で取得する関数です。PHPで日時を文字列で取得する場合、通常、date 関数を使用します。しかし、WordPressでは日時が UTC 時間に設定されているため、date関数は日本時間から 9 時間ずれてしまいます。date_i18n 関数はロケールに合わせた日時を取得する関数です。日本での日時を正しく取得するには、date_i18n関数を使用します。

テーブルを作成する際、created_at フィールドのデフォルト値に現在日時を設定しています。そのため、本来 105 行目は必要ありません。しかし、私(筆者)がレンタルしているサーバーの都合で、この行を追加しています。

$wpdbinsert 関数でデータを挿入した場合、挿入されたデータのプライマリーキーのフィールドの値が、insert_id フィールドに格納されています。プライマリーキーのフィールドを自動インクリメントにしている場合、挿入された値を取得するのに利用できます。

insert_product関数の作成

製品をデータベースに登録する、insert_product関数を Fow_OnlineHelp_DB クラスに追加します。コードは以下のとおりです。

    /**
     * データベースに製品を登録する
     * @param   string  $product    登録する製品名
     * @return  mixed   (登録成功)登録した製品のID (登録失敗)false
     */
    public function insert_product($product)
    {
        global $wpdb;

        $table = $wpdb->prefix . Fow_OnlineHelp_Lib::FOW_OH_TABLES['product'];
        $data = [
            'prod_name' => sanitize_text_field($product),
            'created_at' => date_i18n('Y-m-d H:i:s'),
        ];

        $format = [
            '%s',
            '%s',
        ];

        if ($wpdb->insert($table, $data, $format) === false) {
            return false;
        } else {
            return $wpdb->insert_id;
        }
    }

以上で、製品とカテゴリーを登録できるようになりました。実際にテストしてみましょう。
なお、製品とカテゴリーは登録できるはずですが、管理画面のトップを表示してみると問題があることが分かります。次回はこの問題の修正を行います。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)