File: /home/assibfaf/assignmentghostwriter.com/prox-classes/User/Employee.php
<?php
/**
* @package Proxim
* @author Davison Pro, Chris Mugo <davisonpro.coder@gmail.com>
* @copyright 2019 Proxim
* @version 1.5.0
* @since File available since Release 1.0.0
*/
namespace Proxim\User;
use Db;
use Proxim\Database\DbQuery;
use Proxim\Cache\Cache;
use Proxim\ObjectModel;
use Proxim\Application;
use Proxim\Order\Order;
use Proxim\Validate;
use Proxim\Tools;
use Proxim\Util\ArrayUtils;
use Proxim\Util\DateUtils;
use Proxim\Crypto\Hashing;
/**
* Employee
*/
class Employee extends ObjectModel {
const START_ID = 1353442;
/** User groups */
const GROUP_ADMIN = 1;
const GROUP_EDITOR = 2;
const GROUP_WRITER = 3;
const GROUP_SUB_ADMIN = 4;
/** Writer Category **/
const CATEGORY_BEST = 2;
const CATEGORY_ESL = 3;
const CATEGORY_ENL = 4;
/** Writer Working Status **/
const STATUS_WORKING = 2;
const STATUS_CANNOT_WORK = 4;
const STATUS_NEVER_WORK = 5;
/** @var $id Employee ID */
public $id;
public $employee_group;
public $email;
public $first_name;
public $middle_name;
public $last_name;
public $gender = 'male';
public $phone;
public $writer_category = self::CATEGORY_BEST;
public $academic_level = LEVEL_COLLEGE;
public $employee_rating;
public $employee_status = self::STATUS_WORKING;
public $avatar;
public $about;
public $facebook_profile;
public $linkedin_profile;
public $last_pay = 0;
public $total_paid = 0;
public $total_orders_revised = 0;
public $total_orders_rejected = 0;
public $email_notifications = 1;
public $password;
public $reset_password_token;
public $reset_password_validity;
public $last_passwd_gen;
public $secure_key;
public $policy_accepted = 0;
public $policy_accepted_at;
public $is_started = 0;
public $is_banned = 0;
public $push_notifications = 0;
public $live_notifications_counter = 0;
public $live_notifications_lastid;
public $live_messages_counter = 0;
public $live_messages_lastid;
public $notification_sound = 1;
public $last_login;
public $last_activity;
public $reg_date;
/** @var bool is the user logged in */
public $logged = false;
public $is_admin = false;
public $is_editor = false;
public $is_writer = false;
/** Writer Percent **/
public $writer_percent = 0;
/** Default profile picture */
public $user_picture_default;
/** User picture */
public $user_picture;
public $writer_category_title;
public $academic_level_title;
public $employee_status_title;
/**
* @see ObjectModel::$definition
*/
public static $definition = array(
'table' => 'employee',
'primary' => 'employee_id',
'fields' => array(
'employee_group' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt', 'required' => true),
'email' => array('type' => self::TYPE_STRING, 'validate' => 'isEmail', 'required' => true, 'size' => 255),
'first_name' => array('type' => self::TYPE_STRING, 'validate' => 'isName', 'required' => false, 'size' => 255),
'middle_name' => array('type' => self::TYPE_STRING, 'validate' => 'isName', 'required' => false, 'size' => 255),
'last_name' => array('type' => self::TYPE_STRING, 'validate' => 'isName', 'required' => false, 'size' => 255),
'gender' => array('type' => self::TYPE_STRING),
'phone' => array('type' => self::TYPE_STRING, 'validate' => 'isPhoneNumber', 'required' => false, 'size' => 50),
'writer_category' => array('type' => self::TYPE_INT, 'validate' => 'isInt'),
'academic_level' => array('type' => self::TYPE_INT, 'validate' => 'isInt'),
'employee_rating' => array('type' => self::TYPE_INT, 'validate' => 'isInt'),
'employee_status' => array('type' => self::TYPE_INT, 'validate' => 'isInt'),
'avatar' => array('type' => self::TYPE_STRING),
'about' => array('type' => self::TYPE_STRING),
'facebook_profile' => array('type' => self::TYPE_STRING),
'linkedin_profile' => array('type' => self::TYPE_STRING),
'last_pay' => array('type' => self::TYPE_FLOAT, 'validate' => 'isPrice'),
'total_paid' => array('type' => self::TYPE_FLOAT, 'validate' => 'isPrice'),
'total_orders_revised' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'),
'total_orders_rejected' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'),
'email_notifications' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
'password' => array('type' => self::TYPE_STRING, 'validate' => 'isPasswd', 'required' => true, 'size' => 255),
'reset_password_token' => array('type' => self::TYPE_STRING, 'validate' => 'isSha1', 'size' => 40),
'reset_password_validity' => array('type' => self::TYPE_DATE, 'validate' => 'isDateOrNull'),
'last_passwd_gen' => array('type' => self::TYPE_DATE, 'validate' => 'isDateOrNull'),
'secure_key' => array('type' => self::TYPE_STRING, 'validate' => 'isMd5'),
'policy_accepted' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
'policy_accepted_at' => array('type' => self::TYPE_DATE, 'validate' => 'isDateOrNull'),
'is_started' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
'is_banned' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
'push_notifications' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
'live_notifications_counter' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'),
'live_notifications_lastid' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'),
'live_messages_counter' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'),
'live_messages_lastid' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'),
'notification_sound' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
'last_login' => array('type' => self::TYPE_DATE, 'validate' => 'isDateOrNull'),
'last_activity' => array('type' => self::TYPE_DATE, 'validate' => 'isDateOrNull'),
'reg_date' => array('type' => self::TYPE_DATE, 'validate' => 'isDate')
)
);
/**
* constructor.
*
* @param null $id
*/
public function __construct($id = null)
{
global $globals;
parent::__construct($id);
if ($this->id) {
$this->is_admin = ($this->employee_group == self::GROUP_ADMIN)? true: false;
$this->is_editor = ($this->employee_group == self::GROUP_EDITOR)? true: false;
$this->is_writer = ($this->employee_group == self::GROUP_WRITER)? true: false;
$academicLevels = $globals['academicLevels'];
$academic_level = $this->academic_level ? ArrayUtils::get($academicLevels, $this->academic_level) : ArrayUtils::get($academicLevels, LEVEL_COLLEGE);
$this->academic_level_title = ArrayUtils::get($academic_level, 'title');
$writerPreferences = $globals['writerPreferences'];
$writer_preference = $this->writer_category ? ArrayUtils::get($writerPreferences, $this->writer_category) : ArrayUtils::get($writerPreferences, self::CATEGORY_BEST);
$this->writer_category_title = ArrayUtils::get($writer_preference, 'title');
}
}
public function add($autoDate = true, $nullValues = true)
{
$this->secure_key = md5(uniqid(rand(), true));
$this->last_passwd_gen = DateUtils::now();
if ( !$this->getNextEmployeeId() ) {
$this->employee_group = self::GROUP_ADMIN;
$this->id = self::START_ID;
} else {
$next_employee_id = Db::getInstance()->getValue('SELECT MAX(`employee_id`)+2 FROM `' . PROX_DB_PREFIX . 'employee`');
$this->id = $next_employee_id;
}
$this->force_id = true;
$success = parent::add($autoDate, $nullValues);
return $success;
}
/**
* Return user instance from its e-mail (optionally check password).
*
* @param string $email e-mail
* @param string $plaintextPassword Password is also checked if specified
*
* @return bool|User User instance
*/
public function getByEmail($email, $plaintextPassword = null)
{
if (!Validate::isEmail($email) || ($plaintextPassword && !Validate::isPasswd($plaintextPassword))) {
return false;
}
$sql = new DbQuery();
$sql->select('e.*');
$sql->from('employee', 'e');
$sql->where('e.`email` = \'' . pSQL($email) . '\'');
$result = Db::getInstance()->getRow($sql);
if (!$result) {
return false;
}
$crypto = new Hashing();
$passwordHash = $result['password'];
$shouldCheckPassword = !is_null($plaintextPassword);
if ($shouldCheckPassword && !$crypto->checkHash($plaintextPassword, $passwordHash)) {
return false;
}
$this->id = $result['employee_id'];
foreach ($result as $key => $value) {
if (property_exists($this, $key)) {
$this->{$key} = $value;
}
}
if ($shouldCheckPassword && !$crypto->isFirstHash($plaintextPassword, $passwordHash)) {
$this->password = $crypto->hash($plaintextPassword);
$this->update();
}
return $this;
}
/**
* Check user information and return user validity.
*
* @return bool user validity
*/
public function isLogged()
{
/* Employee is valid only if it can be load and if session is active */
return $this->logged == 1 && (int) $this->id && Employee::checkPassword($this->id, $this->password);
}
/**
* Soft logout, delete everything that links to the user
*
* @since 1.0.0
*/
public function logout() {
// remove auth_token
if (isset(Application::getInstance()->container->cookie)) {
Application::getInstance()->container->cookie->userLogout();
}
$this->logged = false;
}
/**
* Check if employee password is the right one.
*
* @param int $employee_id Employee ID
* @param string $passwordHash Hashed password
*
* @return bool result
*/
public static function checkPassword($employee_id, $passwordHash)
{
if (!Validate::isUnsignedId($employee_id)) {
die(Tools::displayError());
}
$cacheId = 'Employee::checkPassword' . (int) $employee_id . '-' . $passwordHash;
if (!Cache::isStored($cacheId)) {
$sql = new DbQuery();
$sql->select('e.`employee_id`');
$sql->from('employee', 'e');
$sql->where('e.`employee_id` = ' . (int) $employee_id);
$sql->where('e.`password` = \'' . pSQL($passwordHash) . '\'');
$result = (bool) Db::getInstance(PROX_USE_SQL_SLAVE)->getValue($sql);
Cache::store($cacheId, $result);
return $result;
}
return Cache::retrieve($cacheId);
}
/**
* Fill Reset password unique token with random sha1 and its validity date. For forgot password feature.
*/
public function stampResetPasswordToken()
{
$salt = $this->id . '-' . $this->secure_key;
$this->reset_password_token = sha1(time() . $salt);
$this->reset_password_validity = date('Y-m-d H:i:s', strtotime('+' . 1440 . ' minutes'));
}
/**
* Test if a reset password token is present and is recent enough to avoid creating a new one (in case of customer triggering the forgot password link too often).
*/
public function hasRecentResetPasswordToken()
{
if (!$this->reset_password_token || $this->reset_password_token == '') {
return false;
}
// TODO maybe use another 'recent' value for this test. For instance, equals password validity value.
if (!$this->reset_password_validity || strtotime($this->reset_password_validity) < time()) {
return false;
}
return true;
}
/**
* Returns the valid reset password token if it validity date is > now().
*/
public function getValidResetPasswordToken()
{
if (!$this->reset_password_token || $this->reset_password_token == '') {
return false;
}
if (!$this->reset_password_validity || strtotime($this->reset_password_validity) < time()) {
return false;
}
return $this->reset_password_token;
}
/**
* Delete reset password token data.
*/
public function removeResetPasswordToken()
{
$this->reset_password_token = null;
$this->reset_password_validity = null;
}
/**
* This method return the ID of the next employee.
*
* @since 1.0.0
*
* @return int
*/
public function getNextEmployeeId()
{
return Db::getInstance()->getValue('
SELECT employee_id
FROM ' . PROX_DB_PREFIX . 'employee
WHERE employee_id > ' . (int) $this->id . '
ORDER BY employee_id ASC');
}
}