Files
trafficpumper/app/Models/SerpCheck.php
T
2026-08-29 15:53:53 +03:00

73 lines
2.4 KiB
PHP

<?php
namespace App\Models;
use App\Enums\KeywordDevice;
use App\Enums\SearchEngine;
use App\Enums\SerpCheckStatus;
use Illuminate\Database\Eloquent\Concerns\HasUlids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use LogicException;
class SerpCheck extends Model
{
use HasFactory,HasUlids;
protected $guarded = ['id', 'keyword_id', 'ulid'];
protected function casts(): array
{
return ['status' => SerpCheckStatus::class, 'search_engine' => SearchEngine::class, 'device' => KeywordDevice::class, 'checked_at' => 'datetime', 'started_at' => 'datetime', 'completed_at' => 'datetime', 'failed_at' => 'datetime', 'provider_task_posted_at' => 'datetime', 'provider_last_polled_at' => 'datetime', 'provider_next_poll_at' => 'datetime', 'provider_cost' => 'decimal:6'];
}
public function uniqueIds(): array
{
return ['ulid'];
}
public function getRouteKeyName(): string
{
return 'ulid';
}
public function keyword(): BelongsTo
{
return $this->belongsTo(Keyword::class);
}
public function results(): HasMany
{
return $this->hasMany(SerpResult::class);
}
public function begin(): bool
{
if ($this->status !== SerpCheckStatus::Pending) {
return false;
}
return $this->forceFill(['status' => SerpCheckStatus::Running, 'active_slot' => 'active', 'started_at' => now()])->save();
}
public function complete(array $data): bool
{
if ($this->status !== SerpCheckStatus::Running) {
throw new LogicException('Invalid check transition.');
}
return $this->forceFill($data + ['status' => SerpCheckStatus::Completed, 'active_slot' => null, 'checked_at' => now(), 'completed_at' => now(), 'failed_at' => null, 'error_code' => null, 'error_message' => null])->save();
}
public function fail(string $code, string $message): bool
{
if (! in_array($this->status, [SerpCheckStatus::Pending, SerpCheckStatus::Running], true)) {
return false;
}
return $this->forceFill(['status' => SerpCheckStatus::Failed, 'active_slot' => null, 'failed_at' => now(), 'error_code' => $code, 'error_message' => $message])->save();
}
}