PHPのRuby on Railsクローンのフレームワーク Akelos PHPをいじってみた出来事のメモ。

Akelosをいじってみるメモ帳

Akelos PHP Blogチュートリアル一覧(全18記事)
Akelos PHP ユーザ認証チュートリアル一覧(全19記事)

2008年09月02日

Akelosユーザ認証チュートリアル 4.Userモデルをちゃんと その2 validation

続いて、モデルに入るデータのルールを決めていきます。
validateの登場です。
validateは、入ってくるデータの内容を確認し、正当性をチェックして、ちゃんとデータが入るようにします。ただしく無いデータが来た場合のエラー処理もまとめてしてくれます。

C:\xampp\htdocs\projects\blog\app\models\user.php
を開いてください。

下記のようなコードを前回のUserメソッドの後ろに足します。
//入力内容のチェック
function validate()
{

//emailはユニークか?
$this->validatesUniquenessOf('email', array('notice'=>$this->t('email address registed!')));

//新しく作るときだけのチェック項目
if($this->isNewRecord()) {

//パスワードと、パスワード確認枠には入力があるか?
$this->validatesPresenceOf(array('passwd','passwd_confirmation'));

//チェックボックスの確認
$this->validatesInclusionOf('is_enable', array('1') ,$this->t('Please check checkbox of confirmation'));
}

//新しく作るとき または 修正時でかつパスワード修正がある場合のみのチェック
if($this->isNewRecord() || !empty($this->passwd))
{
//パスワードの長さチェック
$this->validatesLengthOf('passwd', array('in'=>array(5, 40), 'too_long' => $this->t('password too long.'), 'too_short' => $this->t('password too short')));

//パスワード確認の為の再入力枠とパスワードの内容が一致しているか
$this->validatesConfirmationOf('passwd', $this->t('not confirmation password'));

}

//emailとnameの空入力チェック
$this->validatesPresenceOf(array('email','name'));

//emailアドレスが有効なアドレスか?
$this->validatesFormatOf('email', AK_EMAIL_REGULAR_EXPRESSION, $this->t('error email address.')) ;


}

色々なvalidation用メソッドが登場しています。

コメントを見てある程度使い方がわかると思いますが、共通なのは 最初に調べたいカラム名を指定して、validationがエラーだった場合のメッセージ内容を$this->t('xxx')で指定するところですね。
なぜ、このようにメッセージを設定するかは別途書くとして、今はこういうもんだと思っておけば良いかと思います。ちなみにコード内では、xxxの部分は英語にしておいた方が良いです。日本語化は別なところでしますので、ここでは適当に。

わかりにくいのはvalidatesUniquenessOfとvalidatesConfirmationOfですかね。
validatesUniquenessOfは、いわゆる重複値チェックを一気にしてくれます。
DB内のemailフィールドで同じ値を持つデータが無いかを調べてくれます。便利です。
メールアドレスは個人毎にユニークに持つものなので、ここでチェックさせています。

validatesConfirmationOfは、指定した属性の名前と、その名前の後ろに"_confirmation"を足した名前の属性とで、一致をチェックするものです。
フォームの再入力値チェック用に使います。
ここでは、passwdを指定していますので、自動的に passwd_confirmation と比べる形になります。

posted by AMUAMU at 03:38| Comment(0) | TrackBack(0) | チュートリアル | このブログの読者になる | 更新情報をチェックする

Akelosユーザ認証チュートリアル 3.Userモデルをちゃんとする その1 属性設定

Userモデルはデータのテーブルだけでは不十分です。
そこで、下記のようなコードを足します。

class User extends ActiveRecord
{
//クラス内の共通暗号化キーです
var $_my_common_salt = 'my_common_pass';

//管理者かどうかのフラグです。
var $is_admin = false;

//管理者として設定する人のメールアドレス
var $_admin_email = array("hoge@sample.com","amuamu@sample.com");


//クラス生成時の処理
function User()
{
// Railsで言うattr_accessorの設定
// DBのテーブルに無い属性を仮想的に作る場合に使います。
// 確認画面などに表示させ、入力させたいフィールドを足すのに必要なものをここでは指定
$this->set('passwd_confirmation');
// Railsで言うattr_protectedの設定
// ユーザが修正出来ないように保護するものを指定
$this->setProtectedAttributes(array('id','salt'));

//親のコンストラクタを呼びます おまじない
parent::__construct(func_get_args());
}
}

$_my_common_saltはパスワードの暗号化(ハッシュ化)に使う固定値です。適当な文字列に修正してください。
$is_adminと、$_admin_emailは管理者の為の設定です。管理者アドレスと一致し、ログインが成功した費とは管理者として認識し、フラグを立てるための設定です。

