HEX
Server: LiteSpeed
System: Linux s917.lon1.mysecurecloudhost.com 4.18.0-477.21.1.lve.1.el8.x86_64 #1 SMP Tue Sep 5 23:08:35 UTC 2023 x86_64
User: assibfaf (3034)
PHP: 7.4.33
Disabled: NONE
Upload Files
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');
    }
}