masayuki5160's diary

名古屋でエンジニアしてます。

Ethna勉強中 その3

前回に引き続き本家サイトの
アプリケーション構築手順3(http://ethna.jp/old/ethna-document-tutorial-practice3.html)を参考に、
ぼくなりの解釈をいれながらログイン処理をEthnaで実装していきます。


こまかい技術的な話はぬきにすると、
今回やることの流れとしてはこんな感じでいきます。


0.プロジェクトの作成
 今回はtestというプロジェクトとします。

1.loginアクションの作成
 メールアドレス、パスワードを入力するフォームとログインボタンを設置。
 んでこの段階でいったんうまくいけてるか確認。

2.login_doアクションの作成
 login_doアクションでフォーム値の検証と認証処理を行う。
 
 まずは画面の遷移をかえる。
 今回はログインボタンをおしたら、indexページにとぶように設定する。設定後にいちおう確認。
 そして、フォーム値の検証処理とエラー処理を実装。
 んでうまく動作するかチェック。
 最後に認証処理を実装。
 そして確認。。



ざっとこんな感じでいきます。
んじゃプロジェクト作成から。




0.プロジェクトの作成

なにはともあれプロジェクトを作成。

#ethna add-project test


そして公開ディレクトリ(今回は/var/www/htmlとします)へシンボリックリンクをはる。

#cd /var/www/html
#ln -s /home/ethna/project/test/www test

この段階でちゃんと動いてるか確認。
indexページが表示されるはずです。

http://IP/test/

1.loginアクションの作成

次はログイン用の画面をつくっていきます。

#ethna add-action login

これでapp/action/Login.phpができます。
そしてビューとテンプレートもつくっていきます。

#ethna add-view login
#ethna add-template login

ビューはついでにつくりましたが、
実は今回はいじることないので放置します。
ではテンプレート(template/ja/login.tpl)を下記のようにします。


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head></head>
<body>
<form action="{$script}" method="post">
<input type="hidden" name="action_login_do" value="dummy">
<table border="0">
<tr>
<td>メールアドレス</td>
<td><input type="text" name="mailaddress" value=""></td>
</tr>
<tr>
<td>パスワード</td>
<td><input type="password" name="password" value=""></td>
</tr>
</table>
<p>
<input type="submit" name="action_login_do" value="ログイン">
</p>
</form>
</body>
</html>


{$script}は実行中のPHPスクリプトを表しています。
フォーム値のvalueの部分はあとでエラー処理の実装のときに設定するのでまたあとで。

ここまできたら一度ブラウザで確認。
メールアドレス、パスワードのフォームとログインボタンが表示されればOKです。

http://IP/test/?action_login=true

2.login_doアクションの作成

さて最後にlogin_doアクションの作成をしていきます。
login_doアクションでは、
フォーム値(メールアドレスとパスワードの値)の検証と認証の処理を行います。


ということでいつものようにethnaコマンドを実行。

#ethna add-action login_do

app/action/Login/Do.phpが作成されます。
前述したように、今回はindexページに遷移したいのでこのファイルを下記のように変更する。

function perform()
{
return 'index';
}

これでログインボタンをおすとindexページにとぶようになります。確認してみてください。




さて次にフォーム値の自動検証機能を実装していきます。
Ethnaではアクションフォームというオブジェクトを利用することで、
検証を簡単に実装することができます。
で、そのアクションフォームというのはethna add-actionコマンドを実行したときに生成されているのでそこに今回使用するメールアドレスとパスワードの文字数制限だったり使用する文字だったりなんやらを定義していきます。
そうすることで、後述するアクションフォームのvalidate()メソッドを利用して検証を楽に行うことができるわけです。

というわけでまずはメールアドレスとパスワードの属性を定義していきます。
app/action/Login/Do.phpを下記のように編集。

var $form = array(
'mailaddress' => array(
'name' => 'メールアドレス',
'required' => true,
'type' => VAR_TYPE_STRING,
),
'password' => array(
'name' => 'パスワード',
'required' => true,
'type' => VAR_TYPE_STRING,
),

それぞれ表示名、入力必須項目、データ型を設定しています。

ここで属性を定義することでアクションクラスのprepare()メソッドでフォーム値の検証を実施できます。
同様にapp/action/Login/Do.phpを編集。
validate()メソッドは検出したエラー数を返り値としています。

class Test_Action_LoginDo extends Test_ActionClass
{
/**
* preprocess of login_do Action.
*
* @access public
* @return string forward name(null: success.
* false: in case you want to exit.)
*/
function prepare()
{
/*フォーム値の検証結果に応じて遷移先を変更する*/
if($this->af->validate() > 0){
return 'login';
}

return null;
}


だんだん形にはなってきました。
でもエラー処理がさっぱりです。
というわけで次はエラー処理をかるく。。

まずは、フォーム値の表示。
いまのままだと入力したフォーム値が失われてしまうことがあります。
(メールアドレスだけ入力してパスワードの入力をわすれてログインボタンをおした場合など。
この場合は再度メールアドレスから入力する必要があります。)

これを防ぐために以下のようにvalue値を設定します。
これで入力した値が失われることはありません。

template/ja/login.tpl


<form action="{$script}" method="post">
<input type="hidden" name="action_login_do" value="dummy">
<table border="0">
<tr>
<td>メールアドレス</td>
<td><input type="text" name="mailaddress" value="{$form.mailaddress}"></td>
</tr>
<tr>
<td>パスワード</td>
<td><input type="password" name="password" value="{$form.password}"></td>
</tr>
</table>
<p>
<input type="submit" name="action_login_do" value="ログイン">
</p>
</form>
</body>

さてもうひとつエラー処理としてエラーメッセージの表示をします。
これは簡単で、以下のようにテンプレートに記述することでエラーメッセージを表示できます。
(詳しいことは本家サイトを参照お願いしますw)

template/ja/login.tpl


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

ここまでで、認証の処理をのぞくすべての実装がおわりました。
フォーム値の検証の処理はできるので、
ためしにブラウザからアクセスしてみてください。
(たとえばメールアドレスだけ入力してログインボタンをおすとエラーが表示されるはずです。)



だいぶ長くなってしまいましたがこれで最後ですw
では認証の処理について。

流れとしては、
app/Test_UserManager.phpという認証処理を行うクラスを作成し、
アクションクラスから呼び出す、という感じ。

app/Test_UserManager.phpは下記のとおり。
auth()メソッドでは仮にメールアドレスとパスワードが同じとき認証がとおるように設定しています。


エラーコードもapp/Sample_Error.phpで下記のように定義できます。
(E_TEST_AUTHについてはapp/Test_UserManager.php参照)

define('E_TEST_AUTH', -128);

で、作成したクラスをapp/Test_Controller.phpでインクルード。

include_once('Test_UserManager.php');


最後にアクションクラスのperform()メソッドで実装。

function perform()
{
/*インスタンス作成*/
$um =& new Test_UserManager();
/*auth()メソッドで認証結果を確認*/
$result = $um->auth($this->af->get('mailaddress'),$this->af->get('password'));

if(Ethna::isError($result))
{
$this->ae->addObject(null,$result);
return 'login';
}

return 'index';
}


これで完成です。
メールアドレスとパスワードに同じ値を入力したら認証できるようになってるはずです。

本家のサイトとやってることも、
コードもおんなじなんですけど、
あっちみたけどわからん、困った!って人の助けになればと思いちょっとコメント多めにいれてみたりしてます。
どなたかの参考になれば幸いです。

ではでは。