<?php

/**
 * This is the model class for table "user".
 *
 * The followings are the available columns in table 'user':
 * @property string $name
 * @property string $firstname
 * @property string $lastname
 * @property string $email
 * @property string $password
 * @property string $pin
 * @property string $extension
 */
class User extends PhonalisaRecord
{

    const FAX_SEND_NOT_ALLOWED = 0;
    const FAX_SEND_ALLOWED = 1;
    const FAX_SEND_INHERIT_FROM_GROUP = 2;

    public $extension;
    public $name;
    public $oldName;
    public $firstname;
    public $lastname;
    public $email;
    public $password;
    public $pin;
    public $user_timezone;
    public $user_language;
    public $user_time_format;
    public $user_date_format;
    public $addressReferece;
    public $clip_int;
    public $clip_ext;
    public $clir_int;
    public $clir_ext;
    public $call_waiting;
    public $dnd;
    public $email_fax;
    public $email_vmail;
    public $email_external_missed_call;
    public $email_internal_missed_call;
    public $email_sip_account_offline;
    public $key_tone;
    public $ringtone_int;
    public $ringtone_ext;
    public $ringtone_queue;
    public $ringtone_callgroup;
    public $oldPin;
    public $newPin;
    public $confirmPin;
    public $oldPassword;
    public $newPassword;
    public $confirmPassword;
    public $changedPin;
    public $changedPassword;
    public $passwordPlainText;
    public $email_vmail_delete;
    public $zrtp;
    public $faxSendAllowed = User::FAX_SEND_INHERIT_FROM_GROUP;
    public $fax_header_text;
    public $fax_header_number;
    public $droptarget;
    public $short;
    public $value;
    public $descr;
    public $type;
    public $key;
    public $id;
    public $activeCallForward; /// NOT USED ANY MORE!
    public $simpleCallForwardJson; /// NOT USED ANY MORE!
    public $advancedCallForwardJson; /// NOT USED ANY MORE!
    public $phone_presence;
    public $jabber_presence;
    public $jabber_presence_text;
    public $jabber_pw_digest;
    public $group;
    public $groups = array();
    public $userMonitor;
    public $internMessageBeforeAnswer;
    public $externMessageBeforeAnswer;
    public static $_realUser = null;
    public static $_sudoUser = null;
    public $isSystemAdmin = false;
    public $settingsId;
    public $isDedicatedFaxUser;
    public $scriptExtension;
    public $provisioningProfile;
    public $keyProfile;
    public $ldapId;
    public $ldapInterface;

    /* caching vars */
    private $_addressbooks_cache = array();
    private $_userGroupIds_cache = null;
    private $_userGroups_cache = null;
    private $_callGroupIds_cache = null;
    private $_queueIds_cache = null;
    public $callForwardSet;
    public $defaultCallForwardSet;
    public $accountBalance;

    public function behaviors()
    {
        return array(
            'AttributesBackupBehavior' => 'ext.AttributesBackupBehavior',
        );
    }

    public function getTypesHumanReadable($type)
    {
        $typeAsString = __('USER_TYPE_UNDEFINED');
        if ($type == User::LDAPImport) {
            $typeAsString = __('USER_TYPE_LDAP_IMPORT');
        }
        return $typeAsString;
    }

    // getter functions :
    public function getTimeFormat()
    {
        if ($this->user_time_format) {
            return $this->user_time_format;
        }
        return cfg('USER_TIME_FORMAT');
    }

    public function getDateFormat()
    {
        if ($this->user_time_format) {
            return $this->user_date_format;
        }
        return cfg('USER_DATE_FORMAT');
    }

    public function getTimeZone()
    {
        if ($this->user_timezone) {
            return $this->user_timezone;
        }
        return cfg('TIMEZONE');
    }

    public static function myAttributes()
    {
        return array(
            "extension" => 'extension',
            "name" => 'name',
            "group" => "group",
            "firstname" => 'firstname',
            "lastname" => "lastname",
            "email" => "email",
            "password" => "password",
            "pin" => "pin",
            "user_timezone" => "user_timezone",
            "user_language" => "user_language",
            "user_time_format" => "user_time_format",
            "user_date_format" => "user_date_format",
            "addressReferece" => "addressReferece",
            "phone_presence" => "phone_presence",
            "jabber_presence" => "jabber_presence",
            "jabber_presence_text" => "jabber_presence_text",
            "jabber_pw_digest" => "jabber_pw_digest",
            "clip_int" => "clip_int",
            "clip_ext" => "clip_ext",
            "clir_int" => "clir_int",
            "clir_ext" => "clir_ext",
            "call_waiting" => "call_waiting",
            "dnd" => "dnd",
            "email_fax" => "email_fax",
            "email_vmail" => "email_vmail",
            "email_external_missed_call" => "email_external_missed_call",
            "email_internal_missed_call" => "email_internal_missed_call",
            "key_tone" => "key_tone",
            "ringtone_int" => "ringtone_int",
            "ringtone_ext" => "ringtone_ext",
            "ringtone_queue" => "ringtone_queue",
            "ringtone_callgroup" => "ringtone_callgroup",
            "email_vmail_delete" => "email_vmail_delete",
            "email_sip_account_offline" => "email_sip_account_offline",
            "zrtp" => "zrtp",
            'faxSendAllowed' => 'faxSendAllowed',
            "fax_header_text" => "fax_header_text",
            "fax_header_number" => "fax_header_number",
            "droptarget" => "droptarget",
            "short" => "short",
            "value" => "value",
            "descr" => "descr",
            "type" => "type",
            "key" => "key",
            "id" => "id",
            'userMonitor' => 'userMonitor',
            'activeCallForward' => 'activeCallForward',
            'simpleCallForwardJson' => 'simpleCallForwardJson',
            'advancedCallForwardJson' => 'advancedCallForwardJson',
            'internMessageBeforeAnswer' => 'internMessageBeforeAnswer',
            'externMessageBeforeAnswer' => 'externMessageBeforeAnswer',
            'isSystemAdmin' => 'isSystemAdmin',
            'callForwardSet' => 'callForwardSet',
            'defaultCallForwardSet' => 'defaultCallForwardSet',
            'accountBalance' => 'accountBalance',
            'settingsId' => 'settingsId',
            'isDedicatedFaxUser' => 'isDedicatedFaxUser',
            "scriptExtension" => "scriptExtension",
            'provisioningProfile' => 'provisioningProfile',
            'keyProfile' => 'keyProfile',
            'ldapId' => 'ldapId',
            'ldapInterface' => 'ldapInterface'
        );
    }

