Buravo46's Note

学んだ事を書いていくブログです。

【Drupal】入力情報をデータベーステーブルに挿入するカスタムモジュールの作成

経緯

フォームから入力したデータをデータベースへ追加するようなことってどうやるんだろうと調べていて、 情報があまりなかったので書こうと思いました。

環境

OS : Windows 7 32bit

Drupal : Drupal Version 7.37

XAMPP : XAMPP Version 5.5.24

Apache : Apache Version 2.4.12

MySQL : MySQL Server Version 5.6.24

PHP : PHP Version 5.6.8

前提

下記の項目について、なんとなく理解していることを前提とします。

  1. フックについての理解
  2. カスタムモジュール作成の流れ
  3. hook_menu関数, hook_form関数, form_id_validate関数, form_id_submit関数の使い方

概要

作成するモジュール内容は、コンテンツの部分にIDと名前を入力するフォームと送信ボタンを表示するカスタムモジュールです。 送信ボタン押下時に、入力フォームが未入力もしくはIDへ数字を入力したならばエラー処理をします。 そうでない場合は、入力内容を画面へ表示しデータベースのテーブルへ入力内容を挿入するようにします。

手順

モジュールは下記の手順で作成します。

  • モジュール名.installファイルの作成

  • モジュール名.installに、モジュールをインストール時の動作を定義

    1. hook_schema関数でデータベーススキーマの情報を定義
    2. hook_install関数でモジュールインストール時の処理を定義
    3. hook_uninstall関数でモジュールアンインストール時の処理を定義
  • モジュール名.moduleに、モジュールの動作を定義

    1. form_id_validate関数で入力値の検証
    2. form_id_submit関数で送信時の処理

具体例

まずは具体例であるソースコードを表示し、後からソースコードの簡単な解説していこうと思います。

下記はモジュールの情報を定義しているモジュール名.infoファイルです。 ファイル名はexample_db_insert.infoにしています。

; モジュール名
name = Example Database Insert
; モジュールの概要
description = Example.
; Drupalコアのバージョン
core = 7.x
; パッケージ名
package = Example

下記はモジュールの動作を定義しているモジュール名.moduleファイルです。 ファイル名はexample_db_insert.moduleにしています。

<?php

/**
 * @file
 * 入力情報をデータベーステーブルに挿入するカスタムモジュール
 */

/**
 * Implements hook_menu().
 */
function example_db_insert_menu() {
  // 文字列を適切な言語へ変換
  $db_insert_title = t('Database Insert Page');
  $db_insert_description = t('入力情報をデータベーステーブルに挿入するカスタムモジュール画面');
  // 入力フォームを表示する画面のPathとアクセス時の挙動
  $items['example/db_insert'] = array(
    // ページ名
    'title' => $db_insert_title,
    // ページ概要
    'description' => $db_insert_description,
    // ユーザがページを訪問した際に呼び出されるコールバック関数
    'page callback' => 'drupal_get_form',
    // ユーザがページを訪問した際に呼び出されるコールバック関数の引数
    'page arguments' => array('example_db_insert_form'),
    // アクセス時に呼び出されるコールバック関数
    'access callback' => TRUE,
  );
  return $items;
}

/**
 * Implements hook_form().
 */
function example_db_insert_form($form, &$form_state) {
  // 文字列を適切な言語へ変換
  $form_id_title = t('Id');
  $form_name_title = t('Name');
  $form_submit_value = t('送信');
  // フォームの初期化
  $form = array();
  // ID入力フォーム
  $form['id'] = array(
    // フォームのタイプ
    '#type' => 'textfield',
    // フォームのタイトル
    '#title' => $form_id_title,
  );
  // 名前入力フォーム
  $form['name'] = array(
    // フォームのタイプ
    '#type' => 'textfield',
    // フォームのタイトル
    '#title' => $form_name_title,
  );
  // 送信ボタン
  $form['submit'] = array(
    // フォームのタイプ
    '#type' => 'submit',
    // フォームのタイトル
    '#name' => 'submit',
    // ボタンに表示される値
    '#value' => $form_submit_value,
  );
  return $form;
}

/**
 * Implements form_id_validate().
 */
function example_db_insert_form_validate($form, &$form_state) {
  // 入力されているかの検証
  if (!$form_state['values']['id'] || !$form_state['values']['name']){
    // 文字列を適切な言語へ変換
    $form_error_not_entered = t('It is not entered.');
    // 未入力ならばエラー処理
    form_set_error('submit', $form_error_not_entered);
  }
  // IDが数字を入力されているかを検証
  else if(!ctype_digit($form_state['values']['id'])) {
    // 文字列を適切な言語へ変換
    $form_error_not_type = t('It is not type of ID.');
    // IDに数字以外を入力されていたならばエラー処理
    form_set_error('submit', $form_error_not_type);
  }
  // Nameの文字数が255を超えているかを検証
  else if(strlen($form_state['values']['name']) >= 255) {
    // 文字列を適切な言語へ変換
    $form_error_over_chara = t('It is over name.');
    // Nameの文字数が255を超えていたならばエラー処理
    form_set_error('submit', $form_error_over_chara);
  }
}

/**
 * Implements form_id_submit().
 */
