YetiForceCompany/YetiForceCRM

View on GitHub
modules/Settings/WebserviceUsers/models/Record.php

Summary

Maintainability
D
2 days
Test Coverage
F
38%
<?php

/**
 * Record Model.
 *
 * @package Settings.Model
 *
 * @copyright YetiForce S.A.
 * @license   YetiForce Public License 6.5 (licenses/LicenseEN.txt or yetiforce.com)
 * @author    Radosław Skrzypczak <r.skrzypczak@yetiforce.com>
 * @author    Mariusz Krzaczkowski <m.krzaczkowski@yetiforce.com>
 */
class Settings_WebserviceUsers_Record_Model extends Settings_Vtiger_Record_Model
{
    /**
     * Changes.
     *
     * @var array
     */
    public $changes = [];
    /**
     * Table name.
     *
     * @var string
     */
    public $baseTable = '';

    /**
     * Table name.
     *
     * @var string
     */
    public $baseIndex = '';

    /**
     * Module Name.
     *
     * @var string
     */
    public $name = 'WebserviceUsers';

    /**
     * Edit fields.
     *
     * @var string[]
     */
    public $editFields = [];

    /**
     * List of fields displayed in list view.
     *
     * @var string[]
     */
    public $listFields = [];

    /** @var array List of fields in param column. */
    public $paramsFields = [];

    /** @var array List of custom params labels. */
    public static $customParamsLabels = [
        'language' => 'FL_LANGUAGE',
        'ip' => 'FL_LAST_IP',
        'invalid_login_time' => 'FL_DATETIME_LAST_INVALID_LOGIN',
        'invalid_login' => 'FL_LAST_INVALID_LOGIN',
        'logout_time' => 'FL_LOGOUT_TIME',
        'last_error' => 'FL_LAST_ERROR',
        'error_time' => 'FL_LAST_ERROR_DATE',
        'error_method' => 'FL_LAST_ERROR_METHOD',
        'version' => 'FL_VERSION',
        'fromUrl' => 'FL_FROM_URL',
        'agent' => 'LBL_USER_AGENT',
        'deviceId' => 'LBL_DEVICE_ID',
    ];

    /**
     * Record ID.
     *
     * @return int
     */
    public function getId()
    {
        return $this->get('id');
    }

    /**
     * Check if record is new.
     *
     * @return int
     */
    public function isNew()
    {
        return !$this->getId() || $this->getId() && \array_key_exists('id', $this->changes) && empty($this->changes['id']);
    }

    /**
     * Function to get Module instance.
     *
     * @return Settings_WebserviceUsers_Module_Model
     */
    public function getModule()
    {
        if (!$this->module) {
            $this->module = Settings_Vtiger_Module_Model::getInstance('Settings:WebserviceUsers');
        }
        return $this->module;
    }

    /**
     * Function to set Module instance.
     *
     * @param Settings_WebserviceUsers_Module_Model $moduleModel
     *
     * @return $this
     */
    public function setModule($moduleModel)
    {
        $this->module = $moduleModel;
        return $this;
    }

    /** {@inheritdoc} */
    public function getName()
    {
        return $this->get('name');
    }

    /** {@inheritdoc} */
    public function init(array $data)
    {
        $this->setData($data);
        return $this;
    }

    /** {@inheritdoc} */
    public function set($key, $value)
    {
        if (($prev = $this->value[$key] ?? null) !== $value) {
            $this->changes[$key] = $prev;
        }
        parent::set($key, $value);
        return $this;
    }

    /**
     * Function determines fields available in edition view.
     *
     * @return string[]
     */
    public function getEditFields()
    {
        return $this->editFields;
    }

    /**
     * Get user session.
     *
     * @param string $container
     *
     * @return array
     */
    public function getUserSession(string $container): array
    {
        $dataReader = (new \App\Db\Query())->from(\Api\Core\Containers::$listTables[$container]['session'])
            ->where(['user_id' => $this->getId()])
            ->orderBy(['changed' => SORT_DESC])
            ->limit(30)
            ->createCommand()->query();
        $data = [];
        while ($row = $dataReader->read()) {
            $data[] = $this->getFormatDataSession($row);
        }
        return $data;
    }