    /**
     * 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);
    }

    public static function getRealUserId()
    {
        if (!isset(Yii::app()->user->id)) {
            Yii::app()->user->loginRequired();
        }

        if (isset(Yii::app()->user->realUserId)) {
            return Yii::app()->user->realUserId;
        }
        return Yii::app()->user->id;
    }

    public static function getCurrentRealUser()
    {
        if (self::$_realUser == null) {
            self::$_realUser = User::model()->findByPk(User::getRealUserId());
        }
        return self::$_realUser;
    }

    public static function getCurrentSudoUser()
    {
        if (Yii::app()->user->sudoUser != User::getRealUserId()) {

            if (self::$_sudoUser == null) {
                if (isset(Yii::app()->user->sudoUser)) {
                    self::$_sudoUser = User::model()->findByPk(Yii::app()->user->sudoUser);
                } else {
                    return new User(); //FIXME ??
                }
            }
            return self::$_sudoUser;
        }
        return User::getCurrentRealUser();
    }

    /**
     * @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('name, extension, pin, group', 'required'),
            array('ldapId, ldapInterface', 'required', 'on' => 'LdapImport'),
            array('zrtp, isDedicatedFaxUser, email_sip_account_offline', 'boolean'),
            array('password', 'required', 'on' => 'create'), // required only if you create new user
            array('password', 'ext.PhonalisaValidators.passwordStrength', "on" => array("create", "adminUpdate", "changePassword", "isSystemAdminUpdate")),
            array('addressReferece, internMessageBeforeAnswer, externMessageBeforeAnswer, droptarget, isSystemAdmin, '
                . 'jabber_pw_digest, settingsId, scriptExtension, keyProfile, provisioningProfile',
                'safe'
            ), // FIXME ?
            array('pin, oldPin, newPin, confirmPin, extension, fax_header_number, faxSendAllowed', 'numerical', 'integerOnly' => true), //new version for integer Pin and extension
            array('extension', 'ext.PhonalisaValidators.uniqueExtension'),
            array('name', 'isUnique'),
            array('extension', 'length', 'min' => 2, 'max' => 10),
            array('extension', 'match', 'pattern' => '/^[1-9]/', 'message' => __('USER_MODEL_SHOULD_NOT_START_WITH_ZERO_ERROR_MESSAGE')),
            array('firstname, confirmPassword, newPassword, oldPassword, short, value, descr, key_tone, key, type, call_waiting, ringtone_ext,ringtone_queue
					ringtone_int, email_vmail, email_fax,email_external_missed_call,email_internal_missed_call, dnd, clir_int, clir_ext, clip_int, clip_ext, lastname, email,
					user_language, user_timezone, user_time_format, user_date_format, fax_header_text, email_vmail_delete, ringtone_callgroup', 'length', 'max' => 255
            ),
            array('name', 'match', 'pattern' => '/^[1-9a-z]/', 'message' => __('USER_MODEL_SHOULD_NOT_START_WITH_ZERO_OR_PUNCTUATION_CHARACTERS_ERROR_MESSAGE')),
            array('name', 'match', 'pattern' => '/^[a-z0-9_.-]{1,}$/', 'message' => __('USER_MODEL_SHOULD_ONLY_CONTAIN_UNDERLINE_AND_DOT_PUNCTUATION_CHARACTERS_ERROR_MESSAGE')),
            array('email', 'email'),
            array('name, ldapId', 'length', 'max' => 128),
            array('password', 'length', 'encoding' => 'UTF-8', 'min' => 3, 'max' => 128),
            array('pin, oldPin, confirmPin, newPin', 'length', 'min' => 3, 'max' => 10),
            array('oldPin, newPin, confirmPin', 'required', 'on' => 'changePin'),
            array('oldPassword, newPassword, confirmPassword', 'required', 'on' => 'changePassword'),
            array('oldPassword', 'comparePassword', 'on' => 'changePassword'),
            array('newPassword', 'ext.PhonalisaValidators.passwordStrength'),
            array('oldPin', 'comparePin', 'on' => 'changePin'),
            array('confirmPassword', 'compare', 'compareAttribute' => 'newPassword', 'message' => __('USER_MODEL_PHONESETTINGS_CREDENTIALS_PASSWORD_REPEAT_ERROR_MESSAGE')),
            array('confirmPin', 'compare', 'compareAttribute' => 'newPin', 'message' => __('USER_MODEL_PHONESETTINGS_CREDENTIALS_PIN_REPEAT_ERROR_MESSAGE')),
            array('name', 'ext.PhonalisaValidators.compareAttributes', 'compareAttribute' => 'oldName', 'on' => 'isSystemAdminUpdate'),
            // The following rule is used by search().
            // Please remove those attributes that should not be searched.
            array('defaultCallForwardSet, callForwardSet, name, id, firstname, lastname, email, password, pin, extension, userMonitor, messageBeforeAnswer, externMessageBeforeAnswer', 'safe', 'on' => 'search'),
        );
    }
    ##### new unique-method starts #####

    public function isUnique($attribute, $params)
    {
        //FIXME: Check with the ExtensionManager if this extension already exists (e.g. Queues, IVR's, Conference Rooms etc)
        $model = User::model()->findByAttributes(array($attribute => $this->$attribute));
        if (!$model) {
            return true;
        }

        if ($this->isNewRecord() && $this->$attribute != $model->$attribute) {
            return true;
        } else if (!$this->isNewRecord() && $model->id == $this->id) {
            return true;
        }
        $this->addError($attribute, __('USER_MODEL_IS_UNIQUE_ERROR_MESSAGE'));
        return false;
    }
    ##### new unique-method ends #####
    ##### new comparePin-method starts #####

    public function comparePin($attribute, $params)
    {
        if ($this->pin !== $this->$attribute) {
            $this->addError($attribute, __('USER_MODEL_PHONESETTINGS_CREDENTIALS_OLD_PIN_ERROR_MESSAGE'));
            return false;
        }
        return true;
    }
    ##### new comparePin-method ends #####
    ##### new comparePassword-method starts #####

    public function comparePassword($attribute, $params)
    {
        $currentPassword = $this->$attribute = PasswordGenerator::cryptUserPassword($this, $_POST['User'][$attribute]);
        if ($this->password != $currentPassword) {
            $this->addError($attribute, __('USER_MODEL_PHONESETTINGS_CREDENTIALS_OLD_PASSWORD_ERROR_MESSAGE'));
            return false;
        }
        return true;
    }
    ##### new comparePassword-method ends #####

    /**
     * @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(
            'groups' => array(self::MANY_MANY, 'Groups', 'usersToGroups(userId, groupId)'),
            'sipaccounts' => array(self::HAS_MANY, 'SipAccounts', 'id'),
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'password' => __('USERS_MODEL_PASSWORD'),
            'group' => __('USERGROUPS_MODEL_GROUP'),
            'name' => __('USERS_MODEL_NAME'),
            'firstname' => __('USERS_MODEL_FIRSTNAME'),
            'lastname' => __('USERS_MODEL_LASTNAME'),
            'email' => __('USERS_MODEL_EMAIL'),
            'pin' => __('USERS_MODEL_PIN'),
            'extension' => __('USERS_MODEL_EXTENSION'),
            'user_timezone' => __('USERS_MODEL_USER_TIMEZONE'),
            'user_language' => __('USERS_MODEL_USER_LANGUAGE'),
            'user_time_format' => __('USERS_MODEL_USER_TIME_FORMAT'),
            'user_date_format' => __('USERS_MODEL_USER_DATE_FORMAT'),
            'addressReferece' => __('USERS_MODEL_ADDRESS_REFERENCE'),
            'phone_presence' => __('USERS_MODEL_PHONE_PRESENCE'),
            'jabber_presence' => __('USERS_MODEL_JABBER_PRESENCE'),
            "jabber_presence_text" => __('USERS_MODEL_JABBER_PRESENCE_TEXT'),
            'clip_int' => __('USERS_MODEL_CLIP_INTERNAL'),
            'clip_ext' => __('USERS_MODEL_CLIP_EXTERNAL'),
            'clir_int' => __('USERS_MODEL_CLIR_INTERNAL'),
            'clir_ext' => __('USERS_MODEL_CLIR_EXTERNAL'),
            'call_waiting' => __('USERS_MODEL_CALL_WAITING'),
            'dnd' => __('USERS_MODEL_DND'),
            'email_fax' => __('USERS_MODEL_FAX_NOTIFICATION'),
            'email_vmail' => __('USERS_MODEL_VOICE_MAIL_NOTIFICATION'),
            'email_external_missed_call' => __('USERS_MODEL_EXTERNAL_MISSED_CALL_MAIL_NOTIFICATION'),
            'email_internal_missed_call' => __('USERS_MODEL_INTERNAL_MISSED_CALL_MAIL_NOTIFICATION'),
            'key_tone' => __('USERS_MODEL_KEY_TONE'),
            'ringtone_int' => __('USERS_MODEL_RINGTONE_INTERNAL'),
            'ringtone_ext' => __('USERS_MODEL_RINGTONE_EXTERNAL'),
            'ringtone_queue' => __('USERS_MODEL_RINGTONE_QUEUE'),
            'ringtone_callgroup' => __('USERS_MODEL_RINGTONE_CALL_GROUP'),
            'oldPin' => __('PHONESETTINGS_CREDENTIALS_OLD_PIN'),
            'newPin' => __('PHONESETTINGS_CREDENTIALS_NEW_PIN'),
            'confirmPin' => __('PHONESETTINGS_CREDENTIALS_CONFIRM_PIN'),
            'oldPassword' => __('PHONESETTINGS_CREDENTIALS_OLD_PASSWORD'),
            'newPassword' => __('PHONESETTINGS_CREDENTIALS_NEW_PASSWORD'),
            'confirmPassword' => __('PHONESETTINGS_CREDENTIALS_CONFIRM_PASSWORD'),
            'email_vmail_delete' => __('USER_MODEL_EMAIL_VMAIL_DELETE'),
            'zrtp' => __('USERS_MODEL_ZRTP'),
            'faxSendAllowed' => __('USERS_MODEL_FAX_SENDING_ALLOWED'),
            'fax_header_text' => __('USERS_MODEL_FAX_HEADER_TEXT'),
            'fax_header_number' => __('USERS_MODEL_FAX_HEADER_NUMBER'),
            'droptarget' => __('USERS_MODEL_DROPTARGET'),
            'short' => __('PHONESETTINGS_USER_MODEL_SHORT'),
            'value' => __('PHONESETTINGS_USER_MODEL_VALUE'),
            'descr' => __('PHONESETTINGS_USER_MODEL_DESCRIPTION'),
            'type' => __('PHONESETTINGS_USER_MODEL_TYPE'),
            'key' => __('PHONESETTINGS_USER_MODEL_KEY'),
            'id' => __('USERS_MODEL_ID'),
            'internMessageBeforeAnswer' => __('USER_MODEL_INTERN_MESSAGE_BEFORE_ANSWER'),
            'externMessageBeforeAnswer' => __('USER_MODEL_EXTERN_MESSAGE_BEFORE_ANSWER'),
            'isSystemAdmin' => __('USER_IS_SYSTEM_ADMIN'),
            'accountBalance' => __('USER_MODEL_ACCOUNT_BALANCE'),
            'isDedicatedFaxUser' => __('USER_MODEL_IS_DEDICATED_FAX_USER'),
            "scriptExtension" => __("USER_MODEL_SCRIPT_EXTENSION"),
            'provisioningProfile' => __('USER_MODEL_PROVISIONING_PROFILE'),
            'keyProfile' => __('USER_MODEL_KEY_PROFILE'),
            'ldapId' => __('USER_MODEL_LDAP_ID'),
            'ldapInterface' => __('USER_LDAP_INTERFACE')
        );
    }

    public function getDisplayName()
    {
        return $this->lastname . ", " . $this->firstname . " <" . $this->extension . ">";
    }

    /**
     * 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($order = 'name')
    {
        // Warning: Please modify the following code to remove attributes that
        // should not be searched.

        $criteria = new CDbCriteria;
        $filter = $this->getFilter($criteria, $order);

        $filter['pagination'] = array(
            'pageSize' => getGridPageSize('user-grid'),
        );

        if ($filter != null) {
            $adminUserMax = PhonalisaLicenseManager::adminUserMax();
            $dataprovider = new CPhonalisaDataProvider($this, $filter);
            if ($adminUserMax >= 0) {
                $dataprovider->pagination->pageSize = $dataprovider->pagination->pageSize > $adminUserMax ? $adminUserMax : $dataprovider->pagination->pageSize;
                $dataprovider->totalItemCount = $dataprovider->totalItemCount > $adminUserMax ? $adminUserMax : $dataprovider->totalItemCount;
            }
            return $dataprovider;
        }
    }

    public function phonesettingsUserSearch()
    {
        $phonesettings = $this->renderPhonesettingsUser();
        $dataProvider = new CArrayDataProvider($phonesettings, array('pagination' => false));
        return $dataProvider;
    }

    public function phonesettingsTonesSearch()
    {
        $phonesettings = $this->renderPhonesettingsTones();
        $dataProvider = new CArrayDataProvider($phonesettings, array('pagination' => false));
        return $dataProvider;
    }

    public function PhonesettingsNotificationsSearch()
    {
        $phonesettings = $this->renderPhonesettingsNotifications();
        $dataProvider = new CArrayDataProvider($phonesettings, array('pagination' => false));
        return $dataProvider;
    }

    public function PhonesettingsCredentialsSearch()
    {
        $phonesettings = $this->renderPhonesettingsCredentials();
        $dataProvider = new CArrayDataProvider($phonesettings, array('pagination' => false));
        return $dataProvider;
    }

    public function beforeSave()
    {
        if ($this->isNewRecord()) {

            if (!$this->userLimitationAllowedMoreUsers()) {
                return false;
            }

            $this->passwordPlainText = $this->password;

            // create address entry for first user from wizard
            if ($this->scenario == 'firstUser') {
                $internAddressbook = Addressbook::model()->findByAttributes(array('type' => AddressbookType::intern));
                if ($internAddressbook) {
                    $newAddress = new Addresses;
                    $newAddress->n_given = $this->firstname;
                    $newAddress->n_family = $this->lastname;
                    $newAddress->contact_owner = 'intern';
                    $newAddress->contact_created = time();
                    $newAddress->contact_email = $this->email;
                    $newAddress->contact_tid = $internAddressbook->id;
                    $newAddress->tel_work = $this->extension;
                    $newAddress->source = AddressSourceType::SYSTEM;

                    if (!$newAddress->save()) {
                        $error = $newAddress->errors;
                    }
                    $this->addressReferece = $newAddress->id;
                }
            }
            $this->setDefaultForwardRule();
        }

        $model = User::model()->findByPk($this->id);
        if ($model == NULL) {
            $model = new User();
        }

        if ($this->password == '') {
            $this->password = $model->password; // use old password
        } else if ($this->password != $model->password) {
            // username:domain:password
            $this->jabber_pw_digest = md5($this->name . ':' . cfg('JABBER_DOMAIN') . ':' . $this->password);
            $this->password = md5($this->password . $this->id); // create new
        }

        if ($this->user_timezone == 'Default Timezone') {
            $this->user_timezone = '';
        }

        if ($this->user_language == 'Default Language') {
            $this->user_language = '';
        }

        if ($this->user_time_format == 'Default Time Format') {
            $this->user_time_format = '';
        }

        if ($this->user_date_format == 'Default Date Format') {
            $this->user_date_format = '';
        }

        // Fix for redirect bug in initializer
        if (($this->scenario != 'firstUser') && ($this->scenario != 'LdapImport')) {
            $userModel = User::getCurrentRealUser();
            if (($userModel != null) && ($userModel->id == $this->id)) {
                $this->isSystemAdmin = $userModel->isSystemAdmin;
            }
        }
        $this->updateSettings(array());
        return parent::beforeSave();
    }

    protected function setDefaultForwardRule()
    {
        $defaultCallforward = ForwardPreset::model()->findByAttributes(
                array(
                    'forwardType' => ForwardType::Disabled,
                    'type' => ForwardPresetType::PublicPreset
                )
        );

        if ($defaultCallforward) {
            $this->callForwardSet = $defaultCallforward->id;
            $this->defaultCallForwardSet = $defaultCallforward->id;
        }
    }

    public function afterSave()
    {
        if ($this->isNewRecord) {
            $attributes = array();
            $attributes["authname"] = $this->extension;
            $account = SipAccounts::model()->findByAttributes($attributes);
            if ($account == NULL) {
                // creating SipAccount for this user
                $account = SipAccounts::generateSipAccountForUser($this);
                $account->save();
            }

            if ($this->email != "" && cfg("SEND_WELCOME_EMAIL_USER") == "1") {
                $ucItem = new UCItem();
                $ucItem->setValueForKey("typ", "welcome_email");
                $ucItem->setValueForKey("owner_id", $this->id);
                $ucItem->setValueForKey("password", $this->passwordPlainText);
                $ucItem->save();
            }
            $this->createDefaultForwardKey();
        }
        ErgophoneHelper::createErgophoneConfigFilesForExtension($this->extension);

        if ($this->phonesNeedToTrigger()) {
            $this->triggerYourPhones();
        }
        return parent::afterSave();
    }

    protected function phonesNeedToTrigger()
    {
        $trigger = false;
        $fieldsToTrigger = array();
        $fieldsToTrigger[] = "firstname";
        $fieldsToTrigger[] = "lastname";
        $fieldsToTrigger[] = "extension";
        foreach ($fieldsToTrigger as $field) {
            if (!isset($this->oldAttributes[$field])) {
                continue;
            }
            if ($this->$field != $this->oldAttributes[$field]) {
                $trigger = true;
                break;
            }
        }
        return $trigger;
    }

    protected function createDefaultForwardKey()
    {
        $forwardKeyModel = new ForwardPresetPhoneKey();
        $forwardKeyModel->scenario = 'createUser';
        $forwardKeyModel->owner = $this->id;
        $forwardKeyModel->forwardPreset = $this->callForwardSet;
        $forwardKeyModel->key = '0';
        $forwardKeyModel->save();
    }

    public function getNameIndex()
    {
        return strtoupper(substr($this->name, 0, 1));
    }

    public function getSipAccounts()
    {
        $result = array();
        if (!empty($this->id)) {
            $result = SipAccounts::model()->findAllByAttributes(array("user_id" => $this->id));
        }
        return $result;
    }

    public function getSipAccountCount()
    {
        return SipAccounts::model()->countAllByAttributes(array("user_id" => $this->id));
    }

    public function getAudioFiles()
    {
        $audioFiles = array();
        $privateAudioFiles = AudioFile::model()->findAllByAttributes(array("user_id" => $this->id, 'type' => AudioFileType::privateType));

        $pSortHelper = array();
        foreach ($privateAudioFiles as $file) {
            $pSortHelper[strtolower($file->name)] = $file;
        }
        ksort($pSortHelper);
        $privateAudioFiles = array_values($pSortHelper);

        $systemAudioFiles = AudioFile::model()->findAllByAttributes(array('type' => AudioFileType::systemType));
        $sortHelper = array();
        foreach ($systemAudioFiles as $file) {
            $sortHelper[strtolower($file->name)] = $file;
        }
        ksort($sortHelper);
        $systemAudioFiles = array_values($sortHelper);

        $audioFiles = array_merge($systemAudioFiles, $privateAudioFiles);

        foreach ($audioFiles as $key => $file) {
            if (!AudioFileUseCase::compare($file->usecase, AudioFileUseCase::FORWARDING)) {
                unset($audioFiles[$key]);
            }
        }
        return $audioFiles;
    }

    /**
     * Triggers all Phones of this user
     * @param string $type select the phone type which will be triggert, eg. os60 only (if these keys has changed) NULL == All phones will be triggert!
     */
    public function triggerYourPhones($type = NULL)
    {
        $accounts = $this->getSipAccounts();
        foreach ($accounts as $account) {
            // find phone with this ID (and type)
            $attributes = array();
            $attributes["sip_account_id"] = $account->id;
            if ($type != NULL) {
                $attributes["type"] = $type;
            }
            $phone = Phones::model()->findByAttributes($attributes);
            if ($phone != NULL) {
                $phone->triggerProvisioning();
            }
        }
    }

