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の内容が表示されるはず)。とりあえず、ここまではあっという間に出来ます。

続く...