    /**
     * Get user session.
     *
     * @param string $container
     *
     * @return array
     */
    public function getUserHistoryAccessActivity(string $container): array
    {
        $dataReader = (new \App\Db\Query())->from(\Api\Core\Containers::$listTables[$container]['loginHistory'])
            ->where(['user_id' => $this->getId()])
            ->orderBy(['id' => SORT_DESC])
            ->limit(30)
            ->createCommand()->query();
        $data = [];
        while ($row = $dataReader->read()) {
            $data[] = $this->getFormatLoginHistory($row);
        }
        return $data;
    }

    /**
     * Get format data session.
     *
     * @param array $row
     *
     * @return array
     */
    public function getFormatDataSession(array $row): array
    {
        foreach ($row as $key => $value) {
            switch ($key) {
                case 'parent_id':
                    $row[$key] = $value ? \App\Record::getLabel($value) : '';
                    break;
                case 'language':
                    $row[$key] = $value ? \App\Language::getLanguageLabel($value) : '';
                    break;
                case 'created':
                case 'changed':
                    $row[$key] = \App\Fields\DateTime::formatToDisplay($value);
                    break;
                case 'params':
                    if ($value) {
                        $params = \App\Json::decode($value);
                        $value = '';
                        foreach ($params as $paramsKey => $paramsValue) {
                            $value .= \App\Language::translate(self::$customParamsLabels[$paramsKey] ?? $paramsKey, 'Settings:WebserviceUsers') . ": $paramsValue \n";
                        }
                        $row[$key] = \App\Layout::truncateText($value, 50, true);
                    }
                    break;
                    case 'agent':
                        $row[$key] = \App\Layout::truncateText($value, 50, true);
                        break;
                default:
                    break;
            }
            if (!\in_array($key, ['params', 'agent'])) {
                $row[$key] = App\Purifier::encodeHtml($row[$key]);
            }
        }
        return $row;
    }

    /**
     * Get format data session.
     *
     * @param array $row
     *
     * @return array
     */
    public function getFormatLoginHistory(array $row): array
    {
        foreach ($row as $key => $value) {
            switch ($key) {
                case 'time':
                    $row[$key] = \App\Fields\DateTime::formatToDisplay($value);
                    break;
                case 'status':
                        $row[$key] = \App\Language::translate($value, 'Settings::' . $this->getModule()->getName());
                    break;
                case 'agent':
                    $row[$key] = \App\Layout::truncateText($value, 50, true);
                    break;
                case 'device_id':
                    $row[$key] = "<div class=\"js-popover-tooltip ml-2 mr-2 d-inline mt-2\" data-js=\"popover\" data-content=\"$value\">" . \App\TextUtils::textTruncate($value, 14) . '</div>';
                    break;
                default:
                    break;
            }
            if (!\in_array($key, ['device_id', 'agent'])) {
                $row[$key] = App\Purifier::encodeHtml($row[$key]);
            }
        }
        return $row;
    }

    /** {@inheritdoc} */
    public function getListFields(): array
    {
        if (!isset($this->listFieldModels)) {
            $fieldObjects = [];
            foreach ($this->listFields as $fieldName => $fieldLabel) {
                $fieldObjects[$fieldName] = new \App\Base(['name' => $fieldName, 'label' => $fieldLabel]);
            }
            $this->listFieldModels = $fieldObjects;
        }
        return $this->listFieldModels;
    }

    /**
     * Function to get the instance, given id.
     *
     * @param int    $id
     * @param string $type
     *
     * @return \self
     */
    public static function getInstanceById($id, $type)
    {
        $cacheName = __CLASS__;
        if (\App\Cache::staticHas($cacheName, $id)) {
            return \App\Cache::staticGet($cacheName, $id);
        }
        $instance = self::getCleanInstance($type);
        $data = (new App\Db\Query())
            ->from($instance->baseTable)
            ->where([$instance->baseIndex => $id])
            ->one(App\Db::getInstance('webservice'));
        if (!empty($data['custom_params']) && !App\Json::isEmpty($data['custom_params'])) {
            $data['custom_params'] = \App\Json::decode($data['custom_params']);
            $data = array_merge($data, $data['custom_params']);
        } else {
            $data['custom_params'] = [];
        }
        if (!empty($data['auth'])) {
            $data['auth'] = \App\Json::decode(\App\Encryption::getInstance()->decrypt($data['auth']));
        } else {
            $data['auth'] = [];
        }
        $data['authy_methods'] = $data['auth']['authy_methods'] ?? '';
        $instance->init($data);
        \App\Cache::staticSave($cacheName, $id, $instance);
        return $instance;
    }