    // // // // TEST

    public function getUserGroupIds()
    {
        if ($this->_userGroupIds_cache != null) {
            return $this->_userGroupIds_cache;
        }

        $userGroup = Groups::model()->findByPk($this->group);
        if ($userGroup == null) {
            return array();
        }

        $this->_userGroupIds_cache = array();

        $this->_userGroupIds_cache[] = $this->group;

        foreach ($userGroup->getParentGroups() as $groupModel) {
            $this->_userGroupIds_cache[] = $groupModel->id;
        }
        return $this->_userGroupIds_cache;
    }

    public function getCallGroupIds()
    {
        if ($this->_callGroupIds_cache != null) {
            return $this->_callGroupIds_cache;
        }
        //require_once Yii::app()->basePath . '/modules/routingCallGroup/models/UserToCallGroup.php';
        $userToCallGroups = UserToCallGroup::model()->findAllByAttributes(array('userId' => $this->id));

        $callGroupIds = array();
        foreach ($userToCallGroups as $userToCallGroup) {
            $callGroup = CallGroup::model()->findByPk($userToCallGroup->callGroupId);
            $callGroupIds[] = $callGroup->id;
        }
        if (empty($callGroupIds)) {
            return array();
        }
        foreach ($callGroupIds as $callGroupId) {
            $this->_callGroupIds_cache[] = $callGroupId;
        }
        return $this->_callGroupIds_cache;
    }

