components/user/models/User.php
<?php
/**
* Created by PhpStorm.
* User: ehsanabbasi
* Date: 24/04/15
* Time: 7:23 PM.
*/
namespace CodeJetter\components\user\models;
use CodeJetter\components\user\services\UserAuthentication;
use CodeJetter\core\BaseModel;
use CodeJetter\core\io\Input;
use CodeJetter\core\io\Output;
use CodeJetter\core\Registry;
use CodeJetter\core\security\Validator;
use CodeJetter\core\security\ValidatorRule;
use CodeJetter\core\utility\StringUtility;
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
/**
* Class User.
*/
abstract class User extends BaseModel
{
protected $name;
protected $username;
protected $email;
protected $phone;
protected $password;
protected $status;
protected $token;
protected $tokenGeneratedAt;
protected $timeZone;
/**
* Start setting & getting.
*/
/**
* @return string
*/
public function getUsername()
{
return $this->username;
}
/**
* @param string $username
*/
public function setUsername($username)
{
$this->username = $username;
}
/**
* @return string
*/
public function getEmail()
{
return $this->email;
}
/**
* @param string $email
*/
public function setEmail($email)
{
$this->email = $email;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @param string $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* @return string
*/
public function getPassword()
{
return $this->password;
}
/**
* @param string $password
*/
public function setPassword($password)
{
$this->password = $password;
}
/**
* @return string
*/
public function getPhone()
{
return $this->phone;
}
/**
* @param string $phone
*/
public function setPhone($phone)
{
$this->phone = $phone;
}
/**
* @return string
*/
public function getStatus()
{
return $this->status;
}
/**
* @param string $status
*/
public function setStatus($status)
{
$this->status = $status;
}
/**
* @return string
*/
public function getToken()
{
return $this->token;
}
/**
* @param string $token
*/
public function setToken($token)
{
$this->token = $token;
}
/**
* @return int
*/
public function getTokenGeneratedAt()
{
return $this->tokenGeneratedAt;
}
/**
* @param int $tokenGeneratedAt
*/
public function setTokenGeneratedAt($tokenGeneratedAt)
{
$this->tokenGeneratedAt = $tokenGeneratedAt;
}
/**
* @return string
*/
public function getTimeZone()
{
return $this->timeZone;
}
/**
* @param string $timeZone
*/
public function setTimeZone($timeZone)
{
$this->timeZone = $timeZone;
}
/**
* Finish setting & getting.
*/
/**
* @return User|false
*/
public function getLoggedIn()
{
$userModel = (new StringUtility())->getClassNameFromNamespace(get_class($this));
$result = (new UserAuthentication())->getAllLoggedIn([$userModel]);
return isset($result[$userModel]) ? $result[$userModel] : false;
}
/**
* @param $key String Specify the user property / attribute which is used to search for an existing user
* @param $value String
* @param $password String
*
* @throws \Exception
*
* @return bool|Output
*/
public function login($key, $value, $password)
{
// determine which mapper should be called
$mapperName = $this->getMapperName();
switch ($key) {
case 'email':
// get user by username
$output = (new $mapperName())->getOneByEmail($value);
break;
case 'username':
// get user by username
$output = (new $mapperName())->getOneByUsername($value);
break;
default:
throw new \Exception("key: {$key} is not a valid user property");
break;
}
if (!isset($output) || !$output instanceof Output) {
return false;
}
if ($output->getSuccess() !== true) {
$output->setSuccess(false);
$output->setMessage('Please try again');
return $output;
}
$foundUser = $output->getData();
$output = new Output();
if (empty($foundUser) || !$foundUser instanceof self) {
$output->setSuccess(false);
$output->setMessage('Please try again');
return $output;
}
return (new UserAuthentication())->login($foundUser, $password);
}
/**
* @throws \Exception
*
* @return Output
*/
public function logout()
{
(new UserAuthentication())->logout($this);
}
/**
* @param $email
*
* @throws \Exception
*
* @return bool|Output
*/
public function forgotPassword($email)
{
/**
* Start validating email.
*/
$requiredRule = new ValidatorRule('required');
$emailRule = new ValidatorRule('email');
$emailInput = new Input('email', [$requiredRule, $emailRule]);
$validatorOutput = (new Validator([$emailInput], ['email' => $email]))->validate();
$output = new Output();
if ($validatorOutput->getSuccess() !== true) {
$output->setSuccess(false);
$output->setMessages($validatorOutput->getMessages());
return $output;
}
/**
* Finish validating email & token.
*/
// verify user: check to see if the email exists in db and is active and parent id is 0
$mapperName = $this->getMapperName();
$mapperOutput = (new $mapperName())->getOneByEmail($email, null, 'active');
if (!$mapperOutput instanceof Output) {
return false;
}
if ($mapperOutput->getSuccess() !== true) {
$output->setSuccess(false);
$output->setMessage('Could not find any active user with this email');
return $output;
}
// get user
$user = $mapperOutput->getData();
if (!$user instanceof self) {
$output->setSuccess(false);
$output->setMessage('Could not find any active user with this email');
return $output;
}
return (new UserAuthentication())->forgetPassword($user);
}
/**
* @param $email
* @param $resetPasswordToken
* @param $password
* @param $passwordConfirmation
*
* @throws \Exception
*
* @return Output
*/
public function resetPassword($email, $resetPasswordToken, $password, $passwordConfirmation)
{
/**
* Start validating email & token.
*/
$requiredRule = new ValidatorRule('required');
$emailRule = new ValidatorRule('email');
$emailInput = new Input('email', [$requiredRule, $emailRule]);
$validatorOutput = (new Validator([$emailInput], ['email' => $email]))->validate();
$output = new Output();
if ($validatorOutput->getSuccess() !== true) {
$output->setSuccess(false);
$output->setMessages($validatorOutput->getMessages());
return $output;
}
/**
* Finish validating email & token.
*/
/**
* Start verifying email & token combination.
*/
$mapperName = $this->getMapperName();
$mapperOutput = (new $mapperName())->getOneByEmail($email, null, 'active');
if (!$mapperOutput instanceof Output) {
return false;
}
if ($mapperOutput->getSuccess() !== true) {
$output->setSuccess(false);
$output->setMessage('Email does not exist');
return $output;
}
$user = $mapperOutput->getData();
if (!$user instanceof self) {
$output->setSuccess(false);
$output->setMessage('Could not find any user with this email');
return $output;
}
return (new UserAuthentication())->resetPassword($user, $resetPasswordToken, $password, $passwordConfirmation);
}
/**
* @param $email
* @param $token
*
* @throws \Exception
*
* @return Output
*/
public function checkTokenIsValidByEmail($email, $token)
{
$output = new Output();
/**
* Start validating email & token.
*/
$requiredRule = new ValidatorRule('required');
$emailRule = new ValidatorRule('email');
$emailInput = new Input('email', [$requiredRule, $emailRule]);
$tokenInput = new Input('token', [$requiredRule]);
$validatorOutput = (new Validator([
$emailInput,
$tokenInput,
], ['email' => $email, 'token' => $token]))->validate();
if (!$validatorOutput instanceof Output) {
return false;
}
if ($validatorOutput->getSuccess() !== true) {
$output->setSuccess(false);
$output->setMessages($validatorOutput->getMessages());
return $output;
}
/**
* Finish validating email & token.
*/
/**
* Start verifying email & token combination.
*/
$mapperName = $this->getMapperName();
$mapperOutput = (new $mapperName())->getOneByEmail($email, null, 'active');
if (!$mapperOutput instanceof Output) {
return false;
}
if ($mapperOutput->getSuccess() !== true) {
$output->setSuccess(false);
$output->setMessage('Email does not exist');
return $output;
}
$user = $mapperOutput->getData();
if (!$user instanceof self) {
$output->setSuccess(false);
$output->setMessage('Could not find any user with this email');
return $output;
}
if ($user->getToken() === $token) {
// check token lifetime
$tokenGeneratedAt = $user->getTokenGeneratedAt();
$tokenLivedTime = time() - strtotime($tokenGeneratedAt);
$tokenLifetime = Registry::getConfigClass()->get('tokenLifetime');
$tokenExpired = $tokenLivedTime <= $tokenLifetime ? false : true;
} else {
$tokenExpired = true;
}
/*
* Finish verifying email & token combination
*/
if ($tokenExpired === false) {
$output->setSuccess(true);
$output->setData($user);
} else {
$output->setSuccess(false);
$output->setMessage('Token is expired');
}
return $output;
}
}