続・モジュールを作ろう!(4) ハンドラでテーブルのデータを取得1

本記事は、Cubson というモジュール生成ツールを使った XOOPS のモジュール作成方法を解説するものです。

Cubson を使ってコード生成が出来る人,モジュールを作るために PHP を自分で調べながら学んでいこうという気がある人が対象です(すでに PHP を知っている人も,もちろん)。
本連載のコピペで何とかならない?,という人ではちょっと厳しいかも。

こんなときに使います

ニュース登録時のカテゴリ一覧など、選択肢として使うようなデータをテーブルから取得するときに使います。

また、ぶら下がっている子データの一覧を取得する場合などにも使います(あるユーザが登録した記事の一覧など)。

操作対象テーブルのデータは Cubson の生成するコードで処理できますので、基本的にはノータッチでいけるのですが、そのテーブルに関連するデータ(カテゴリデータや都道府県データなど)は、そのままでは存在しません*1

そのため、以下のサンプルのようなコードを書いて、テーブルのデータを取得する必要があります。

サンプルコード

サンプル1:actions/XxxEditForm.class.php

function executeViewInput(&$render)
{
(略)
  $handler =& $this->mAsset->load('handler', "cat");
  $catsArr = $handler->getObjects();
  $render->setAttribute('cats', $catsArr);
}

サンプル2:actions/XxxEditForm.class.php

function executeViewInput(&$render)
{
(略)
  $handler = xoops_getmodulehandler('forumcat', 'myforum');
  $criteria = new CriteriaCompo('1', '1');
  $criteria->add(new Criteria('uid', 
  $this->mRoot->mContext->mXoopsUser->get('uid')));
  $forumcatsArr = $handler->getObjects($criteria);
  $render->setAttribute('forumcats', $forumcatsArr);
}

解説

一つ目のサンプルは、同じモジュールの "cat" テーブルの全レコードを取ってきて $catsArr にオブジェクトとして入れて、それを "cats" という名前でレンダーに渡しています。

二つ目のサンプルは、いま操作しているモジュールとは別の "myforum" というモジュールの "forumcat" というテーブルのデータのうち、uid が利用ユーザの uid と同じデータを取得し、"forumcats" という名前でレンダーに渡しています。

別のモジュールのテーブルからデータを取ってくるということはあまりやりませんが、強引にデータを取りたい場合はこう書きます。ただし、そのテーブルが XoopsSimpleObject、XoopsObjectGenericHandler を持っていないとだめです*2

その次の行の CriteriaCompo というのは、テーブルからデータを取得する際の条件を保持するクラスです。この行はこのオブジェクトを生成するお決まりの書き方で、実際の条件は次の行に書かれています。

CriteriaCompo オブジェクトにセットされた条件は、実際には SQL 文の WHERE 節や ORDER BY 句に翻訳されます。その処理が、次の行の getObjects($criteria) で行われ、さらにデータベースに接続して指定されたデータを取得し、 $forumcatsArr にオブジェクトとして格納されます。


レンダーに渡されたデータは、テンプレートファイルの中で以下のようにして使うことができます。

<select name="cat_id" class="inputbox" >
  <{foreach item=child from=$cats}>
    <{if $child->get('cat_id') == $actionForm->get('cat_id')}>
      <option value="<{$child->getVar('cat_id')}>" selected="selected">
        <{$child->getShow('cat_name')}>
      </option>
    <{else}>
      <option value="<{$child->getShow('cat_id')}>">
        <{$child->getShow('cat_name')}>
      </option>
    <{/if}>
  <{/foreach}>
</select>

なお、select のオプションに特化した形では、以下の様に簡潔に書くこともできます。

<select name="cat_id">
  <{xoops_optionsArray label="cat_name" from=$cats 
  value="cat_id" default=$actionForm->get('cat_id'))}>
</select>

注意

getObjects() メソッドでとってきたデータは、オブジェクトの配列に格納されるので、テンプレートで利用する場合はその点に注意が必要です。

たとえば、上のサンプルでは、foreach の中で使っているので配列の添え字は要らないのですが、そうではなくいきなり

<{$cats->getShow('cat_name')}>

とやるとエラーになります。正しくは、以下の様に配列の添え字をつけなければなりません。

<{$cats[0]->getShow('cat_name')}>

次回あたりで説明を予定している get() メソッドで取得したデータはこれと反対になるのですが、最初の頃この違いを認識していなくてかなり嵌った記憶が。

*1:本当は Cubson がそこまでやってくれるのですが、いまその機能は死んでいる

*2:Cubson で作ったモジュールなら普通 modules/{moduleName}/class/handler/ 以下に用意されています