<?php

/**
 * IMPORTANT NOTE
 * The code of this system is closed and a private proprietary of Flex Solutions.
 * A written authorization/license from Flex Solutions is required before using or modifying this code.
 * Email: sales@flexsolution.biz, Phone: +962795342585, Website: http://www.flexsolutions.biz
 */

/**
 * This is the model class for table "user".
 *
 * The followings are the available columns in table 'user':
 * @property integer $id
 * @property string $username
 * @property string $password
 * @property string $email
 * @property integer $location_id
 * @property string $status
 * @property integer $created_by
 * @property string $created_date
 * @property integer $last_edited_by
 * @property string $last_edited_date
 *
 * The followings are the available model relations:
 * @property Ticket[] $tickets
 * @property Location $location
 */
class User extends LsmsActiveRecord {

    public $password_repeat;
    public $role;
    public $old_password;
    public $password_strength;
    public $is_LDAP;

    /**
     * Returns the static model of the specified AR class.
     * @param string $className active record class name.
     * @return User the static model class
     */
    public static function model($className = __CLASS__) {
	return parent::model($className);
    }

    /**
     * @return string the associated database table name
     */
    public function tableName() {
	return 'user';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules() {
	// NOTE: you should only define rules for those attributes that
	// will receive user inputs.
	return array(
	    array('status,role', 'required'),
	    array('location_id', 'numerical', 'integerOnly' => true),
	    array('username, password, email', 'length', 'max' => 255),
	    array('status', 'length', 'max' => 8),
	    array('email', 'email'),
	    array('password', 'compare'),
	    array('password_repeat,role,password_strength', 'safe'),
	    array('password', 'passwordStrengthValidate'),
	    array('username', 'unique'),
	    array('email', 'unique'),
	    //Checking if the user is person on system and is foomd manager for give him Food Manager Role
	    array('role', 'foodManagerValidate'),
	    //Checking if username is found on LDAP system and return email if yes
	    array('username', 'usernameValidate'),
	    //The Following two lines Check if user have password and email or just username
	    array('password', 'passwordNonLDAPValidate'),
	    array('email', 'emailNonLDAPValidate'),
	    // The following rule is used by search().
	    // Please remove those attributes that should not be searched.
	    array('id, username, password, email, location_id, status', 'safe', 'on' => 'search'),
	);
    }

    /**
     * @return array relational rules.
     */
    public function relations() {
	// NOTE: you may need to adjust the relation name and the related
	// class name for the relations automatically generated below.
	return array(
	    'tickets' => array(self::HAS_MANY, 'Ticket', 'user_id'),
	    'location' => array(self::BELONGS_TO, 'Location', 'location_id'),
	    'poses' => array(self::HAS_MANY, 'Pos', 'user_id')
	);
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels() {
	return array(
	    'username' => yii::t('default', 'Username'),
	    'password' => yii::t('default', 'Password'),
	    'email' => yii::t('default', 'Email'),
	    'location_id' => yii::t('default', 'Location'),
	    'status' => yii::t('default', 'Status'),
	    'role' => yii::t('default', 'Role'),
	    'password_repeat' => yii::t('default', 'Confirm Password'),
	    'is_LDAP' => yii::t('default', 'LDAP User'),
	);
    }

    /**
     * @return array customized attribute labels Tooltips (name=>label tooltips)
     */
    public function attributeLabelsPopover() {
	return array(
	    'username' => yii::t('default', 'tooltip_username'),
	    'password' => yii::t('default', 'tooltip_password'),
	    'email' => yii::t('default', 'tooltip_email'),
	    'location_id' => yii::t('default', 'tooltip_location_id'),
	    'status' => yii::t('default', 'tooltip_status'),
	    'role' => yii::t('default', 'tooltip_role'),
	    'password_repeat' => yii::t('default', 'tooltip_password_repeat'),
	    'is_LDAP' => yii::t('default', 'tooltip_is_LDAP'),
	);
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
     */
    public function search() {
	$criteria = new CDbCriteria;

	$criteria->compare('username', $this->username, true);
	$criteria->compare('password', $this->password, true);
	$criteria->compare('email', $this->email, true);
	$criteria->compare('location_id', $this->location_id);
	$criteria->compare('status', $this->status, false);
	$pageSize = $this->yiiparam('pageSize');

	return new CActiveDataProvider($this, array(
	    'pagination' => array('pageSize' => $pageSize,),
	    'criteria' => $criteria,
	));
    }

    public static function getAll($status = null) {
	if ($status == "Active") {
	    return User::model()->active()->findAll(array('order' => 'username'));
	} else {
	    return User::model()->findAll(array('order' => 'username'));
	}
    }

    /**
     * perform one-way encryption on the password before we store it in the database
     */
    protected function afterValidate() {
	parent::afterValidate();

	if (!$this->hasErrors()) {
	    if (isset($this->password) && ($this->password != "")) {
		if (isset($this->old_password) && ($this->old_password != "")) {
		    //check if the password has been changed
		    if ($this->password != $this->old_password) {
			// encryption the new password
			$this->password = $this->encrypt($this->email . $this->password); // note that we add a salt to the password "the user email"
		    }
		} else {
		    //If it is new User there is not old password
		    $this->password = $this->encrypt($this->email . $this->password); // note that we add a salt to the password "the user email"
		}
	    }
	}
    }

    //the encryption function
    public static function encrypt($value) {
	return md5(sha1($value));
    }

    protected function afterFind() {
	parent::afterFind();
	$this->role = User::getAssignedRolesNames($this->id);
	$this->is_LDAP = $this->username == '' ? 0 : 1;
	return true;
    }

    //Get the current assigned roles to an user
    public function getAssignedRolesNames($id) {
	$assigned_roles = Yii::app()->authManager->getRoles($id);
	if (isset($assigned_roles) && (count($assigned_roles) > 0)) {
	    foreach ($assigned_roles as $role) {
		return $role->name;
	    }
	} else {
	    return yii::t('default', 'Non Role');
	}
    }

    // the following function will return all defined roles
    public static function getUserRoleOptions() {
	return CHtml::listData(Yii::app()->authManager->getRoles(), 'name', 'name');
    }

    //Get Identifier For user which is username if the user in LDAP or email If the user does not have a username
    public function getIdentifier() {
	$identifier = '';
	if ($this->username != "") {
	    $identifier = $this->username;
	} else {
	    $identifier = $this->email;
	}
	return $identifier;
    }

    //Checking if the user is person on system and is foomd manager for give him Food Manager Role
    public function foodManagerValidate($attribute, $params) {
	if ($this->role == 'Food Manager') {
	    if (isset($this->username) && ($this->username != "")) {
		$person_model = Person::model()->findByAttributes(array('alias' => $this->username));
		if ($person_model != null) {
		    if ($person_model->is_food_manager == 0) {
			$this->addError($attribute, Yii::t('default', "The person ({n}) should be marked as a food manager.", $this->username));
		    } else
		    if ($person_model->department_id != null && $this->location_id != null && $this->location_id != "")
			if (!Department::checkInsideLocation($person_model->department_id, $this->location_id))
			    $this->addError('location_id', Yii::t('default', "You should select the same location of the person ({n}).", $person_model->department->location->code));
		} else {
		    $this->addError($attribute, Yii::t('default', "You should first register the person ({n}) in the system", $this->username));
		}
	    } else {
		$this->addError($attribute, Yii::t('default', "The Food Manager must be LDAP User."));
	    }
	}
    }

    //Checking if username is found on LDAP system and return email if yes
    public function usernameValidate($attribute, $params) {
	if (isset($this->username) && ($this->username != "")) {
	    // Get user email from LDAP based on the username (i.e. based on the user alias)
	    $error_message = LDAP::getUserEmailByAlias($this->username, $email);
	    if ($error_message != "") {
		$this->addError($attribute, $error_message);
	    } else {
		$this->email = $email;
	    }
	}
    }

    //Check if user have password and email or just username
    public function emailNonLDAPValidate($attribute, $params) {
	if (!isset($this->username) || ($this->username == "")) {
	    if ((!isset($this->email)) || ($this->email == "")) {
		$this->addError($attribute, Yii::t('default', "The Email can not be blank, either the username or the email and password shoud be entered."));
	    }
	}
    }

    //Check if user have password and email or just username
    public function passwordNonLDAPValidate($attribute, $params) {

	if (!isset($this->username) || ($this->username == "")) {
	    if ((!isset($this->password)) || ($this->password == "")) {
		$this->addError($attribute, Yii::t('default', "The Password can not be blank, either the username or the email and password shoud be entered."));
	    }
	}
    }

    // validate the password strength
    public function passwordStrengthValidate($attribute, $params) {
	if (!isset($this->username) || ($this->username == "")) {
	    if ($this->password_strength == "too short" || $this->password_strength == "weak") {
		$this->addError("password", Yii::t('default', "The password should not be weak."));
	    }
	}
    }

    //Assign Role to this user and Revoke All other
    public function setRole($selected_role) {
	try {
	    $authManager = Yii::app()->authManager;
	    foreach ($authManager->getRoles() as $role) {
		$authManager->revoke($role->name, $this->id);
	    }

	    $authManager->assign($selected_role, $this->id);
	} catch (Exception $e) {
	    Yii::app()->user->setFlash('error', Yii::t('default', 'The Role has not been updated successfully'));
	}
    }

    // The following function used for display ChangePassword at menu item or not
    public static function canChangePassword($id) {
	$user = User::model()->findByAttributes(array('id' => $id));
	if (isset($user->password) && ($user->password != "")) {
	    return true;
	} else {
	    return false;
	}
    }

    /*
     * The Following Function Is resposible for return All Department Alocated in the geomarket wich user belong to it 
     */

    public static function getDepartmentInGeomarket() {
	$result = array();
	$result[''] = yii::t('default', 'All Departments');
	//When user role is Super Admin he can see all Department
	if (Yii::app()->user->checkAccess('Super Admin')) {
	    $department_array = Department::model()->findAll();
	    foreach ($department_array as $department) {
		$result[$department->id] = $department->name;
	    }
	} else {
	    //when user is not super admin he can see all Departments wich located at locations in his geomarket
	    $location_array = User::model()->getLocationsInGeomarket();
	    foreach ($location_array as $key => $value) {
		$department_array = Department::model()->findAllByAttributes(array('location_id' => $key));
		foreach ($department_array as $department) {
		    $result[$department->id] = $department->name;
		}
	    }
	}
	return $result;
    }

    /*
     * The Following Function Is resposible for return All Location Alocated in the geomarket wich user belong to it
     */

    public static function getLocationsInGeomarket($check_facility_admin_location = false) {
	$result = array();
	$result[''] = yii::t('default', 'All Location');
	//When user role is Super Admin he can see all Location
	if (Yii::app()->user->checkAccess('Super Admin')) {
	    $location_array = Location::model()->findAll();
	    foreach ($location_array as $location) {
		$result[$location->id] = $location->code;
	    }
	} else {
	    $user = User::model()->findByPk(Yii::app()->user->getId());
	    if (Yii::app()->user->checkAccess('Food Manager')) {
		$person_model = Person::model()->findByAttributes(array('alias' => $user->username));
		if ($person_model->is_food_manager == 1)
		    $result[$user->location->id] = $user->location->code;
	    } else {
		//when user is not super admin he can see all locations in his geomarket

		if ($user->location != null) {
		    if (Yii::app()->user->checkAccess('Facility Admin') && $check_facility_admin_location)
			$result[$user->location->id] = $user->location->code;
		    else {
			$geomarket = $user->location->geomarket;
			if ($geomarket != null) {
			    $location_array = Location::model()->findAllByAttributes(array('geomarket_id' => $geomarket->id));
			    foreach ($location_array as $location) {
				$result[$location->id] = $location->code;
			    }
			}
		    }
		}
	    }
	}
	return $result;
    }

    /*
     * The Following Function Is resposible for return All POSs Alocated in the geomarket wich user belong to it
     */

    public static function getPOSInGeomarket() {
	$result = array();
	$result[''] = yii::t('default', 'All POSs');
	//When user role is Super Admin he can see all POSs
	if (Yii::app()->user->checkAccess('Super Admin')) {
	    $pos_array = Pos::model()->findAll();
	    foreach ($pos_array as $pos) {
		$result[$pos->id] = $pos->name;
	    }
	} else {
	    //When user is not super admin he can see all POSs wich located at locations in his geomarket
	    $location_array = User::model()->getLocationsInGeomarket();
	    foreach ($location_array as $key => $value) {
		$pos_array = Pos::model()->findAllByAttributes(array('location_id' => $key));
		foreach ($pos_array as $pos) {
		    $result[$pos->id] = $pos->name;
		}
	    }
	}
	return $result;
    }

    public static function checkFoodManagerUser() {
	if (Yii::app()->user->checkAccess('Food Manager')) {
	    $user_model = User::model()->findByPk(Yii::app()->user->id);
	    $person_model = Person::model()->findByAttributes(array('alias' => $user_model->username));
	    if ($person_model->is_food_manager == 1)
		return true;
	    else
		return false;
	}else {
	    return false;
	}
    }

    public static function getAllFacilityAdmin($location_id, $id, $department_name, $item_html) {
	if ($location_id != null && $location_id != "") {
	    $user_models = User::model()->active()->findAllByAttributes(array('location_id' => $location_id));
	    if ($user_models != null) {
		foreach ($user_models as $user_model) {
		    $role = User::getAssignedRolesNames($user_model->id);
		    if ($role == 'Facility Admin')
			LSMSMail::sendMail('Items requested for ' . $department_name . '–' . $id, 'Dear ' . $user_model->identifier . ',<br/><br/> You have successfully requested the items below for the department (' . $department_name . '): <br/>' . $item_html . '<br/> The attached file contains full details about the request.', $user_model->email, null, 'protected\upload\pdfs\Item-' . $id . '.pdf');
		}
	    }
	}
    }

    public static function getIdsOfDepartments() {
	$user = User::model()->findByPk(Yii::app()->user->getId());
	$geomarket_id = -1;

	if (Yii::app()->user->checkAccess('Food Manager')) {
	    $person_model = Person::model()->findByAttributes(array('alias' => $user->username));
	    if ($person_model->is_food_manager == 1)
		return $person_model->department->id;
	} else {
	    if ($user->location != null) {
		if (Yii::app()->user->checkAccess('Facility Admin')) {
		    $cr = new CDbCriteria();
		    $cr->select = "t.id";
		    $cr->condition = "location_id=" . $user->location_id;

		    $model = Department::model();
		    $department_ids = $model->commandBuilder->createFindCommand(
				    $model->tableName(), $cr)->queryColumn();
		    if ($department_ids != null)
			return implode(',', $department_ids);
		} else {
		    $geomarket_id = $user->location->geomarket_id;
		    //when user is not super admin he can see all locations in his geomarket
		    $cr = new CDbCriteria();
		    $cr->select = "t.id";
		    $cr->join = 'inner join location on location.id = t.location_id';
		    $cr->condition = "geomarket_id=" . $geomarket_id;

		    $model = Department::model();
		    $department_ids = $model->commandBuilder->createFindCommand(
				    $model->tableName(), $cr)->queryColumn();
		    if ($department_ids != null)
			return implode(',', $department_ids);
		}
	    }
	}
	return -1;
    }

}