    /**
     * Function to get the clean instance.
     *
     * @param string $type
     *
     * @return $this
     */
    public static function getCleanInstance($type): self
    {
        $moduleInstance = Settings_Vtiger_Module_Model::getInstance('Settings:WebserviceUsers');
        $moduleInstance->typeApi = $type;
        $instance = $moduleInstance->getService();
        $instance->module = $moduleInstance;
        return $instance;
    }

    /**
     * Function gives list fields for save.
     *
     * @return array
     */
    public function getFieldsForSave()
    {
        return array_intersect_key($this->getEditFields(), $this->changes);
    }

    /**
     * Function gives data for save.
     *
     * @return array
     */
    public function getDataForSave()
    {
        if (empty($this->getId())) {
            $fields = $this->getEditFields();
        } else {
            $fields = $this->getFieldsForSave();
        }
        return array_intersect_key($this->getData(), $fields);
    }

    /**
     * Check if the data is correct.
     *
     * @return bool|string false - if everything is ok
     */
    public function checkData()
    {
        if (empty($this->listFields['user_name'])) {
            return false;
        }
        if ($this->isEmpty('user_name')) {
            $userName = $this->getUserName();
            if (empty($userName)) {
                return 'LBL_EMAIL_ADDRESS_NOT_FOUND';
            }
            if ((new App\Db\Query())
                ->from($this->baseTable)
                ->where(['user_name' => $userName])
                ->exists(App\Db::getInstance('webservice'))) {
                return 'LBL_DUPLICATE_EMAIL_ADDRESS';
            }
        }
        return false;
    }

    /**
     * Function to save.
     *
     * @return bool
     */
    public function save()
    {
        $db = App\Db::getInstance('webservice');
        $table = $this->baseTable;
        $index = $this->baseIndex;
        $data = $this->getDataForSave();
        $params = $this->get('custom_params');
        foreach ($this->paramsFields as $name) {
            if (!isset($data[$name])) {
                continue;
            }
            if ('' !== $data[$name]) {
                $params[$name] = $data[$name];
            }
            unset($data[$name]);
        }
        $data['custom_params'] = $params ? \App\Json::encode($params) : null;
        if (empty($data['authy_methods']) || '-' === $data['authy_methods']) {
            $data['auth'] = '';
        } else {
            $auth = $this->get('auth') ?: [];
            $auth['authy_methods'] = $data['authy_methods'] ?? '';
            $data['auth'] = \App\Encryption::getInstance()->encrypt(\App\Json::encode($auth));
        }
        unset($data['authy_methods']);
        if (empty($this->getId())) {
            $data['user_name'] = $this->getUserName();
            $success = $db->createCommand()->insert($table, $data)->execute();
            if ($success) {
                $this->set('id', $db->getLastInsertID("{$table}_{$index}_seq"));
            }
        } else {
            $success = $db->createCommand()->update($table, $data, [$index => $this->getId()])->execute();
        }
        return $success;
    }

    /**
     * Get user name.
     *
     * @return string
     */
    public function getUserName(): string
    {
        if (!$this->isEmpty('user_name')) {
            return $this->get('user_name');
        }
        $email = '';
        if (1 !== (int) $this->get('type')) {
            try {
                $email = Vtiger_Record_Model::getInstanceById($this->get('crmid'), 'Contacts')->get('email');
            } catch (\Throwable $th) {
            }
        } else {
            $email = \App\User::getUserModel($this->get('user_id'))->getDetail('email1');
        }
        $this->set('user_name', $email);
        return $email;
    }

    /**
     * Function removes record.
     *
     * @return bool
     */
    public function delete()
    {
        $db = App\Db::getInstance('webservice');
        $result = false;
        if ($recordId = $this->getId()) {
            $result = (bool) $db->createCommand()->delete($this->baseTable, [$this->baseIndex => $recordId])->execute();
        }
        return $result;
    }
}