    public function getUserQueueIds()
    {
        if ($this->_queueIds_cache != null) {
            return $this->_queueIds_cache;
        }
        $tiers = Tiers::model()->findAllByAttributes(array('userId' => $this->id));
        $queueIds = array();
        foreach ($tiers as $tier) {
            $queue = Queue::model()->findByPk($tier->queueId);
            $queueIds[] = $queue->id;
        }

        if (empty($queueIds)) {
            return array();
        }

        foreach ($queueIds as $queueId) {
            $this->_queueIds_cache[] = $queueId;
        }

        $this->_queueIds_cache[] = $queue->id;
        return $this->_queueIds_cache;
    }

    public function getUserGroups()
    {
        if ($this->_userGroups_cache != null) {
            return $this->_userGroups_cache;
        }

        $this->_userGroups_cache = array();
        $usersGroup = Groups::model()->findByPk($this->group); //UsersToGroups::model()->findAllByAttributes(array('userId'=>$this->id));
        if (!$usersGroup) {
            $usersGroup = Groups::model()->findByattributes(array('parent' => '0'));
        }
        $this->_userGroups_cache = $usersGroup->getParentGroups();
        $this->_userGroups_cache[] = $usersGroup;
        return $this->_userGroups_cache;
    }

    public function addUserToGroup($gid)
    {
        //check if user is already in this groups
        $found = UsersToGroups::model()->findAllByAttributes(array('userId' => $this->id, 'groupId' => $gid));
        if (count($found) != 0) {
            return false;
        }

        //FIXME: is there any check if a group exists?? This have to been done in UserToGroups-Model!!!
        $userToGroupObj = new UsersToGroups();
        $userToGroupObj->userId = $this->id;
        $userToGroupObj->groupId = $gid;

        if (!$userToGroupObj->save()) {
            $this->addErrors($userToGroupObj->errors);
            return false;
        }
        return true;
    }