User()関数はコンストラクタですね。ここでは、2つの操作をしています。

最初のsetメソッドでは、このモデルが持つべき属性を足しています。コード内のメモに書いてあるように仮想的な属性です。ここではパスワードの確認の為の再入力枠用にpasswd_confirmationとしてあります。

2つめのsetProtectedAttributesは、ユーザが上書き・修正・閲覧出来ないようにすべきものを決めています。こうやって隠しておきたいものや、触られると困るものを指定しておくと安全になります。

最後の部分は親クラスの、まぁ詳しく知る必要は通常は無いかな、おまじないみたいなもんですが、入れ忘れるとうまくいかないので注意。
posted by AMUAMU at 02:27| Comment(0) | TrackBack(0) | チュートリアル | このブログの読者になる | 更新情報をチェックする

Akelosユーザ認証チュートリアル 2.Userモデルを作る。

ユーザのデータを入れるUserモデルを作ります。

コマンドラインで以下を入力して実行してください。
C:\xampp\htdocs\projects\blog>c:\xampp\php\php.exe script\generate model User id, name, passwd, salt, email, is_enable

モデルとしてUserというのを作れと指示していますが、以前実行したものと比べると長いですね。

コマンド後半のid, name, passwd, salt, email, is_enable 部分は、増やすカラムを予め指定して作っています。こうやって指定すると、作られるモデルのなかに入れてくれます。
もちろん手作業でインストーラーファイルを修正してもOKです。

C:\xampp\htdocs\projects\blog\app\installers\user_installer.php
を見れば、その構造がわかります。興味があるようでしたら見てください。

さて、これをマイグレーションしてデータベースに反映させます。
コマンドラインで以下を入力して実行してください。
C:\xampp\htdocs\projects\blog>c:\xampp\php\php.exe script\migrate user install

これでデータベースにはテーブルが作られました。
興味がある人はphpmysqladmin等でテーブル構造を確認してくださいね。


さて、データの中身ですが、下記のように考えて作っていきます。

id = これは必須のフィールドなんで説明も何もないです
name = 名前またはハンドル名、同じ名前を許可
passwd = ハッシュで暗号化されたパスワード ※パスワードは暗号化して入れましょう。
salt = ハッシュする際に付ける個別の文字列(暗号化用)
email = メールアドレス、ここでは最近はやりのemailをID代わりに使うようにしますね。それにパスワード再発行などに必要です
is_enable = 有効・無効フラグ

このままですと、Modelは入れる枠があるだけで、上のように必ずはいるとは限りません。
特にハッシュで暗号化など、入れるルールやチェック・処理みたいなものは、Modelで定義するのが望ましい形らしいです。MVCモデルの考え方ですね。
posted by AMUAMU at 02:24| Comment(0) | TrackBack(0) | チュートリアル | このブログの読者になる | 更新情報をチェックする

Akelosユーザ認証チュートリアル 1.ユーザ認証機能を作るよ!

やっと完成しました!!認証チュートリアルがはじまるよ!!!!!


ということで、現実的なサイトとなると、ユーザ認証が必要です。
pluginでadminプラグインというのもありますが、Akelosならばユーザ認証も簡単に作れます。たぶんw
Akelosの本家サイトも、日本語情報源にも意外とユーザ認証の実装の話が出ていない・・・。
AkelosのコミュニティBBSにはいくつかTopicsがあるけど、優しい内容になってない・・w

まぁ、RoRベースで考えられれば、すぐに出来るとわかるんだろうけどー
実際こういうチュートリアルがあるかないかがユーザの増減に関わりそうな気もする・・・

ということで、ユーザ認証を前回までに作ったBlogチュートリアルのサイトに組み込んでみようかと思う。

方向性としてはblogチュートリアルサイトの、new Post、Edit、Deleteにユーザ制限を加え、ユーザ登録した人だけがこれらのアクションに触れるようにする。

ユーザの登録、ログイン機能、あと適当に最低限必要そうな機能を追加するという感じで。

色々な機能が登場しますが、頑張って体感してもらえれば・・・かなりAkelosの事がわかるんじゃないでしょうか?

実際にサイトを構築する際に使う機能が殆ど網羅されてると個人的には思っています。

ということで、次回から本格的に開始。
posted by AMUAMU at 02:21| Comment(0) | TrackBack(0) | チュートリアル | このブログの読者になる | 更新情報をチェックする

2008年09月01日

Akelos AkActionMailerのバグ解決

AkelosのAkActionMailerは特定のメールアドレスの場合、メール送信出来ない場合がある。

