Skip to main content.

Tuesday, January 02, 2007

Ethnaの導入(その3)アプリケーションオブジェクトの利用

Ethnaの導入(その3)です。今回は、アプリケーションオブジェクトについてのページ等を見ながら、EthnaのO/RマッピングクラスであるEthna_AppObjectクラスを使ってみました。MySQLのテーブルと連携をさせて画面からデータを追加するところまで実装してみました。以下、その詳細です。(※Ethnaのバージョンは、2.3.0です。)

(※2007/01/08 EUC環境の自サーバで日本語データが正しく登録されることを確認しました。Ethnaの内部コードについては、こちらをご覧ください。)

まず、MySQLのテーブルを作成しました。以下のような簡単なテーブルを作成しました。
DROP TABLE IF EXISTS `ethnadb`.`member`;
CREATE TABLE  `ethnadb`.`member` (
  `memid` varchar(255) NOT NULL,
  `name` varchar(255) NOT NULL default '',
  `email` varchar(255) NOT NULL default '',
  `passwd` varchar(255) NOT NULL default '',
  `created_at` datetime NOT NULL default '0000-00-00 00:00:00',
  PRIMARY KEY  (`memid`)
) ENGINE=MyISAM DEFAULT CHARSET=eucjpms;

今回のプロジェクト全体をappobjという名前で以下のように作成しました。
> ethna add-project appobj

次に、データベースの接続情報を作成されたetc配下のappobj-ini.phpに追加しました。appobjは今回のプロジェクト名です。以下、同様です。必要な場合は各自のプロジェクト名としてご理解下さい。
<?php
/*
 * appobj-ini.php
 *
 * update:
 */
$config = array(
    // site
    'url' => '',

    // db
    'dsn' => 'mysql://root:pass1234@localhost/ethnadb',
);
?>

ここで、以下のコマンドでアプリケーションオブジェクトを作成しました。
> ethna add-app-object member
今回の場合は、Appobj_Member.phpというファイルが作成されました。これで作成したmemberテーブルと連携します。実際の連携の情報は、プロジェクトディレクトリのtmp/cache配下に出来るみたいです。テーブルの定義を変更した場合は、一度ここのファイルを削除した方がいいみたいです。

コントローラに作成されたアプリケーションオブジェクトのインクルードを追加します。

作成されたAppobj_Member.phpを編集します。作成されたファイルにはEthna_AppObjectから継承されたクラスとEthna_AppManagerから継承されたクラスが作成されています。実際には、このEthna_AppManagerから継承されたクラスを経由してデータの操作をします。どういうことかというと、実際にはActioinクラスでデータ操作を実行する訳ですが、このActionクラスで同じような処理を何回も書かないように、Ethna_AppManagerのクラスでその処理を書いて、Actionからは呼び出すだけという利用方法にします。(※ここにそのアプリケーションマネージャの使い方についての説明があります。)

以下が今回書いたスクリプトです。今回はadd()だけですが、実際には、一覧取得、変更、削除といった処理を同様に書くことになるかと思います。
<?php
/**
 *  Appobj_Member.php
 *
 *  @author     {$author}
 *  @package    Appobj
 *  @version    $Id: skel.app_object.php,v 1.3 2006/11/06 14:31:24 cocoitiban Exp $
 */

/**
 *  Appobj_MemberManager
 *
 *  @author     {$author}
 *  @access     public
 *  @package    Appobj
 */
class Appobj_MemberManager extends Ethna_AppManager
{
    /**
     * 1件追加する
     * 
     * @access public
     * @param $member memberObject 追加するメンバオブジェクト
     */
    function add(&$member) {
        $member->set("created_at", date("Y-m-d H:i:s"));
        $r =& $member->add();
        
        return $member->isValid() && Ethna::isError($r) === false;
    }

    /**
     * 1件更新する
     * 
     * @access public
     * @param $member memberObject 更新するメンバオブジェクト
     */
    function update(&$member) {
        //とりあえず更新日時を設定
        $member->set("created_at", date("Y-m-d H:i:s"));

        //更新実行
        $r =& $member->update();
        
        return $member->isValid() && Ethna::isError($r) === false;
    }

    /**
     * 1件削除する
     * 
     * @access public
     * @param $member memberObject 削除するメンバオブジェクト
     */
    function remove(&$member) {
        $r =& $member->remove();
        
        return Ethna::isError($r) === false;
    }

