*/ protected $casts = [ 'last_connection' => 'datetime', 'email_verified_at' => 'datetime', ]; /** * Perform any actions required after the model boots. * * @return void */ protected static function booted() { // * EVENT CLOSURES. static::creating(function (self $model) { static::assertEmailIsUnique($model->id, $model->email); }); static::updating(function (self $model) { static::assertEmailIsUnique($model->id, $model->email); }); } // * RELATIONSHIPS /** * HasMany orders relation * * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function orders() { return $this->hasMany(Order::class); } // * METHODS /** * Asserts using validation that the email is unique * * @param mixed $id * @param mixed $email * @return void * @throws \Illuminate\Validation\ValidationException If user email as already used. */ private static function assertEmailIsUnique($id, $email) { self::assertFieldIsUnique($id, 'email', $email); } // * --- AUTH --- /** * Send the email verification notification. * * @return void */ public function sendEmailVerificationNotification() { $this->notify(new NotificationVerifyEmail()); } /** * Mark the given user's email as verified. * * @return boolean * @throws \LDC\LDCCRM\Exceptions\CrmException If an error occurs on server side or on getting response. * @throws \LDC\LDCCRM\Exceptions\ApiErrorException If any error or \LDC\LDCCRM\Enums\ApiError occurs. * @phpcs:ignore Squiz.Commenting.FunctionCommentThrowTag.WrongNumber */ public function markEmailAsVerified() { try { return $this->api_data->activate() && parent::markEmailAsVerified(); } catch (ApiErrorException $e) { if ($e->getApiError()->equals(ApiError::customerAlreadyActive())) { return true && parent::markEmailAsVerified(); } throw $e; } } /** * Send the password reset notification. * * @param mixed $token * @return void */ public function sendPasswordResetNotification($token) { /** @var string $token */ $this->notify(new NotificationResetPassword($token)); } // * --- END AUTH --- /** * Asserts that the field is unique * * @param mixed $id * @param string $field * @param mixed $value * @return void * @throws \Illuminate\Validation\ValidationException If the field is not unique. */ private static function assertFieldIsUnique($id, string $field, $value) { Validator::make([$field => $value], [ $field => Rule::unique('customers', $field)->ignore($id), ], [ $field . '.unique' => trans('La valeur :value pour le champ :attribute est déjà utilisé', [ 'attribute' => $field, 'value' => $value ]) ])->validate(); } /** * Get the crm Data of a customer * * @return \LDC\LDCCRM\Models\Customer * @throws \LDC\LDCCRM\Exceptions\CrmException If cannot fetch data from crm. * @author Jérémy Munsch */ public function getApiDataAttribute(): CrmCustomer { /** @var \LDC\LDCCRM\CrmApiV2 */ $crm = app('crmAPI'); $crmCustomer = $crm->getCustomer($this->hashcode); if (!$crmCustomer) { throw new CrmException('CRM get Customer returned null'); } return $crmCustomer; } /** * Set the crm Data of a customer * @param CustomerCrmResource $resource * * @return CrmCustomer * * @throws \LDC\LDCCRM\Exceptions\CrmException If an error occurs on server side or on getting response. * @throws \LDC\LDCCRM\Exceptions\ApiErrorException If any error or \LDC\LDCCRM\Enums\ApiError occurs. * @author Jérémy Munsch * @phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber */ public function updateApiData(CustomerCrmResource $resource): CrmCustomer { $data = $resource->toArray(null); /** @var \LDC\LDCCRM\CrmApiV2 */ $crm = app('crmAPI'); $crmCustomer = $crm->getCustomer($data['hashcode']); if (!$crmCustomer) { throw new CrmException('CRM get Customer returned null'); } $crmCustomer->fill($data); $crmCustomer->save(); return $crmCustomer; } /** * This mutate Customer attributes to array * including only non critical properties and crm values * (One that can be send to front office without security breach) * * @return array */ public function toArray() { if ($this->hashcode) { return collect(array_merge( parent::toArray(), (array)$this->apiData ))->intersectByKeys([ 'email' => '', 'firstname' => '', 'lastname' => '', 'address' => '', 'address2' => '', 'postcode' => '', 'birth_date' => '', 'city' => '', 'country' => '', 'opt_in' => '', 'phone' => '' ])->toArray(); } else { return parent::toArray(); } } }