<commit_before><?php

namespace app\models;

use app\query\UserQuery;
use yii\db\ActiveRecord;
use yii\db\Expression;
use yii\web\IdentityInterface;

/**
 * This is the model class for table "user".
 *
 * @property integer $id
 * @property string  $email
 * @property string  $password_hash
 * @property string  $created_at
 * @property string  $recovery_code
 * @property string  $authToken
 *
 * @property Organization   $organization
 * @property Patient        $patient
 * @property Doctor         $doctor
 * @property UserInvite[]   $invites
 */
class User extends ActiveRecord implements IdentityInterface
{
    const ROLE_PATIENT = 'patient';
    const ROLE_DOCTOR  = 'doctor';
    const ROLE_CHIEF   = 'chief';

    /**
     * @var string
     */
    public $inviteCode;

    /**
     * @var string
     */
    public $password;

    /**
     * @var UserInvite
     */
    private $userInvite;

    /**
     * @inheritdoc
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @inheritdoc
     */
    public function getAuthKey()
    {
        return null;
    }

    /**
     * @inheritdoc
     */
    public function validateAuthKey($authKey) : bool
    {
        return false;
    }

    /**
     * Validates password and rehashes it if needed.
     * 
     * @param  string $password
     * @return bool
     */
    public function validatePassword(string $password) : bool
    {
        if (password_verify($password, $this->password_hash)) {
            if (password_needs_rehash($this->password_hash, PASSWORD_DEFAULT)) {
                $this->updateAttributes([
                    'password_hash' => password_hash($password, PASSWORD_DEFAULT),
                ]);
            }
            
            return true;
        }

        return false;
    }

    /**
     * Creates new auth token for this user.
     *
     * @return string
     */
    public function getAuthToken() : string
    {
        return (new UserToken(['user_id' => $this->id]))->create();
    }

    /**
     * @inheritdoc
     */
    public function rules() : array
    {
        return [
            [['email', 'inviteCode'], 'trim'],
            [['email', 'inviteCode', 'password'], 'required', 'message' => '{attribute} не может быть пустым'],
            ['email', 'email', 'message' => 'Некорректный формат Email адреса'],
            ['email', 'unique', 'message' => 'Email уже используется'],
            ['password', 'string', 'min' => 6, 'max' => 72,
                'tooShort' => 'Пароль не может быть короче 6 символов',
                'tooLong' => 'Пароль не может быть длиннее 72 символов'],
            ['inviteCode', 'validateInviteCode'],
        ];
    }

    /**
     * Checks invite code.
     * @param $attribute
     */
    public function validateInviteCode(string $attribute)
    {
        $this->userInvite = UserInvite::find()->byCode($this->inviteCode)->byEmail($this->email)->one();

        if ($this->userInvite === null) {
            $this->addError($attribute, 'Некорректный инвайт код');
        }
    }

    /**
     * Registers user and sends welcome message to email.
     *
     * @return bool
     */
    public function register() : bool
    {
        $transaction = $this->getDb()->beginTransaction();

        try {
            if (!$this->validate()) {
                return false;
            }
            
            $this->save(false);

            \Yii::$app->mailer->compose('register', ['user' => $this])
                ->setTo($this->email)
                ->setSubject('Регистрация в системе')
                ->setFrom(\Yii::$app->params['adminEmail'])
                ->send();

            $this->userInvite->updateAttributes(['referral_id' => $this->id]);

            $role = \Yii::$app->authManager->getRole($this->userInvite->role);
            \Yii::$app->authManager->assign($role, $this->id);

            switch ($this->userInvite->role) {
                case self::ROLE_PATIENT:
                    (new Patient())->link('user', $this);
                    \Yii::$app->db->createCommand()->insert('patient_to_doctor', [
                        'patient_id' => $this->patient->id,
                        'doctor_id'  => $this->userInvite->referrer->doctor->id,
                    ])->execute();
                    break;
                case self::ROLE_DOCTOR:
                    $doctor = new Doctor([
                        'user_id'         => $this->id,
                        'organization_id' => $this->userInvite->referrer->organization->id,
                    ]);
                    $doctor->save();
                    break;
            }

            $transaction->commit();
            
            return true;
        } catch (\Throwable $e) {
            \Yii::error($e);
            
            $transaction->rollBack();
            
            return false;
        } 
    }
<commit_msg>Create organization on chief register<commit_after><?php

namespace app\models;

use app\query\UserQuery;
use yii\db\ActiveRecord;
use yii\db\Expression;
use yii\web\IdentityInterface;

/**
 * This is the model class for table "user".
 *
 * @property integer $id
 * @property string  $email
 * @property string  $password_hash
 * @property string  $created_at
 * @property string  $recovery_code
 * @property string  $authToken
 *
 * @property Organization   $organization
 * @property Patient        $patient
 * @property Doctor         $doctor
 * @property UserInvite[]   $invites
 */
class User extends ActiveRecord implements IdentityInterface
{
    const ROLE_PATIENT = 'patient';
    const ROLE_DOCTOR  = 'doctor';
    const ROLE_CHIEF   = 'chief';

