ldc-com-app-bo/app/Models/Contact.php

161 lines
5 KiB
PHP
Raw Permalink Normal View History

2023-07-13 08:34:54 +00:00
<?php
namespace App\Models;
use App\Casts\AsArrayOfInput;
use App\Lib\Inputs\Definition\Input;
use App\Lib\Inputs\InputEmail;
use App\Lib\Inputs\InputPhone;
use App\Lib\Inputs\InputText;
use App\Traits\Models\HasUuidKey;
use Illuminate\Database\Eloquent\Factories\HasFactory;
2023-07-13 08:34:54 +00:00
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
2023-07-13 08:34:54 +00:00
/**
* @property integer $app_user_id Associated app user.
* @property string $id Contact id.
* @property string $email Contact email.
* @property string|null $lastname Contact last name.
* @property string|null $firstname Contact first name.
* @property string|null $phone Contact phone.
* @property array<\App\Lib\Inputs\Definition\Input> $data Contact data.
* @property string|null $notes Contact notes.
* @property array<array<string,string>> $visits Contact visits.
* @property-read \Carbon\Carbon|null $created_at Created date.
* @property-read \Carbon\Carbon|null $updated_at Updated date.
2023-07-13 08:34:54 +00:00
*/
class Contact extends Model
{
use HasFactory;
use HasUuidKey;
2023-07-13 08:34:54 +00:00
/**
* The attributes that are mass assignable.
*
* @var list<string>
2023-07-13 08:34:54 +00:00
*/
protected $fillable = [
'app_user_id',
'email',
'lastname',
2023-07-13 08:34:54 +00:00
'firstname',
'data',
2023-07-13 08:34:54 +00:00
'phone',
'notes',
'visits',
'timestamp',
2023-07-13 08:34:54 +00:00
];
/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [
'data' => AsArrayOfInput::class,
'timestamp' => 'immutable_datetime',
'visits' => 'array'
];
/**
* Perform any actions required after the model boots.
*
* @return void
*/
protected static function booted(): void
{
static::creating(function (self $model) {
$model->id = Str::uuid();
self::assertContactDataIsMatchingFormulary($model);
});
static::deleting(function (self $model) {
self::assertContactDataIsMatchingFormulary($model);
});
}
2023-07-13 08:34:54 +00:00
// * RELATIONSHIPS
/**
* MorphToMany Directories.
2023-07-13 08:34:54 +00:00
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function appUser(): \Illuminate\Database\Eloquent\Relations\BelongsTo
2023-07-13 08:34:54 +00:00
{
return $this->belongsTo(AppUser::class, 'app_user_id', 'id');
}
// * METHODS
/**
* Get all inputs.
*
* @return array
* @throws \RuntimeException This should not happen since data was validated on contact insertion.
* ! It may happen if this model does not have an email.
* ! It may only happen if input validation rules are changed.
*/
public function allInputs(): array
{
return $this->mandatoryInputs() + $this->data;
}
/**
* Get mandatory inputs.
*
* @return array<\App\Lib\Inputs\Definition\Input>
* @throws \RuntimeException If this model does have an email.
*/
public function mandatoryInputs(): array
{
// * firsname
$data[] = InputText::make('Prénom', $this->firstname, [], false);
// * lastname
$data[] = InputText::make('Nom', $this->lastname, [], false);
// * email
$data[] = InputEmail::make('E-mail', $this->email, [], true);
// * phone
$data[] = InputPhone::make('Téléphone', $this->phone, [], false);
return $data;
2023-07-13 08:34:54 +00:00
}
/**
* Assert contact data is matching actual Formularies
*
* @param \App\Models\Contact $contact
* @return void
*/
2025-05-20 16:20:23 +02:00
public static function assertContactDataIsMatchingFormulary(Contact $contact): void
{
/** @var \Illuminate\Support\Collection<string,integer> */
$formularies = Formulary::query()->pluck('slug')->flip();
\collect($contact->data)->each(function (Input $input) use ($formularies) {
if (!$formularies->has($input->data->formSlug)) {
throw new \ErrorException(
"Formulary {$input->data->formSlug} does not exist, do not store this contact data prop"
);
}
});
}
/**
* Remove Data Input on All contacts
*
* @param \App\Models\Formulary $formulary
* @return void
*/
public static function removeDataInputOnAllContacts(Formulary $formulary): void
{
DB::transaction(function () use ($formulary) {
Contact::query()->select(['id', 'data'])->each(function (Contact $contact) use ($formulary) {
$contact->data = \collect($contact->data)->filter(function (Input $input) use ($formulary) {
return $input->data->formSlug !== $formulary->slug;
})->toArray();
$contact->saveOrFail();
});
});
}
2023-07-13 08:34:54 +00:00
}