    public function getStateColor()
    {
        if ($this->phone_presence == "online" || $this->phone_presence == "free") {
            return "green";
        } else if ($this->phone_presence == "busy") {
            return "red";
        }
        return "gray";
    }

    public function getJabberStateColor()
    {
        //die($this->jabber_presence);
        if ($this->jabber_presence == "0") {
            return "green";
        } else if ($this->jabber_presence == "1" || $this->jabber_presence == "3") {
            return "red";
        }
        return "gray";
    }

    // // // // TEST end !
    ##### Stuff for UserPhonesetting #####

    public function renderPhonesettingsUser()
    {
        $userSettings = array(
            /* array(
              'id'=>'1',
              'key'=>'clir_int',
              'short'=>'<p data-translation-id="PHONESETTINGS_USER_MODEL_CLIR_INTERNAL_SHORT">'.__('PHONESETTINGS_USER_MODEL_CLIR_INTERNAL_SHORT').'</p>',
              'value'=>'',
              'descr'=>'<p data-translation-id="PHONESETTINGS_USER_MODEL_CLIR_INTERNAL_DESCRIPTION">'.__('PHONESETTINGS_USER_MODEL_CLIR_INTERNAL_DESCRIPTION').'</p>',
              'type'=>'bool',
              ), */
            array(
                'id' => '2',
                'key' => 'clir_ext',
                'short' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_CLIR_EXTERNAL_SHORT">' . __('PHONESETTINGS_USER_MODEL_CLIR_EXTERNAL_SHORT') . '</p>',
                'value' => '',
                'descr' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_CLIR_EXTERNAL_DESCRIPTION">' . __('PHONESETTINGS_USER_MODEL_CLIR_EXTERNAL_DESCRIPTION') . '</p>',
                'type' => 'bool',
            ),
            array(
                'id' => '3',
                'key' => 'clip_int',
                'short' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_CLIP_INTERNAL_SHORT">' . __('PHONESETTINGS_USER_MODEL_CLIP_INTERNAL_SHORT') . '</p>',
                'value' => '',
                'descr' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_CLIP_INTERNAL_DESCRIPTION">' . __('PHONESETTINGS_USER_MODEL_CLIP_INTERNAL_DESCRIPTION') . '</p>',
                'type' => 'text',
            ),
            array(
                'id' => '4',
                'key' => 'clip_ext',
                'short' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_CLIP_EXTERNAL_SHORT">' . __('PHONESETTINGS_USER_MODEL_CLIP_EXTERNAL_SHORT') . '</p>',
                'value' => '',
                'descr' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_CLIP_EXTERNAL_DESCRIPTION">' . __('PHONESETTINGS_USER_MODEL_CLIP_EXTERNAL_DESCRIPTION') . '</p>',
                'type' => 'text',
            ),
            array(
                'id' => '5',
                'key' => 'call_waiting',
                'short' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_CALL_WAITING_SHORT">' . __('PHONESETTINGS_USER_MODEL_CALL_WAITING_SHORT') . '</p>',
                'value' => '',
                'descr' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_CALL_WAITING_DESCRIPTION">' . __('PHONESETTINGS_USER_MODEL_CALL_WAITING_DESCRIPTION') . '</p>',
                'type' => 'bool',
            ),
            array(
                'id' => '6',
                'key' => 'dnd',
                'short' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_DND_SHORT">' . __('PHONESETTINGS_USER_MODEL_DND_SHORT') . '</p>',
                'value' => '',
                'descr' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_DND_DESCRIPTION">' . __('PHONESETTINGS_USER_MODEL_DND_DESCRIPTION') . '</p>',
                'type' => 'bool',
            ),
        );
        return $userSettings;
    }

    public function renderPhonesettingsTones()
    {
        $userSettings = array(
            array(
                'id' => '7',
                'key' => 'key_tone',
                'short' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_KEY_TONE_SHORT">' . __('PHONESETTINGS_USER_MODEL_KEY_TONE_SHORT') . '</p>',
                'value' => '',
                'descr' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_KEY_TONE_DESCRIPTION">' . __('PHONESETTINGS_USER_MODEL_KEY_TONE_DESCRIPTION') . '</p>',
                'type' => 'bool',
            ),
            array(
                'id' => '8',
                'key' => 'ringtone_int',
                'short' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_RINGTONE_INTERNAL_SHORT">' . __('PHONESETTINGS_USER_MODEL_RINGTONE_INTERNAL_SHORT') . '</p>',
                'value' => '',
                'descr' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_RINGTONE_INTERNAL_DESCRIPTION">' . __('PHONESETTINGS_USER_MODEL_RINGTONE_INTERNAL_DESCRIPTION') . '</p>',
                'type' => 'dropdown',
            ),
            array(
                'id' => '9',
                'key' => 'ringtone_ext',
                'short' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_RINGTONE_EXTERNAL_SHORT">' . __('PHONESETTINGS_USER_MODEL_RINGTONE_EXTERNAL_SHORT') . '</p>',
                'value' => '',
                'descr' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_RINGTONE_EXTERNAL_DESCRIPTION">' . __('PHONESETTINGS_USER_MODEL_RINGTONE_EXTERNAL_DESCRIPTION') . '</p>',
                'type' => 'dropdown',
            ),
            array(
                'id' => '10',
                'key' => 'ringtone_queue',
                'short' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_RINGTONE_QUEUE_SHORT">' . __('PHONESETTINGS_USER_MODEL_RINGTONE_QUEUE_SHORT') . '</p>',
                'value' => '',
                'descr' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_RINGTONE_QUEUE_DESCRIPTION">' . __('PHONESETTINGS_USER_MODEL_RINGTONE_QUEUE_DESCRIPTION') . '</p>',
                'type' => 'dropdown',
            ),
            array(
                'id' => '11',
                'key' => 'ringtone_callgroup',
                'short' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_RINGTONE_CALL_GROUP_SHORT">' . __('PHONESETTINGS_USER_MODEL_RINGTONE_CALL_GROUP_SHORT') . '</p>',
                'value' => '',
                'descr' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_RINGTONE_CALL_GROUP_DESCRIPTION">' . __('PHONESETTINGS_USER_MODEL_RINGTONE_CALL_GROUP_DESCRIPTION') . '</p>',
                'type' => 'dropdown',
            )
        );
        return $userSettings;
    }