    /**
     * @var string
     */
    public $inviteCode;

    /**
     * @var string
     */
    public $password;

    /**
     * @var UserInvite
     */
    private $userInvite;

    /**
     * @inheritdoc
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @inheritdoc
     */
    public function getAuthKey()
    {
        return null;
    }

    /**
     * @inheritdoc
     */
    public function validateAuthKey($authKey) : bool
    {
        return false;
    }

    /**
     * Validates password and rehashes it if needed.
     * 
     * @param  string $password
     * @return bool
     */
    public function validatePassword(string $password) : bool
    {
        if (password_verify($password, $this->password_hash)) {
            if (password_needs_rehash($this->password_hash, PASSWORD_DEFAULT)) {
                $this->updateAttributes([
                    'password_hash' => password_hash($password, PASSWORD_DEFAULT),
                ]);
            }
            
            return true;
        }

        return false;
    }

    /**
     * Creates new auth token for this user.
     *
     * @return string
     */
    public function getAuthToken() : string
    {
        return (new UserToken(['user_id' => $this->id]))->create();
    }

    /**
     * @inheritdoc
     */
    public function rules() : array
    {
        return [
            [['email', 'inviteCode'], 'trim'],
            [['email', 'inviteCode', 'password'], 'required', 'message' => '{attribute} не может быть пустым'],
            ['email', 'email', 'message' => 'Некорректный формат Email адреса'],
            ['email', 'unique', 'message' => 'Email уже используется'],
            ['password', 'string', 'min' => 6, 'max' => 72,
                'tooShort' => 'Пароль не может быть короче 6 символов',
                'tooLong' => 'Пароль не может быть длиннее 72 символов'],
            ['inviteCode', 'validateInviteCode'],
        ];
    }

    /**
     * Checks invite code.
     * @param $attribute
     */
    public function validateInviteCode(string $attribute)
    {
        $this->userInvite = UserInvite::find()->byCode($this->inviteCode)->byEmail($this->email)->one();

        if ($this->userInvite === null) {
            $this->addError($attribute, 'Некорректный инвайт код');
        }
    }

    /**
     * Registers user and sends welcome message to email.
     *
     * @return bool
     */
    public function register() : bool
    {
        $transaction = $this->getDb()->beginTransaction();

        try {
            if (!$this->validate()) {
                return false;
            }
            
            $this->save(false);

            \Yii::$app->mailer->compose('register', ['user' => $this])
                ->setTo($this->email)
                ->setSubject('Регистрация в системе')
                ->setFrom(\Yii::$app->params['adminEmail'])
                ->send();

            $this->userInvite->updateAttributes(['referral_id' => $this->id]);

            $role = \Yii::$app->authManager->getRole($this->userInvite->role);
            \Yii::$app->authManager->assign($role, $this->id);

            switch ($this->userInvite->role) {
                case self::ROLE_CHIEF:
                    $organization = new Organization(['owner_id' => $this->id]);
                    $organization->save(false);
                    break;
                case self::ROLE_PATIENT:
                    (new Patient())->link('user', $this);
                    \Yii::$app->db->createCommand()->insert('patient_to_doctor', [
                        'patient_id' => $this->patient->id,
                        'doctor_id'  => $this->userInvite->referrer->doctor->id,
                    ])->execute();
                    break;
                case self::ROLE_DOCTOR:
                    $doctor = new Doctor([
                        'user_id'         => $this->id,
                        'organization_id' => $this->userInvite->referrer->organization->id,
                    ]);
                    $doctor->save(false);
                    break;
            }

            $transaction->commit();
            
            return true;
        } catch (\Throwable $e) {
            \Yii::error($e);
            
            $transaction->rollBack();
            
            return false;
        } 
    }

{'fraction_non_alphanumeric': 0.1435397173004181, 'fraction_numerical': 0.0011945052757316346, 'mean_word_length': 1.6727853152434158, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 150, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '865221', 'n_tokens_mistral': 2932, 'n_tokens_neox': 2837, 'n_words': 590}