S2Container+S2Dao.PHP5を使ってみる(その5)
まず、その4で、actionでserviceのauthorizeメソッドを使う仮定、みたいなことを書いたけど、多分その時点でserviceのinterfaceに書いてしまうのが正解かも(実際には、actionはすぐに書いてしまえるので、serviceもほぼ同時に書くことになりますが)。実装は後回しでOKってことで。必要な実装が洩れてたら少なくとも実行時には分かるし。ただPHPの場合コンパイルしないのでコンパイル時点で怒られて気付く、というのは無理ですが。
ともかく、serviceを書く。serviceはdtoを引数にして呼ばれる、と、特に考えずにいつもそのように書く。
- MemberLoginService.class.php
<?php interface MemberLoginService { public function authorize(MemberLoginDto $dto); } ?>
次に実装ですが、ログイン処理はemailとpasswordで会員テーブルからmemberを引き当てるので、先にdaoにそれ用のメソッドを書きます。daoはinterfaceだけ書いておけば、あとはS2Daoがやってくれるので素晴らしく楽ちん。実際にどんなクエリを発行してるのかは分かりませんが・・・。
- MemberDao.class.php
<?php /** * @author * @since 2006/06/19 */ interface MemberDao { const BEAN = "MemberEntity"; //他のメソッドは省略 const getMemberByEmailPasswordList_QUERY = "email = /*email*/ and password = /*password*/"; public function getMemberByEmailPasswordList($email, $password); } ?>
where以下をメソッド名_QUERYという定数に書いてやればいいだけ。/*引数名*/とコメントしとけばメソッドの引数値のプレースホルダになります。あと、メソッド名はListで終わらせるとS2Daoの用意するS2Dao_ArrayList型で返してくれるみたい。Arrayで返してもらうにはメソッド名の最後をArrayにする。Entityを一つだけ返して欲しければArrayともListとも書かない。非常にシンプルです。で、ここでは普通にArrayでもらってもいいけど、試しにListで受け取ることにしてみました。
次に、daoで検索してmemberを見つけたら、そのemailとpasswordの値をdtoに渡すことが必要になるので、そこをdxoを使って行いますので、それも先に書いておきます。MemberEntityとMemberLoginDtoを引数にして、entityからdtoへ単に必要なデータをコピー、と。
- MemberLoginDxo.class.php
<?php interface MemberLoginDxo { public function copyMemberToDto(MemberEntity $entity = null, MemberLoginDto $dto = null); } ?>
実装は下記にようにしました。要らないデータまでコピーしてるが、とりあえず書いてしまったのでそのままおいておこう。
- MemberLoginDxoImpl.class.php
<?php class MemberLoginDxoImpl implements MemberLoginDxo { public function __construct(){} public function copyMemberToDto(MemberEntity $entity = null, MemberLoginDto $dto = null) { if($entity == null) { $dto->setId(""); $dto->setFirstName(""); $dto->setLastName(""); $dto->setEmail(""); $dto->setPassword(""); } else { $dto->setId($entity->getId()); $dto->setFirstName($entity->getFirstName()); $dto->setLastName($entity->getLastName()); $dto->setEmail($entity->getEmail()); $dto->setPassword($entity->getPassword()); } } } ?>
で、seerviceの実装はこうなりました。MemberLoginDxoとMemberDaoを使うので、それ用にフィールドとgetter/setterを用意し、DIするようにする。処理内容的には、MemberEntityが見つかったらdtoのisAuthorizedをtrueに設定しています。
- MemberLoginServiceImpl.class.php
<?php <?php class MemberLoginServiceImpl implements MemberLoginService { private $dxo; private $memberDao; public function setDxo(MemberLoginDxo $value = null){ $this->dxo = $value; } public function getDxo(){ return $this->dxo; } public function setMemberDao(MemberDao $value = null){ $this->memberDao = $value; } public function getMemberDao(){ return $this->memberDao; } public function __construct(){} public function authorize(MemberLoginDto $dto) { $memberList = $this->memberDao->getMemberByEmailPasswordList($dto->getEmail(), $dto->getPassword()); $member = null; $dto->setIsAuthorized(false); if($memberList != null) { $i = $memberList->getIterator(); if($i->valid()) { $member = $i->current(); $dto->setIsAuthorized(true); } } $this->dxo->copyMemberToDto($member, $dto); } } ?>
ここまででmemberLogin回りは完了。S2Base.PHP5 with Smartyでは、public/d.phpにmod=モジュール名、act=アクション名のパラメータを渡して画面遷移を行うので、
http://localhost/LoginSample/public/d.php?mod=Login&act=memberLogin
にアクセスするとログインページが表示されました。
d.phpにあるS2BASE_PHP5_DEFAULT_MODULE_NAMEとS2BASE_PHP5_DEFAULT_ACTION_NAMEを設定しておけばデフォルトで飛ぶmoduleとactionを指定できるので、下記の様に設定すれば、
http://localhost/LoginSample/public/d.php
でログイン画面へ遷移するようになります。
define('S2BASE_PHP5_DEFAULT_MODULE_NAME','Login'); define('S2BASE_PHP5_DEFAULT_ACTION_NAME','memberLogin');
現時点で、ログイン画面で適当にemailとpasswordを入力してログインをクリックすると、membersテーブルに何も入ってないためログイン処理に失敗し、再度ログイン画面が表示されます。登録画面はまだ作ってないので、MySQL QUERY Browserとかで適当に会員を登録した状態で、その情報でログインが成功するか確かめます。ログイン出来ればviewCartへ遷移するはず(自動生成されたactionでは、そのままの状態だとexecuteで単にアクション名.tplを処理するだけなので、自動生成されたviewCart.tplの内容が表示されるはず)。とりあえず、ここまではあっという間に出来ます。
続く...