    public function renderPhonesettingsNotifications()
    {
        $userSettings = array(
            array(
                'id' => '10',
                'key' => 'email_fax',
                'short' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_FAX_NOTIFICATION_SHORT">' . __('PHONESETTINGS_USER_MODEL_FAX_NOTIFICATION_SHORT') . '</p>',
                'value' => '',
                'descr' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_FAX_NOTIFICATION_DESCRIPTION">' . __('PHONESETTINGS_USER_MODEL_FAX_NOTIFICATION_DESCRIPTION') . '</p>',
                'type' => 'bool',
            ),
            array(
                'id' => '11',
                'key' => 'email_vmail',
                'short' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_VOICEMAIL_NOTIFICATION_SHORT">' . __('PHONESETTINGS_USER_MODEL_VOICEMAIL_NOTIFICATION_SHORT') . '</p>',
                'value' => '',
                'descr' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_VOICEMAIL_NOTIFICATION_DESCRIPTION">' . __('PHONESETTINGS_USER_MODEL_VOICEMAIL_NOTIFICATION_DESCRIPTION') . '</p>',
                'type' => 'bool',
            ),
            array(
                'id' => '16',
                'key' => 'email_vmail_delete',
                'short' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_EMAIL_VMAIL_DELETE_SHORT">' . __('PHONESETTINGS_USER_MODEL_EMAIL_VMAIL_DELETE_SHORT') . '</p>',
                'value' => '',
                'descr' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_EMAIL_VMAIL_DELETE_DESCRIPTION">' . __('PHONESETTINGS_USER_MODEL_EMAIL_VMAIL_DELETE_DESCRIPTION') . '</p>',
                'type' => 'bool',
            ),
            array(
                'id' => '13',
                'key' => 'email_external_missed_call',
                'short' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_EXTERNAL_MISSED_CALL_NOTIFICATION_SHORT">' . __('PHONESETTINGS_USER_MODEL_EXTERNAL_MISSED_CALL_NOTIFICATION_SHORT') . '</p>',
                'value' => '',
                'descr' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_EXTERNAL_MISSED_CALL_NOTIFICATION_DESCRIPTION">' . __('PHONESETTINGS_USER_MODEL_EXTERNAL_MISSED_CALL_NOTIFICATION_DESCRIPTION') . '</p>',
                'type' => 'bool',
            ),
            array(
                'id' => '13',
                'key' => 'email_internal_missed_call',
                'short' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_INTERNAL_MISSED_CALL_NOTIFICATION_SHORT">' . __('PHONESETTINGS_USER_MODEL_INTERNAL_MISSED_CALL_NOTIFICATION_SHORT') . '</p>',
                'value' => '',
                'descr' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_INTERNAL_MISSED_CALL_NOTIFICATION_DESCRIPTION">' . __('PHONESETTINGS_USER_MODEL_INTERNAL_MISSED_CALL_NOTIFICATION_DESCRIPTION') . '</p>',
                'type' => 'bool',
            ),
        );
        return $userSettings;
    }

    public function renderPhonesettingsCredentials()
    {
        $userSettings = array(
            array(
                'id' => '12',
                'key' => 'pin',
                'short' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_CURRENT_PIN_SHORT">' . __('PHONESETTINGS_USER_MODEL_CURRENT_PIN_SHORT') . '</p>',
                'value' => '',
                'descr' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_CURRENT_PIN_DESCRIPTION">' . __('PHONESETTINGS_USER_MODEL_CURRENT_PIN_DESCRIPTION') . '</p>',
                'type' => 'text',
            ),
            array(
                'id' => '15',
                'key' => 'password',
                'short' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_CURRENT_PASSWORD_SHORT">' . __('PHONESETTINGS_USER_MODEL_CURRENT_PASSWORD_SHORT') . '</p>',
                'value' => '',
                'descr' => '<p data-translation-id="PHONESETTINGS_USER_MODEL_CURRENT_PASSWORD_DESCRIPTION">' . __('PHONESETTINGS_USER_MODEL_CURRENT_PASSWORD_DESCRIPTION') . '</p>',
                'type' => 'text',
            ),
        );
        return $userSettings;
    }

    public function renderValue($data)
    {
        $userId = Yii::app()->User->sudoUser;
        $model = User::model()->findByPk($userId);

        if ($data['type'] == 'bool') {
            return CHtml::checkBox('User[' . $data['key'] . ']', $model->{$data['key']}, array('name' => '.$value.', 'uncheckValue' => '0'));
        } else if ($data['type'] == 'text') {
            return CHtml::textField('User[' . $data['key'] . ']', $model->{$data['key']});
        } else if ($data['type'] == 'dropdown') {
            $stdRingtones = array(
                'ringtone-1' => __('BELLCORE') . ' 1',
                'ringtone-2' => __('BELLCORE') . ' 2',
                'ringtone-3' => __('BELLCORE') . ' 3',
                'ringtone-4' => __('BELLCORE') . ' 4',
                'ringtone-5' => __('BELLCORE') . ' 5',
                'ringtone-6' => __('BELLCORE') . ' 6',
                'ringtone-7' => __('BELLCORE') . ' 7',
                'ringtone-8' => __('BELLCORE') . ' 8',
                'ringtone-9' => __('BELLCORE') . ' 9',
                'ringtone-10' => __('BELLCORE') . ' 10',
                'mute' => __('BELLCORE_MUTE'),
            );

            $userRingtones = CHtml::listData(Ringtone::model()->findAllByAttributes(array('userId' => User::getCurrentSudoUser()->id)), 'id', 'fileName');

            $availableRingTones = array(__('CHOOSE_BELLCHOR') => array_merge($stdRingtones, $userRingtones));
            return CHtml::dropDownList('User[' . $data['key'] . ']', $model->{$data['key']}, $availableRingTones);
        }
    }
    ##### Stuff for PhonesettingsUser ends #####

    public function afterDelete()
    {
        parent::afterDelete();
        if (!$this->deleteAddresses()) {
            return false;
        }

        if (!$this->deleteSipAccounts()) {
            return false;
        }

        if (!$this->deleteConferenceModeratorReferences()) {
            return false;
        }

        $internAddress = Addresses::model()->findByPk($this->addressReferece);
        if ($internAddress) {
            $internAddress->delete();
        }

        if (!$this->deleteUserSettings()) {
            return false;
        }

        //delete ExternalNumbers
        do {
            $externalNumbers = ExternalNumber::model()->findAllByAttributes(array('userId' => $this->id));
            foreach ($externalNumbers as $number) {
                $number->delete();
            }
        } while (!empty($externalNumbers));
        return true;
    }

    public function beforeDelete()
    {
        if (($this->scenario != 'LdapImport') && ($this->id == User::getCurrentRealUser()->id)) {
            throw new CHttpException(400, Yii::t('err', __('USER_MODEL_ERROR_MESSAGE_CANT_DELETE_YOURSELF')));
            return false;
        }

        if ($this->isSystemAdmin && $this->countByAttributes(array('isSystemAdmin' => "1")) <= 1) {
            throw new CHttpException(400, Yii::t('err', __('USER_MODEL_ERROR_MESSAGE_CANT_DELETE_LAST_ADMIN')));
            return false;
        }

        if (!$this->deleteTiers()) {
            return false;
        }

        if (!$this->deleteSecretaryReferences()) {
            return false;
        }

        if (!$this->deleteBossReferences()) {
            return false;
        }

        if (!$this->deleteThirdPartyCredentials()) {
            return false;
        }

        if (!$this->deleteUserCallForwardings()) {
            return false;
        }

        if (!$this->deleteSystemCallForwardingKeys()) {
            return false;
        }

        if (!$this->deleteUserToCallGroup()) {
            return false;
        }

        return parent::beforeDelete();
    }

