ldc-legaulois/app/Models/Contact.php
Jérémy Munsch 191b83780a
Ticket1052 : Definetly fix Contact stat issues
- correction on table : PK is now Date instead of Timestamp
- Contact::incrementStat now dispatches a job to handle concurent incrementations
- Transactions are used on contact actions
- date is no correctly casted
- isoFormat is use with Carbon
2022-09-29 11:39:25 +02:00

140 lines
3 KiB
PHP

<?php
namespace App\Models;
use App\Enums\ContactFormType;
use App\Jobs\IncrementContactStatsJob;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Carbon;
class Contact extends Model
{
/**
* The primary key for the model.
*
* @var string
*/
protected $primaryKey = 'date';
/**
* Indicates if the model should be timestamped.
*
* @var boolean
*/
public $timestamps = false;
/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'date' => 'date'
];
/**
* Perform any actions required after the model boots.
*
* @return void
*/
protected static function booted()
{
static::creating(function (self $model) {
$model->date = Carbon::now();
$model->all = 1;
});
static::updating(function (self $model) {
// * increment general counter
$model->all = $model->all + 1;
});
}
/**
* Increments the ContactFormType stats of today
*
* @param ContactFormType $type
* @return void
*/
public static function incrementStat(ContactFormType $type)
{
IncrementContactStatsJob::dispatch($type);
}
/**
* Get values attribute
*
* @param mixed $value
* @return array
*/
public function getValuesAttribute($value): array
{
return $this->unserialize($value ?? serialize($this->counterSkeleton()));
}
/**
* Set values attribute
*
* @param array $value
* @return string
*/
public function setValuesAttribute(array $value): string
{
$this->attributes['values'] = $this->serialize($value);
return $this->attributes['values'];
}
/**
* Serialize value
*
* @param array $value
* @return string
*/
private function serialize(array $value)
{
return serialize($this->merge($this->counterSkeleton(), $value));
}
/**
* Unserialize value
*
* @param string $value
* @return array
*/
private function unserialize(string $value)
{
return $this->merge($this->counterSkeleton(), unserialize($value));
}
/**
* Merge thow array
*
* TODO: Replace this with collection or array merge.
*
* @param array $a
* @param array $b
* @return array
*/
private function merge(array $a, array $b): array
{
foreach ($a as $i => $v) {
if (isset($b[$i])) {
$a[$i] = $b[$i];
}
}
return $a;
}
/**
* Get Counter skeleton
* @return array
*/
private function counterSkeleton(): array
{
return collect(ContactFormType::toArray())->mapWithKeys(function (ContactFormType $enum) {
if ($enum->equals(ContactFormType::none())) {
return [];
}
return [$enum->value => 0];
})->toArray();
}
}