    /**
     * 全件取得する
     * 
     * @access public
     * @return array member全件の取得
     */
    function getList(){
        // member一覧を取得
        $members = $this->getObjectPropList(
            'member',
            null,
            null,
            array(
                'created_at' => OBJECT_SORT_ASC,
            )
        );
        
        // エラーチェック
        if (Ethna::isError($members)) {
            return false;
        }
        
        return $members[1];
    }
}
    
/**
 *  Appobj_Member
 *
 *  @author     {$author}
 *  @access     public
 *  @package    Appobj
 */
class Appobj_Member extends Ethna_AppObject
{
    /**
     *  プロパティの表示名を取得する
     *
     *  @access public
     */
    function getName($key)
    {
        return $this->get($key);
    }
}
?>

次に以下のコマンドでAddというアクションを作成しました。
> ethna add-action add
Actionを編集する前に以下のようなデータを追加するための画面(テンプレート)を作成しました。
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=EUC-JP">
    </head>
    <body>
        <h2>Member - Add</h2><hr>

        <table border="0"
            {if count($errors)}
                <ul>{foreach from=$errors item=error}
                    <li>{$error}</li>
                {/foreach}</ul>
            {/if}>
        </table>

        <form method="post" action="{$script}">
            
            <input type="hidden" name="action_add" value="true">
            
            MemberID:<input type="text" name="memid" value=""><br><br>

            Name:<input type="text" name="name" value=""><br>
            Email:<input type="text" name="email" value=""><br>
            Password:<input type="password" name="passwd" value=""><br>

            <input type="submit" name="action_add" value="Exec Add">
        </form>

    </body>
</html>

これで、addアクションを以下のように編集しました。ActionFormの方にフォームの定義を書いて、ActionClassのperform()でデータを追加します。
<?php
/**
 *  Add.php
 *
 *  @author     {$author}
 *  @package    Appobj
 *  @version    $Id: skel.action.php,v 1.10 2006/11/06 14:31:24 cocoitiban Exp $
 */

/**
 *  addフォームの実装
 *
 *  @author     {$author}
 *  @access     public
 *  @package    Appobj
 */
class Appobj_Form_Add extends Appobj_ActionForm
{
    /** @var    bool    バリデータにプラグインを使うフラグ */
    var $use_validator_plugin = true;

    /**
     *  @access private
     *  @var    array   フォーム値定義
     */
    var $form = array(

    // フォームの定義
    'memid' => array(
        'type' => VAR_TYPE_STRING,
        'form_type' => FORM_TYPE_TEXT,
        'name' => "memid",
        'required' => true,
        'max' => 255,
    ),

    'name' => array(
        'type' => VAR_TYPE_STRING,
        'form_type' => FORM_TYPE_TEXT,
        'name' => "name",
        'required' => true,
        'max' => 255,
    ),

    'email' => array(
        'type' => VAR_TYPE_STRING,
        'form_type' => FORM_TYPE_TEXT,
        'name' => "email",
        'required' => true,
        'max' => 255,
    ),

    'passwd' => array(
        'type' => VAR_TYPE_STRING,
        'form_type' => FORM_TYPE_PASSWORD,
        'name' => "passwd",
        'required' => true,
        'max' => 255,
    ),
    );
}

/**
 *  addアクションの実装
 *
 *  @author     {$author}
 *  @access     public
 *  @package    Appobj
 */
class Appobj_Action_Add extends Appobj_ActionClass
{
    /**
     *  addアクションの前処理
     *
     *  @access public
     *  @return string      遷移名(正常終了ならnull, 処理終了ならfalse)
     */
    function prepare()
    {
        return null;
    }

    /**
     *  addアクションの実装
     *
     *  @access public
     *  @return string  遷移名
     */
    function perform()
    {
        //MemberManagerを取得する 
        $memberManager =& $this->backend->getManager("member");

        //AppObjectを生成する
        $member =& new Appobj_Member($this->backend);
        
        //importFormで一括で取得
        $member->importForm();      
        
        //memberManager経由で追加処理をする
        $ret = $memberManager->add($member);
        
        //エラー処理
        if($ret === false) {
            $this->ae->add(null, "Error at add.", E_ADD_FAILED);
        }

        return 'add';
    }
}
?>

以上で、実行するとデータが追加されました。とはいってもこの場合、追加の機能しかないので、追加出来たかどうかはデータベースを直接見て確認します。プロジェクトファイル全体を以下に置いておきます。
プロジェクトファイル一式(※2007/01/08 その他、一覧、更新、削除処理実装済みのバージョンです。)説明は、こちらです。

関連リンク
Ethna
データベースアクセス(アプリケーションオブジェクトを使わない場合)

Webプログラミング関連記事