    public function deleteConferenceModeratorReferences()
    {
        include_once(__DIR__ . '/../modules/routingConference/models/ConferenceModerator.php');

        $references = ConferenceModerator::model()->findAllByAttributes(array('userId' => $this->id));
        if (count($references)) {
            foreach ($references as $reference) {
                if (!$reference->delete()) {
                    return false;
                }
            }
        }
        return true;
    }

    public function deleteSecretaryReferences()
    {
        $models = Secretary::model()->findAllByAttributes(array('secretaryId' => $this->id));
        return $this->deleteModels($models);
    }

    public function deleteBossReferences()
    {
        $models = Secretary::model()->findAllByAttributes(array('bossId' => $this->id));
        return $this->deleteModels($models);
    }

    protected function deleteThirdPartyCredentials()
    {
        $models = ThirdPartyCredential::model()->findAllByAttributes(array('owner' => $this->id));
        return $this->deleteModels($models);
    }

    protected function deleteUserCallForwardings()
    {
        $models = ForwardPreset::model()->findAllByAttributes(array('owner' => $this->id));
        return $this->deleteModels($models, 'deleteUser');
    }

    protected function deleteSystemCallForwardingKeys()
    {
        $models = ForwardPresetPhoneKey::model()->findAllByAttributes(array('owner' => $this->id));
        return $this->deleteModels($models, 'deleteUser');
    }

    protected function deleteModels($models, $scenario = '')
    {
        foreach ($models as $model) {
            if (!empty($scenario)) {
                $model->scenario = $scenario;
            }
            if (!$model->delete()) {
                return false;
            }
        }
        return true;
    }

    public function deleteAddresses()
    {
        //FIXME with limit / offset ...
        include_once(__DIR__ . '/../models/Addressbook.php');

        $privateBooks = Addressbook::model()->findAllByAttributes(array('type' => 1));
        foreach ($privateBooks as $book) {
            $addresses = Addresses::model()->findAllByAttributes(array('contact_owner' => $this->id, 'contact_tid' => $book->id));
            if ($addresses) {
                foreach ($addresses as $address) {
                    $address->delete();
                }
            }
        }
        return true;
    }

    public function deleteSipAccounts()
    {
        //FIXME with limit / offset ...
        $sipaccounts = $this->getSipAccounts();

        if (!empty($sipaccounts)) {
            foreach ($sipaccounts as $sipaccount) {
                if (!$sipaccount->delete()) {
                    return false;
                }
            }
        }
        return true;
    }

    public function deleteTiers()
    {
        $tiers = Tiers::model()->findAllByAttributes(array("userId" => $this->id));
        if (!empty($tiers)) {
            foreach ($tiers as $tier) {
                $tier->tempUserExtension = $this->extension;

                $tier->save();
                if (!$tier->delete()) {
                    return false;
                }
            }
        }
        return true;
    }

    public function deleteUserToCallGroup()
    {
        $userToCallGroups = UserToCallGroup::model()->findAllByAttributes(array("userId" => $this->id));
        if (!empty($userToCallGroups)) {
            foreach ($userToCallGroups as $userToCallGroup) {
                if (!$userToCallGroup->delete()) {
                    return false;
                }
            }
        }
        return true;
    }

    public function getDefaultLanguage()
    {
        $language = '';
        if ($this->user_language != $language || $this->user_language != null || $this->user_language != '') {
            $language = $this->user_language;
        }
        if ($language == null) {
            $language = cfg('GUI_LANGS');
        }
        return $language;
    }

    public function hasPermission($itemId, $permissionType)
    {
        $groupIds = $this->getUserGroupIds();
        foreach ($groupIds as $groupId) {
            $permissionModel = Permissions::model()->getPermissionsArray(array('groupId' => $groupId, 'itemId' => $itemId, 'type' => $permissionType), true);
            if ($permissionModel) {
                return true;
            }
        }
        return false;
    }

    public function getForwardingSets($permissionType = 'read_forwardingset')
    {
        $presets = array();
        $allowedTypes = array('read_forwardingset', 'write_forwardingset');

        if (!in_array($permissionType, $allowedTypes)) {
            Log::e('Invalid permssion type "' . $permissionType . '" requested');
            return null;
        }

        $userGroupIds = $this->getUserGroupIds();
        foreach ($userGroupIds as $groupId) {
            // public and system presets
            $permissions = Permissions::model()->getPermissionsArray(array('groupId' => $groupId, 'type' => $permissionType));
            foreach ($permissions as $permission) {
                $preset = ForwardPreset::model()->findByPk($permission['itemId']);

                if ($preset == null) {
                    Log::e('ForwardPreset id: ' . $permission['itemId'] . ' not found (User->getForwardingSets()');
                } else {
                    $presets[] = ForwardPreset::model()->findByPk($permission['itemId']);
                }
            }
        }

        // private presets
        //$privatePresets = ForwardPreset::model()->getPrivatePresets(User::getCurrentSudoUser()->id);
        $privatePresets = ForwardPreset::model()->getPrivatePresets($this->id);
        $presets = array_merge($presets, $privatePresets);
        return array_unique($presets);
    }

    public function getAddressbooks($permissionType = 'read', $noInternal = false)
    {
        $mergedArray = array();
        $allowedTypes = array('read', 'write', 'sync');
        if (!in_array($permissionType, $allowedTypes)) {
            return null;
        }

        if (array_key_exists($permissionType, $this->_addressbooks_cache)) {
            return $this->_addressbooks_cache[$permissionType];
        }

        //FIXME is this line neccesary ?
        //include_once (__DIR__.'/../models/Addressbook.php');

        $userGroupIds = $this->getUserGroupIds();

        foreach ($userGroupIds as $groupId) {
            $addressbookPermissions = Permissions::model()->getPermissionsArray(array('groupId' => $groupId, 'type' => $permissionType));
            foreach ($addressbookPermissions as $addressbookPermission) {
                $book = Addressbook::model()->findByPk($addressbookPermission['itemId']);
                if ($noInternal == true && $book->isInternalAddressbook()) {
                    continue; // ignore this book cause internal addressbook has been skipped.
                }

                if ($book != NULL) {
                    $mergedArray[$addressbookPermission['itemId']] = $book;
                }
            }
        }

        $this->_addressbooks_cache[$permissionType] = $mergedArray;
        return $mergedArray;
    }

    public function getCalendars($permissionType = 'read_calendar')
    {
        $mergedArray = array();
        $allowedTypes = array('read_calendar', 'write_calendar', 'sync_calendar');
        if (!in_array($permissionType, $allowedTypes)) {
            return null;
        }

        $userGroupIds = $this->getUserGroupIds();

        foreach ($userGroupIds as $groupId) {
            $permissions = Permissions::model()->getPermissionsArray(array('groupId' => $groupId, 'type' => $permissionType));
            foreach ($permissions as $permission) {
                $calendar = Calendar::model()->findByPk($permission['itemId']);
                if ($calendar != NULL) {
                    $mergedArray[$permission['itemId']] = $calendar;
                }
            }
        }
        return $mergedArray;
    }

    ///TEST
    public function getJsonUsers()
    {
        $jsonUsers = array();
        $users = $this->findAll();
        foreach ($users as $user) {
            $jsonUser['name'] = $user->name;
            $jsonUser['extension'] = $user->extension;
            $jsonUsers[] = $jsonUser;
        }
        return json_encode($jsonUsers);
    }

