前回作成した UserModel.class.php
には、システム側からの要求で作成したメソッド(A)とDBの定義から要求されたメソッドとプロパティ(B)が混在しています。そこで、この(A)と(B)については分けておきたくなります。
(B)の部分については、テーブルの定義から自動的に決定されるので、ソースコードを書き出すプログラムを作成しておけば、テーブルの定義が変わってもそのプログラムで書き出せば良いし、 手作業で書き換えることはかえってバグの元 になります。
また、動作確認などでバグがあったとしても、UserModelBase.class.php
にバグがある可能性は低く、UserModel.class.php
に書かれた処理を対象にデバッグ対象を絞り込みやすくなります。
こうしておくことで、基本的に UserModelBase.class.php
はいじってはならず、UserModel.class.php
に必要な処理を記述するという「基本的なルール」を設定することができます。
UserModel.class.php
<?php
namespace MyApp\model;
use MyApp\dao\UserDao;
/**
* UserModel
*/
final class UserModel extends UserModelBase
{
/**
* アカウントをロックするログイン失敗回数
*/
const LOCK_COUNT = 3;
/**
* アカウントをロックする時間(分)
*/
const LOCK_MINUTE = 15;
/**
* メールアドレスからユーザーを検索する
* @param string $strEmail
* @return \MyApp\model\UserModel
*/
public function getModelByEmail($strEmail)
{
$dao = UserDao::getDaoFromEmail($strEmail);
return (isset($dao[0])) ? $this->setProperty(reset($dao)) : null;
}
/**
* パスワードが一致しているかどうかを判定する
* @param type $password
* @return bool
*/
public function checkPassword($password)
{
$hash = $this->getPassword();
return password_verify($password, $hash);
}
/**
* ログイン失敗をリセットする
* 1以上のときに0にする
* @return bool
*/
public function loginFailureReset()
{
$count = $this->getLoginFailureCount();
if (0 < $count) {
$this->setLoginFailureCount(0)
->setLoginFailureDatetime(null);
return $this->save();
}
//変更の必要がない
return true;
}
/**
* ログイン失敗をインクリメントする
* 指定回数(self::LOCK_COUNT)に満たないときのみ+1
* @return bool
*/
public function loginFailureIncrement()
{
$count = $this->getLoginFailureCount();
if (self::LOCK_COUNT > $count) {
$now = (new \DateTime())->format('Y-m-d H:i:s');
$this->setLoginFailureCount(1 + $count)
->setLoginFailureDatetime($now);
return $this->save();
}
//ログイン失敗が設定以上のとき
return true;
}
/**
* アカウントがロックされているかどうかを判定する
* @return bool ロックされていたら true
*/
public function isAccountLock()
{
$count = $this->getLoginFailureCount();
$datetime = $this->getLoginFailureDatetime();
$lastFailureDatetime = new \DateTime($datetime);
$interval = new \DateInterval(
sprintf('PT%dM', self::LOCK_MINUTE)
);
$lastFailureDatetime->add($interval);
//設定時間以内で、かつ設定回数以上の失敗を記録しているとき
if ($lastFailureDatetime > new \DateTime() && self::LOCK_COUNT <= $count) {
return true;
}
return false;
}
}
UserModelBase.class.php
<?php
/**
* **** 注意 ****
* このファイルは自動的に生成されます。
* 手動でいじったりしないようにしてください。
*/
namespace MyApp\model;
use MyApp\dao\UserDao;
/**
* UserModelBase
*/
class UserModelBase
{
/**
* ユーザーID
*/
private $_userId = null;
/**
* パスワード(ハッシュ)
*/
private $_password = null;
/**
* 表示名
*/
private $_displayName = null;
/**
* メールアドレス
*/
private $_email = null;
/**
* トークン
*/
private $_token = null;
/**
* ログイン失敗回数
*/
private $_loginFailureCount = null;
/**
* ログイン失敗日時
*/
private $_loginFailureDatetime = null;
/**
* 削除フラグ
*/
private $_deleteFlag = null;
/**
* プロパティをセットする
* @param array $arrDao
* @return \MyApp\model\UserModel
*/
protected function setProperty(array $arrDao)
{
$this->setUserId($arrDao['userId'])
->setDisplayName($arrDao['displayName'])
->setEmail($arrDao['email'])
->setPassword($arrDao['password'])
->setToken($arrDao['token'])
->setLoginFailureCount($arrDao['loginFailureCount'])
->setLoginFailureDatetime($arrDao['loginFailureDatetime'])
->setDeleteFlag($arrDao['deleteFlag']);
return $this;
}
/**
* 更新する
* @return bool
*/
public function save()
{
return UserDao::save($this);
}
/**
* 新規作成する
* @return int
*/
public function create()
{
return UserDao::insert($this);
}
/**
* ユーザーIDを設定する
* @param int $userId
* @return \MyApp\model\UserModel
*/
public function setUserId($userId)
{
$this->_userId = $userId;
return $this;
}
/**
* パスワード(ハッシュ)を設定する
* @param string $password
* @return \MyApp\model\UserModel
*/
public function setPassword($password)
{
$this->_password = $password;
return $this;
}
/**
* 表示名を設定する
* @param string $displayName
* @return \MyApp\model\UserModel
*/
public function setDisplayName($displayName)
{
$this->_displayName = $displayName;
return $this;
}
/**
* メールアドレスを設定する
* @param string $email
* @return \MyApp\model\UserModel
*/
public function setEmail($email)
{
$this->_email = $email;
return $this;
}
/**
* トークンを設定する
* @param string $token
* @return \MyApp\model\UserModel
*/
public function setToken($token)
{
$this->_token = $token;
return $this;
}
/**
* ログイン失敗回数を設定する
* @param int $loginFailureCount
* @return \MyApp\model\UserModel
*/
public function setLoginFailureCount($loginFailureCount)
{
$this->_loginFailureCount = $loginFailureCount;
return $this;
}
/**
* ログイン失敗日時を設定する
* @param string $loginFailureDatetime
* @return \MyApp\model\UserModel
*/
public function setLoginFailureDatetime($loginFailureDatetime)
{
$this->_loginFailureDatetime = $loginFailureDatetime;
return $this;
}
/**
* 削除フラグを設定する
* @param bool $deleteFlag
* @return \MyApp\model\UserModel
*/
public function setDeleteFlag($deleteFlag)
{
$this->_deleteFlag = $deleteFlag;
return $this;
}
/**
* ユーザーIDを取得する
* @return int
*/
public function getUserId()
{
return $this->_userId;
}
/**
* パスワード(ハッシュ)を取得する
* @return string
*/
public function getPassword()
{
return $this->_password;
}
/**
* 表示名を取得する
* @return string
*/
public function getDisplayName()
{
return $this->_displayName;
}
/**
* メールアドレスを取得する
* @return string
*/
public function getEmail()
{
return $this->_email;
}
/**
* トークンを取得する
* @return string
*/
public function getToken()
{
return $this->_token;
}
/**
* ログイン失敗回数を取得する
* @return int
*/
public function getLoginFailureCount()
{
return $this->_loginFailureCount;
}
/**
* ログイン失敗日時を取得する
* @return string
*/
public function getLoginFailureDatetime()
{
return $this->_loginFailureDatetime;
}
/**
* 削除フラグを取得する
* @return bool
*/
public function getDeleteFlag()
{
return $this->_deleteFlag;
}
}
次回は、当初予定していた「ログインメソッドの実装」はすでに作成済みですので、テンプレート・クラスを作成することにします。