false, 'skipOnEmpty' => false], ['email', 'email', 'message' => 'Cette adresse email n\'est pas valide'], ['email', 'verifyEmail'], ['status', 'default', 'value' => self::STATUS_ACTIVE], ['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED, self::STATUS_ADMIN, self::STATUS_PRODUCER]], ['password_old', 'verifyPasswordOld'], ['password_new', 'verifyPasswordNew'], ['password_new_confirm', 'verifyPasswordNewConfirm'], [['date_last_connection', 'password_old', 'password_new', 'password_new_confirm', 'password_hash', 'points_sale', 'product_price_percent', 'user_groups'], 'safe'], ]; } public function attributeLabels() { return [ 'id' => 'ID', 'name' => 'Prénom', 'lastname' => 'Nom', 'phone' => 'Téléphone', 'address' => 'Adresse', 'username' => 'Identifiant', 'password' => 'Mot de passe', 'rememberMe' => 'Se souvenir de moi', 'no_mail' => 'Ne pas recevoir d\'email de la part du Chat des Noisettes', 'mail_distribution_monday' => 'Lundi', 'mail_distribution_tuesday' => 'Mardi', 'mail_distribution_wednesday' => 'Mercredi', 'mail_distribution_thursday' => 'Jeudi', 'mail_distribution_friday' => 'Vendredi', 'mail_distribution_saturday' => 'Samedi', 'mail_distribution_sunday' => 'Dimanche', 'password_old' => 'Ancien mot de passe', 'password_new' => 'Nouveau mot de passe', 'password_new_confirm' => 'Confirmation du nouveau mot de passe', 'points_sale' => 'Points de vente', 'type' => 'Type', 'name_legal_person' => 'Libellé', 'is_main_contact' => 'Contact principal', 'product_price_percent' => 'Prix produits : pourcentage', 'user_groups' => "Groupes d'utilisateurs" ]; } /** * Retourne les options de base nécessaires à la fonction de recherche. * * @return array */ public static function defaultOptionsSearch() { return [ 'with' => [], 'join_with' => ['userProducer', 'userUserGroup'], 'orderby' => 'user.name ASC, user.lastname ASC', 'attribute_id_producer' => '' ]; } /** * Vérifie le mot de passe envoyé par l'utilisateur. * * @param string $attribute * @param array $params */ public function verifyPasswordOld($attribute, $params) { if (strlen($this->password_old)) { if (!$this->validatePassword($this->password_old)) { $this->addError($attribute, 'Mot de passe invalide.'); } } if (!strlen($this->password_old) && (strlen($this->password_new) || strlen($this->password_new_confirm))) { $this->addError($attribute, 'Ce champs ne peut être vide'); } if (!strlen($this->password_new) && (strlen($this->password_old) || strlen($this->password_new_confirm))) { $this->addError('password_new', 'Ce champs ne peut être vide'); } if (!strlen($this->password_new_confirm) && (strlen($this->password_old) || strlen($this->password_new))) { $this->addError('password_new_confirm', 'Ce champs ne peut être vide'); } } /** * Vérifie le mot de passe de l'utilisateur. * * @param string $attribute * @param array $params */ public function verifyPasswordNew($attribute, $params) { if (strlen($this->password_new) < 6) { $this->addError($attribute, 'Votre mot de passe doit comporter au moins 6 caractères.'); } } /** * Vérifie la confirmation de mot de passe de l'utilisateur. * * @param string $attribute * @param array $params */ public function verifyPasswordNewConfirm($attribute, $params) { if ($this->password_new != $this->password_new_confirm) { $this->addError($attribute, 'Les deux mots de passe doivent être identiques'); } } /** * Vérifie l'email de l'utilisateur. * * @param string $attribute * @param array $params */ public function verifyEmail($attribute, $params) { if($this->id) { $user = User::find()->where("email LIKE :email AND type != :guest AND id != :id")->params(array(':email' => '%' . $this->email . '%', ':id' => $this->id, ':guest' => 'guest'))->one(); } else { $user = User::find()->where("email LIKE :email AND type != :guest")->params(array(':email' => '%' . $this->email . '%', ':guest' => 'guest'))->one(); } if ($user) { $this->addError($attribute, 'Cette adresse email est déjà utilisée par un autre utilisateur '); } } /** * Vérifie que l'utilisateur a au moins un nom de défini * * @param $attribute * @param $params */ public function verifyOneName($attribute, $params) { if(strlen($this->lastname) == 0 && strlen($this->name_legal_person) == 0) { $this->addError('lastname', 'Vous devez saisir au moins un nom.'); $this->addError('name_legal_person', 'Vous devez saisir au moins un nom.'); } } /* * Relations */ public function getUserProducer() { return $this->hasMany(UserProducer::className(), ['id_user' => 'id']); } public function getUserUserGroup() { return $this->hasMany(UserUserGroup::className(), ['id_user' => 'id']); } public function getOrder() { return $this->hasMany(Order::className(), ['id_user' => 'id']); } /** * @inheritdoc */ public static function findIdentity($id) { return static::findOne(['id' => $id]); } /** * @inheritdoc */ public static function findIdentityByAccessToken($token, $type = null) { throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.'); } /** * Finds user by username * * @param string $username * @return static|null */ public static function findByUsername($username) { return static::findOne(['username' => $username]); } /** * Recherche un utilisateur via son adresse email. * * @param string $email * @return User */ public static function findByEmail($email) { return static::findOne(['email' => $email]); } /** * Finds user by password reset token * * @param string $token password reset token * @return static|null */ public static function findByPasswordResetToken($token) { if (!static::isPasswordResetTokenValid($token)) { return null; } return static::findOne([ 'password_reset_token' => $token, ]); } /** * Recherche des utilisateurs suivant les paramètres : id_etablissement, * inactifs, id_point_vente, nom, prenom, email, telephone. * * @param array $params * @return Query */ public static function findBy($params = []) { if (!isset($params['id_producer'])) { $params['id_producer'] = GlobalParam::getCurrentProducerId(); } $query = (new Query()) ->select(['user.id AS user_id', 'user.name', 'user.lastname', 'user.phone', 'user.email', 'user.created_at', 'user.date_last_connection', 'user_producer.*', 'user.address', 'user.name_legal_person']) ->from('user'); $active = (isset($params['inactive']) && $params['inactive']) ? 0 : 1; $query->innerJoin('user_producer', 'user.id = user_producer.id_user AND user_producer.active = ' . $active . ' AND user_producer.id_producer = :id_producer', [':id_producer' => $params['id_producer']]); if (isset($params['id_point_sale']) && $params['id_point_sale']) { $point_sale = PointSale::findOne(['id' => $params['id_point_sale']]); $conditionLinkUserPointSale = 'user.id = user_point_sale.id_user AND user_point_sale.id_point_sale = :id_point_sale'; $usersPointSaleLink = false; $usersPointSaleHasOrder = false; if (isset($params['users_point_sale_link']) && $params['users_point_sale_link']) { $usersPointSaleLink = true; } elseif (isset($params['users_point_sale_has_order']) && $params['users_point_sale_has_order']) { $usersPointSaleHasOrder = true; } elseif ($point_sale->restricted_access) { $usersPointSaleLink = true; } else { $usersPointSaleHasOrder = true; } if ($usersPointSaleLink) { $query->innerJoin('user_point_sale', 'user.id = user_point_sale.id_user AND user_point_sale.id_point_sale = :id_point_sale', [':id_point_sale' => $params['id_point_sale']]); } elseif ($usersPointSaleHasOrder) { $query->innerJoin( 'order', 'user.id = order.id_user AND order.id_point_sale = :id_point_sale', [':id_point_sale' => $params['id_point_sale']] )->groupBy('user.id'); } } if (isset($params['subscribers']) && $params['subscribers']) { $query->innerJoin( 'subscription', 'user.id = subscription.id_user AND subscription.id_producer = :id_producer', [':id_producer' => GlobalParam::getCurrentProducerId()] )->groupBy('user.id'); } if (isset($params['inactive']) && $params['inactive']) { $query->innerJoin( 'order', 'user.id = order.id_user' ) ->groupBy('user.id'); } if (isset($params['name'])) { $query->andFilterWhere(['like', 'name', $params['name']]); } if (isset($params['lastname'])) { $query->andFilterWhere(['like', 'lastname', $params['lastname']]); } if (isset($params['email'])) { $query->andFilterWhere(['like', 'email', $params['email']]); } if (isset($params['phone'])) { $query->andFilterWhere(['like', 'phone', $params['phone']]); } $query->orderBy('user.type DESC, user.lastname ASC, user.name ASC'); return $query; } /** * Finds out if password reset token is valid * * @param string $token password reset token * @return boolean */ public static function isPasswordResetTokenValid($token) { if (empty($token)) { return false; } $expire = Yii::$app->params['user.passwordResetTokenExpire']; $parts = explode('_', $token); $timestamp = (int)end($parts); return $timestamp + $expire >= time(); } /** * @inheritdoc */ public function getId() { return $this->getPrimaryKey(); } /** * @inheritdoc */ public function getAuthKey() { return $this->auth_key; } /** * @inheritdoc */ public function validateAuthKey($authKey) { return $this->getAuthKey() === $authKey; } /** * Validates password * * @param string $password password to validate * @return boolean if password provided is valid for current user */ public function validatePassword($password) { return Yii::$app->security->validatePassword($password, $this->password_hash); } /** * Generates password hash from password and sets it to the model * * @param string $password */ public function setPassword($password) { $this->password_hash = Yii::$app->security->generatePasswordHash($password); } /** * Generates "remember me" authentication key */ public function generateAuthKey() { $this->auth_key = Yii::$app->security->generateRandomString(); } /** * Generates new password reset token */ public function generatePasswordResetToken() { $this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time(); } /** * Removes password reset token */ public function removePasswordResetToken() { $this->password_reset_token = null; } /** * Retourne l'utilisateur courant. * * @return User */ public static function getCurrent() { if (!Yii::$app->user->isGuest) { return Yii::$app->user->identity; } return false; } /** * Retourne si l'utilisateur courant est connecté ou non. * * @return boolean */ public static function isCurrentConnected() { return !Yii::$app->user->isGuest; } /** * Retourne si l'utilisateur est un producteur ou non. * * @return boolean */ public function isProducer() { return ($this->status == User::STATUS_ADMIN || $this->status == User::STATUS_PRODUCER) && $this->id_producer; } /** * Retourne si l'utilisateur courant est un producteur ou non. * * @return boolean */ public static function isCurrentProducer() { $user = User::getCurrent(); if ($user) { return $user->isProducer(); } return false; } /** * Retourne si l'utilisateur est un admin ou non. * * @return boolean */ public function isAdmin() { return $this->status == User::STATUS_ADMIN; } /** * Retourne si l'utilisateur courant est un admin ou non. * * @return boolean */ public static function isCurrentAdmin() { $user = User::getCurrent(); if ($user) { return $user->isAdmin(); } return false; } /** * Retourne le nom du producteur. * * @return string */ public function getNameProducer() { $producer = Producer::findOne($this->id_producer); return $producer->name; } /** * Retourne les établissements liés à l'utilisateur. * * @return array */ public function getBookmarkedProducers() { $producers = (new \yii\db\Query()) ->select('*') ->from(['user_producer', 'producer']) ->where('user_producer.id_producer = producer.id') ->andWhere(['user_producer.id_user' => $this->id]) ->andWhere(['user_producer.active' => 1]) ->all(); return $producers; } /** * Retourne le crédit de l'utilisateur pour un producteur donné. * * @param integer $id_etablissement * @return float */ public function getCredit($idProducer) { $userProducer = UserProducer::searchOne([ 'id_user' => $this->id ]); if ($userProducer) { return $userProducer->credit; } return 0; } /** * Retourne le point de vente favoris d'un utilisateur : le point de vente auquel le client est lié, * le point de vente de la dernière commande sinon. * * @return PointSale */ public function getFavoritePointSale() { $arrayUserPointSale = UserPointSale::find() ->innerJoinWith('pointSale', true) ->where([ 'user_point_sale.id_user' => $this->id, 'point_sale.id_producer' => GlobalParam::getCurrentProducerId() ]) ->all(); if (count($arrayUserPointSale) == 1) { $pointSale = PointSale::findOne(['id' => $arrayUserPointSale[0]->id_point_sale]); } else { $lastOrder = Order::find()->innerJoinWith('pointSale', true)->where([ 'order.id_user' => $this->id, 'point_sale.id_producer' => GlobalParam::getCurrentProducerId() ]) ->orderBy('order.id DESC') ->one(); if ($lastOrder) { $pointSale = PointSale::findOne(['id' => $lastOrder->id_point_sale]); } } if (isset($pointSale)) { return $pointSale; } return false; } /** * Met à jour la date de dernière connexion de l'utilisateur. */ public function updateLastConnection() { $this->date_last_connection = date('Y-m-d H:i:s'); $this->save(); } /** * Envoie un email de bienvenue à l'utilisateur lors de son inscription * via le backend du site. * * @param string $password */ public function sendMailWelcome($password) { if (strlen($this->email)) { $producer = Producer::findOne(GlobalParam::getCurrentProducerId()); Yii::$app->mailer->compose(); $mail = Yii::$app->mailer->compose( ['html' => 'createUserAdmin-html', 'text' => 'createUserAdmin-text'], ['user' => $this, 'producer' => $producer, 'password' => $password] ) ->setTo($this->email) ->setFrom(['contact@opendistrib.net' => 'distrib']) ->setSubject('[distrib] Inscription') ->send(); } } public function getFullAddress($nl2br = false) { $address = ''; if(isset($this->lastname) && isset($this->name) && strlen($this->lastname) && strlen($this->name)) { $address .= $this->lastname . ' ' . $this->name . "\n"; } if(isset($this->name_legal_person) && strlen($this->name_legal_person)) { $address .= $this->name_legal_person. "\n"; } $address .= $this->address; if($nl2br) { $address = nl2br($address) ; } return $address; } public function getUsername($withType = false) { $username = '' ; if(isset($this->name_legal_person) && strlen($this->name_legal_person)) { $username = $this->name_legal_person ; if($withType) { $username = 'Personne morale / '.$username ; } } else { $username = $this->lastname.' '.$this->name ; } return $username ; } public static function getUsernameFromArray($modelArray, $withType = false) { $username = '' ; if(isset($modelArray['name_legal_person']) && strlen($modelArray['name_legal_person'])) { $username = $modelArray['name_legal_person'] ; if($withType) { $username = 'Personne morale / '.$username ; } } else { $username = $modelArray['lastname'].' '.$modelArray['name'] ; } return $username ; } public static function populateDropdownList() { $usersArray = User::findBy()->all() ; $usersArrayDropdown = ['' => '--'] ; foreach($usersArray as $user) { $usersArrayDropdown[$user['user_id']] = User::getUsernameFromArray($user, true) ; } return $usersArrayDropdown ;; } /** * Retourne l'ID de l'utilisateur courant connecté. * * @return mixed */ public static function getCurrentId() { if (!Yii::$app->user->isGuest) { return Yii::$app->user->identity->id; } return false; } /** * Retourne le status de l'utilisateur courant connecté. * * @return integer|boolean */ public static function getCurrentStatus() { if (!Yii::$app->user->isGuest) { return Yii::$app->user->identity->status; } return false; } public static function hasAccessBackend() { return User::getCurrentStatus() == USER::STATUS_ADMIN || User::getCurrentStatus() == USER::STATUS_PRODUCER; } public function belongsToUserGroup($userGroupId) { if(!$this->userUserGroup) { $this->populateRelation('userUserGroup', UserUserGroup::searchAll([ 'id_user' => $this->id ])) ; } if($this->userUserGroup) { foreach($this->userUserGroup as $userUserGroup) { if($userUserGroup->id_user_group == $userGroupId) { return true ; } } } return false ; } public static function getTypeChoicesArray() { return [ User::TYPE_INDIVIDUAL => 'Particulier', User::TYPE_LEGAL_PERSON => 'Personne morale', User::TYPE_GUEST => 'Visiteur' ]; } }