function example_db_insert_form_submit($form, &$form_state) {
  // 文字列を適切な言語へ変換
  $form_values_id = t('ID : @id', array('@id' => $form_state['values']['id']));
  $form_values_name = t('Name : @name', array('@name' => $form_state['values']['name']));
  // 文字の表示
  drupal_set_message($form_values_id);
  drupal_set_message($form_values_name);
  // データベーステーブルへの挿入
  db_insert('example_db_insert_table')
  ->fields(array(
    // カラムにデータを挿入
    'id' => $form_state['values']['id'],
    'name' => $form_state['values']['name'],
  ))
  ->execute();
}

下記はモジュールのインストール、アンインストール時の動作を定義しているモジュール名.installファイルです。 ファイル名はexample_db_insert.installにしています。

<?php

/**
 * @file
 * インストールまたはアンインストール時に定義した動作を処理するインストールファイル
 */

/**
 * Implements hook_install().
 */
function example_db_insert_install() {
  // テーブルが存在していなければ処理
  if (!db_table_exists('example_db_insert_table')){
    // テーブルの作成
    drupal_install_schema('example_db_insert');
  }
}

/**
 * Implements hook_uninstall().
 */
function example_db_insert_uninstall() {
// テーブルが存在していたら処理
  if (db_table_exists('example_db_insert_table')){
    // テーブルの削除
    drupal_uninstall_schema('example_db_insert');
  }
}

/**
 * Implements hook_schema().
 */
function example_db_insert_schema() {
  // スキーマの初期化
  $schema = array();
  // データベーステーブルスキーマの定義
  $schema['example_db_insert_table'] = array(
    // テーブルの概要
    'description' => 'The base table for nodes.',
    // フィールド
    'fields' => array(
      // カラムフィールド
      'id' => array(
        // カラムの概要
        'description' => 'id.',
        // Intデータ型
        'type' => 'int',
        // 符号なしかどうか
        'unsigned' => TRUE,
        // NULLを許可するかどうか
        'not null' => TRUE),
      // カラムフィールド
      'name' => array(
        // カラムの概要
        'description' => 'name.',
        // 文字列データ型
        'type' => 'varchar',
        // 文字列の長さ
        'length' => 255,
        // NULLを許可するかどうか
        'not null' => TRUE,
        // デフォルト値
        'default' => ''),
    ),
    // プライマリキー.
    'primary key' => array('id'),     
  );
  return $schema;
}

解説

それでは手順に沿ってソースコードの解説をしていこうと思います。

モジュール名.installファイルの作成

モジュール名.moduleモジュール名.infoと同じ階層にモジュール名.installファイルを作成します。

モジュール名.installに、モジュールをインストール時またはアンインストール時の動作を定義

この.installファイルに hook_install関数や hook_uninstall関数、hook_schema関数を定義していきます。

1. hook_schema関数でデータベーススキーマの情報を定義

hook_schema関数はデータベーススキーマの定義をしています。 まずはスキーマの初期化を行ないます。 次に、$schema['テーブル名']と記述し、テーブルを定義します。 テーブルには'fields'を定義しており、この中にカラムフィールドを定義していきます。

2. hook_install関数でモジュールインストール時の処理を定義

hook_install関数はモジュールのインストール時に処理される関数です。 例えば下記のようなときに処理されます。

  • modulesフォルダに配置した時

  • モジュール管理画面でインストールした時

  • モジュール管理画面でモジュールの有効化

インストール時にdb_table_exists関数でテーブルが存在しているかをチェックしています。 もしも存在していなければdrupal_install_schema関数で定義したデータベーススキーマを基にテーブルを作成します。

3. hook_uninstall関数でモジュールアンインストール時の処理を定義

hook_uninstall関数はモジュールのアンインストール時に処理される関数です。 例えば下記のようなときに処理されます。

  • モジュール管理画面でアンインストールした時

インストール時にdb_table_exists関数でテーブルが存在しているかをチェックしています。 もしも存在していればdrupal_uninstall_schema関数でテーブルを削除します。

モジュール名.moduleに、モジュールの動作を定義

この.moduleファイルに hook_menu関数や hook_form関数、form_id_validate関数、form_id_submit関数を定義していきます。 hook_menu関数や hook_form関数は特に書くことはないので省略します。

1. form_id_validate関数で入力値の検証

form_id_validate関数ではIDのタイプやNameの文字数を検証しています。 もしもIDのタイプが数字でない場合や、Nameの文字数が255を超えているならばエラー処理をしています。

2. form_id_submit関数で送信時の処理

form_id_submit関数ではdb_insert関数を使用してデータベースへ情報を追加しています。 db_insert関数を使用すると返り値としてInsertQueryクラスが渡されます。 このクラスに対してアロー演算子でフィールドへデータを追加するfields関数やInsertQueryクラスの実行をするexecute関数を使い、テーブルにデータを挿入する命令を実行していきます。

これで入力情報をデータベーステーブルに挿入するカスタムモジュールの作成ができました。

まとめ

今回は入力情報をデータベーステーブルにデータを挿入するカスタムモジュールを作成しました。 Drupal用の関数を使えば、意外と簡単にできました。しかし、あんまりDrupal用の関数を使いすぎるとバージョンの互換性の問題が怖いです。 使う使わないの判断をちゃんと考えられるようにしないといけませんね。

参考サイト

DrupalAPI - hook_install

DrupalAPI - hook_uninstall

DrupalAPI - hook_sheme

PHP Documentation - ctype_digit

Drupal - Schema Reference

DrupalAPI - drupal_install_schema

DrupalAPI - drupal_uninstall_schema

DrupalAPI - db_table_exists

DrupalAPI - db_insert

DrupalAPI - InsertQuery

DrupalAPI - InsertQuery::fields

DrupalAPI - InsertQuery::execute