    public function getPhotoUrl($size = 460)
    {
        $addressModel = Addresses::model()->findByPk($this->addressReferece);
        if ($addressModel == null || $addressModel->contact_jpegphoto == '') {
            return bu() . '/img/backgrounds/noAvatar.png';
        }
        return $addressModel->getPhotoUrl($size);
    }

    public function getGroupName()
    {
        $group = $this->getGroup();
        if ($group == null) {
            return false;
        }
        return $group->name;
    }

    public function getGroup()
    {
        $group = Groups::model()->findByPk($this->group);
        if ($group == null) {
            return false;
        }
        return $group;
    }

    public function getRevelantProvisioningProfiles()
    {
        $allProfiles = array();

        if (!empty($this->provisioningProfile)) {
            $profile = ProvisioningProfile::model()->findByPk($this->provisioningProfile);
            if ($profile != NULL) {
                $allProfiles['user'] = $profile;
            }
        }

        $group = $this->getGroup();
        if ($group == false) {
            return $allProfiles;
        }

        $profile = $group->getProvisioningProfile();
        if ($profile) {
            $allProfiles['group'] = $profile;
        }

        $parents = $group->getParentGroups();
        foreach ($parents as $key => $parent) {
            $profile = $parent->getProvisioningProfile();
            if ($profile) {
                $allProfiles["parent_$key"] = $profile;
            }
        }
        return array_reverse($allProfiles);
    }

    public function groupsForPermission($permission)
    {
        $allGroups = array();

        $parentGroups = $this->getUserGroups();
        foreach ($parentGroups as $parentGroup) {
            //$this->hasPermission($itemId, $permissionType)
        }
        //dump();die();

        $groupsWithPermission = Permissions::model()->getPermissionsArray(array('groupId' => $this->group, 'type' => $permission));
        //$groupsWithPermission = Permissions::model()->findAllByAttributes(array('itemId' => $this->group, 'type' => $permission));
        //dump($groupsWithPermission);die();

        foreach ($groupsWithPermission as $groupWithPermission) {
            $group = Groups::model()->findByPk($groupWithPermission['itemId']);
            if ($group) {
                $allGroups = array_merge($allGroups, $group->getChildren(true));
                $allGroups[] = $group;
            }
        }
        return $allGroups;
    }

    /**
     * @return array users,where current user has monitor sudo
     */
    public function getSudoUsers()
    {
        if ($this->isSystemAdmin) {
            return User::model()->findAll(array(), array('limit' => 1000));
        }
        return $this->getUsersForPermission('sudo');
    }

    /**
     * @return array users, where current user has monitor permission
     */
    public function getMonitorUsers()
    {
        return $this->getUsersForPermission('monitor');
    }

    /**
     * @param string $permission type
     * @return array users, where current user has selected permission
     */
    public function getUsersForPermission($permission)
    {
        $users = array();
        $permissions = Permissions::model()->getPermissionsArray(array('groupId' => $this->group, 'type' => $permission), true);

        foreach ($permissions as $permissionAttributes) {
            $group = Groups::model()->findByPk($permissionAttributes['itemId']);
            if ($group) {
                $users = array_merge($users, $group->getUsers());
                foreach ($group->getChildren(true) as $groupChild) {
                    $users = array_merge($users, $groupChild->getUsers());
                }
            }
        }

        $uniqueUsersArray = array();
        foreach ($users as $user) {
            $uniqueUsersArray[$user->id] = $user;
        }
        return $uniqueUsersArray;
    }

    public function getQueueIds()
    {
        $tiers = Tiers::model()->findAllByAttributes(array('userId' => $this->id));
        $queueIds = array();
        foreach ($tiers as $tier) {
            $queueIds[] = $tier->queueId;
        }
        return $queueIds;
    }

    public function humanReadableSearchFilterForGroup()
    {
        $list = array();
        $groups = Groups::model()->findAll();
        foreach ($groups as $group) {
            $list[$group->id] = $group->name;
        }
        asort($list);
        return $list;
    }

    public static function csvRelevantAttributes()
    {
        return array(
            'name' => array('length' => 64),
            'extension' => array('length' => 64),
            'firstname' => array('length' => 64),
            'lastname' => array('length' => 64),
            'email' => array('length' => 128),
            'pin' => array('length' => 40),
        );
    }

    public function getSettings()
    {
        $settings = UserSettings::model()->findByPk($this->settingsId);
        if (!$settings) {
            $settings = new UserSettings();
            $settings->userId = $this->id;
        }
        return $settings;
    }

    public function updateSettings($attributes)
    {
        $settings = $this->getSettings();
        if (!empty($attributes)) {
            $settings->attributes = $attributes;
        }
        $settings->save();
        $this->settingsId = $settings->id;
    }

    protected function deleteUserSettings()
    {
        $userSettings = UserSettings::model()->findByPk($this->settingsId);
        if ($userSettings) {
            if (!$userSettings->delete()) {
                return false;
            }
        }
        return true;
    }

    public function getLanguageDropdownList()
    {
        $language = Sysconfig::model()->getLanguageArray();
        asort($language);
        return array_unshift_assoc(
                $language, 'Default Language', __('DEFAULT_LANGUAGE') . ' (' . cfg('GUI_LANGS') . ')'
        );
    }

    public function getTimeZoneDropdownList()
    {
        $timezone = Sysconfig::model()->getTimeZones();
        return array_unshift_assoc(
                $timezone, 'Default Timezone', __('DEFAULT_TIMEZONE') . ' (' . cfg('TIMEZONE') . ')'
        );
    }

    public function getTimeFormatDropdownList()
    {
        $timeFormat = Sysconfig::model()->getTimeFormat();
        return array_unshift_assoc(
                $timeFormat, 'Default Time Format', __('DEFAULT_TIME_FORMAT') . ' (' . cfg('USER_TIME_FORMAT') . ')'
        );
    }

    public function getDateFormatDropdownList()
    {
        $dateFormat = Sysconfig::model()->getDateFormat();
        asort($dateFormat);
        return array_unshift_assoc(
                $dateFormat, 'Default Date Format', __('DEFAULT_DATE_FORMAT') . ' (' . cfg('USER_DATE_FORMAT') . ')'
        );
    }

    public function getProvisioningProfileDropdownList()
    {
        $provProfileList = CHtml::listData(ProvisioningProfile::model()->find(array(), 'name'), 'id', 'name');
        return array_unshift_assoc($provProfileList, '', '---');
    }

    public function getKeyProfileDropdownList()
    {
        $keyProfileList = CHtml::listData(ProvisioningKeyProfile::model()->find(array(), 'name'), 'id', 'name');
        return array_unshift_assoc($keyProfileList, '', '---');
    }

    public function getCurrentUserCount()
    {
        $allUsers = User::model()->findAll();
        return count($allUsers);
    }

    public function userLimitationAllowedMoreUsers()
    {
        $result = false;
        if (PhonalisaLicenseManager::adminUserMax() > $this->getCurrentUserCount()) {
            $result = true;
        }
        if (PhonalisaLicenseManager::adminUserMax() === -1) {
            $result = true;
        }
        return $result;
    }

    public static function getFaxSendAllowedDropdownList()
    {
        return array(
            User::FAX_SEND_NOT_ALLOWED => __('USER_FAX_SEND_NOT_ALLOWED'),
            User::FAX_SEND_ALLOWED => __('USER_FAX_SEND_ALLOWED'),
            User::FAX_SEND_INHERIT_FROM_GROUP => __('USER_FAX_SEND_INHERIT_FROM_GROUP')
        );
    }
}