その特定のメールアドレスというのは"-"を含んだアドレス。
具体的には so-net.ne.jp だとアウト。

かなり痛いバグだ。
まぁ、リリースされたばかりだし、しょうがない。
後日本家にフィードバックしたいが、二通りの解決方法を見つけた。

まず、本来の解決方法
→取りあえず本体をいじって解決

akelos\lib\AkActionMailer\AkMailMessage.php
のsetRecipientsメソッド
function setRecipients($recipients)
{
// $this->recipients = join(", ", (array)Ak::toArray($recipients));
$this-<recipients = join(", ",(array)$this->_recipientsArray($recipients)); $this->setHeader('To',$this->getTo());
}

function _recipientsArray()
{
$args = func_get_args();
return is_array($args[0]) ? $args[0] : (func_num_args() === 1 ? $this->_recipientsToArray($args[0]) : $args);
}

function _recipientsToArray($string)
{
$args = $string;
if(count($args) == 1 && !is_array($args)){
(array)$args = array_unique(array_map('trim',array_diff(explode(',',strtr($args.',',';|',',,,')),array(''))));
}
return $args;
}


と、_getMessageHeaderFieldFormatedも修正が必要

function _getMessageHeaderFieldFormated($address_header_field)
{
$charset = empty($this->charset) ? AK_ACTION_MAILER_DEFAULT_CHARSET : $this->charset;
// return join(", ",AkActionMailerQuoting::quoteAnyAddressIfNecessary(Ak::toArray($address_header_field), $charset));
return join(", ",AkActionMailerQuoting::quoteAnyAddressIfNecessary($this->_recipientsArray($address_header_field), $charset));
}



これで、問題は完全に取り除かれる。ただしスマートじゃないですね・・・
//でコメントアウトしてるところが問題のポイント
Ak::toArray() を使ってるんだが、こいつが-もarrayに分けちゃうって問題だと思う。
なので、Ak::toArray()の-を分けない関数として_recipientsArray()とrecipientsToArray()を作って、こいつに投げている感じです。


第二の解決法

メールアドレスの指定を
$this->setRecipients(array($User->email));
とする。

とっても簡単。でもtrimとか複数アドレスの分割とかしてくれないのが問題。スパム対策としてもオススメできないのかな?脆弱性がある気がする

まぁ、でもスマートに解決できるってのはある。

第二の解決法はちょっと、本当にこれでいいのか自信ないなぁー・・・
タグ:akelos
posted by AMUAMU at 19:24| Comment(0) | TrackBack(0) | Akelos | このブログの読者になる | 更新情報をチェックする

2008年08月24日

AkObjectのlogメソッドは機能しないから直す

AkActiveRecordなど主要なクラスの基本クラスとなっているAkObjectクラス。

これには log というメソッド(関数)があるんだが、これが機能しない。

バグかな?

とりあえず、下記のようにして直してみた。
コメントアウトしているところが、元のコード。太字が足したところ。

AkObject.php内
function log($message, $type = '', $identifyer = '')
{
// require_once 'Log.php';
// $ident = empty($ident) ? 'main' : $ident;
//
// $log = Log::singleton('file', AK_LOGS_DIR.DS.$ident.'.log',$ident);
// $log->log($type, $message);

$logger =& Ak::getLogger();
$logger->log( empty($type) ? 'debug' : $type ,$message);

}
タグ:akelos
posted by AMUAMU at 00:52| Comment(0) | TrackBack(0) | Akelos | このブログの読者になる | 更新情報をチェックする

2008年08月23日

DEBUG用メモ:DBへのSQLクエリーの結果確認る

データベースへのSQLクエリーの発行内容は、デバッグフラグを立てておけば、標準でdevelopment.logに出る。

しかしながら、このSQLはPEARのADODBに渡す形式のSQLである。

SQLが正常に動いているかどうかをデバッグしたい場合にはさらに、どのような引数を付けているか、SQLの結果の生の状態はどんな風になっているかを確認しないと辛いときがある

そこで、デバッグ出力を足してみる
\lib\AkActiveRecord\AkDbAdapter.php

