date = date('Y-m-d'); return $contact; }); static::updating(function ($contact) { $contact->all++; // increment general counter return $contact; }); } /** * Increments the ContactFormType stats of today * * @param ContactFormType $type * @return void */ public static function incrementStat(ContactFormType $type) { $contact = static::where('date', '=', date('Y-m-d'))->firstOrNew(); // Can't do $contact->counter[$type->value]++ => ErrorException $d = $contact->values; $d[$type->value]++; $contact->values = $d; $contact->save(); } public function getValuesAttribute($value): array { return $this->unserialize($value ?? serialize($this->counterSkeleton())); } public function setValuesAttribute(array $value): string { $this->attributes['values'] = $this->serialize($value); return $this->attributes['values']; } private function serialize(array $value) { return serialize($this->merge($this->counterSkeleton(), $value)); } private function unserialize(string $value) { return $this->merge($this->counterSkeleton(), unserialize($value)); } private function merge(array $a, array $b): array { foreach ($a as $i => $v) { if (isset($b[$i])) { $a[$i] = $b[$i]; } } return $a; } private function counterSkeleton(): array { return collect(ContactFormType::toArray())->mapWithKeys(function ($enum) { if ($enum->equals(ContactFormType::none())) { return []; } return [$enum->value => 0]; })->toArray(); } }