executeメソッド内(220行前後 [8/23現在最新のソースコードで])
の .... $this->connection->Execute(... が含まれている行の前後に以下を足して、ログで確認できるようにしてみた


$this->_log($message.'(bindings): '. empty($bindings) ? '' : print_r($bindings ,true));
$result = isset($bindings) ? $this->connection->Execute($sql_string, $bindings) : $this->connection->Execute($sql_string);
$this->_log($message.'(result): '. print_r($result,true));

前後の太字の部分が足したところ
これで、SQLの前後の中身がまるまるdevelopment.logに出る。

複雑なSQLのデバッグ時には役に立つんじゃないかな?

(8/24修正)
$bindingsが空だった場合が想定されてなかったので、ちょっと修正した
タグ:tips DEBUG
posted by AMUAMU at 23:41| Comment(0) | TrackBack(0) | Akelos | このブログの読者になる | 更新情報をチェックする

2008年08月19日

AkActiveRecordの挙動が・・・&ActionMailerがおかしい?

色々確認をしていると、2つほど問題が発生して時間食ってる。
取りあえず寝る為にメモ代わりに・・w

1.AkActiveRecordの挙動がいまいち不安定で、動作確認に時間がかかるぅ・・・
findFirstBy に ('email',$email) とか引数を与えると
findFirstBy -> findBy -> find -> _findInitial -> _findEvery -> findBySql -> $this->_db->select [AkDbAdapterへ] -> execute -> $this->connection->Execute [PEARのADODBライブラリへ]

という感じで、呼び出される。

本来このPEARのADODBライブラリのExecuteメソッド
Execute($sql,$inputarr=false)

に対して
$sql = "SELECT * FROM users WHERE users.email = ? LIMIT 1"
$inputarr = Array( [0] => hoge@hogehoge.jp )

というふうにAkDbAdapter等で展開されて渡されて、正常にSQL文が実行されるはずなんだけど、なーんか動作が不安定。
SQL文は正常に生成できてるんだけど
$inputarr = Array( [1] => hoge@hogehoge.jp )

とかって、なんか配列展開中のarray_shiftがうまく行かないのか、配列が2番目(配列番号1)とか変なところに入る事がある。
試行錯誤してると、いきなり治ったりするからタチが悪い。
Apache再起動しても治らないのに、デバッグ用に出力コード入れただけで治ったりとか、もう、なんなんだいったいw
Akelosってより、Windows環境のPHPが不安定なのか?????

致命的な問題に繋がる事じゃないし、良いんだけど、
デバッグで時間食う・・・・・
Akelosが悪いわけじゃないっぽいんだけど、いまいち・・・
ソースコードを追っかける限りは問題無さそうだしなぁ・・・

とりあえず、今は正常に動いているので解決。
これが解決したので今日は終わり。

2.そして、残ってるのがActionMailerがおかしい?ってかんじのところ
具体的には、メールアドレスとして abc@aa1.so-net.ne.jp というアドレスを入れると、何故か「 - 」でアドレスが分割されて、Toが2つになって、SMTPサーバに送られる。
RCPT TO:<abc@aa.so>
RCPT TO:<net.ne.jp>

とかって、SMTPサーバ側の受信ログで2つのアドレスに分割されているところまで、確認した。
AkActionMailerクラスのrecipients(Mail.phpのrecipientsそのままっぽいんだけど)には正常なアドレスで格納されている事は確認した。

Akelosが悪いのか、Akelos付属のPEARのMail.phpの問題なのかなぁ・・・?
とりあえず、明日(というか今日だろうけど)はこれを追っかけよう。

あとちょっとなんだ、あとちょっと。
文は全部書けているんで、ここらの確認が済めば、再校正をすれば完成なんだけどなぁ、チュートリアル。

まぁ、でも、こういうデバッグとか調査は楽しいw(まぞ?
タグ:雑記
posted by AMUAMU at 04:58| Comment(0) | TrackBack(0) | Akelos | このブログの読者になる | 更新情報をチェックする

2008年08月18日

あーとちょっとぉー

Akelosチュートリアル、認証機能追加編
あとちょっとだぁ

暇を見つけて少しずつ最終確認中でする
タグ:雑記
posted by AMUAMU at 23:37| Comment(0) | TrackBack(0) | Akelos | このブログの読者になる | 更新情報をチェックする

2008年08月14日

ActionMailer問題解決

メールプロパティの渡し方がまずかったようだ
委細は後日の記事で

問題は解決したので、細かいところの最終確認中
FindBy周りの挙動を精査してるところ。
何が最適なのか、サニタイジング大丈夫なのかをコード全部読んで確認しないと不安なんでw
タグ:雑記
posted by AMUAMU at 09:18| Comment(0) | TrackBack(0) | Akelos | このブログの読者になる | 更新情報をチェックする

広告


この広告は60日以上更新がないブログに表示がされております。

以下のいずれかの方法で非表示にすることが可能です。

・記事の投稿、編集をおこなう
・マイブログの【設定】 > 【広告設定】 より、「60日間更新が無い場合」 の 「広告を表示しない」にチェックを入れて保存する。


×

この広告は1年以上新しい記事の投稿がないブログに表示されております。