some progress
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class Domain extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'site_id',
|
||||
'domain',
|
||||
'expires_at',
|
||||
'last_checked_at',
|
||||
'is_active',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'expires_at' => 'datetime',
|
||||
'last_checked_at' => 'datetime',
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
|
||||
public function site(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Site::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if domain is expiring soon (within 30 days)
|
||||
*/
|
||||
public function isExpiringSoon(): bool
|
||||
{
|
||||
if (!$this->expires_at) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->expires_at->lte(Carbon::now()->addDays(30));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if domain has expired
|
||||
*/
|
||||
public function isExpired(): bool
|
||||
{
|
||||
if (!$this->expires_at) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->expires_at->lte(Carbon::now());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get days until expiration
|
||||
*/
|
||||
public function daysUntilExpiration(): ?int
|
||||
{
|
||||
if (!$this->expires_at) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Carbon::now()->diffInDays($this->expires_at, false);
|
||||
}
|
||||
}
|
||||
@@ -53,4 +53,14 @@ class Site extends Model
|
||||
{
|
||||
return $this->hasMany(DnsRecord::class);
|
||||
}
|
||||
|
||||
public function domains(): HasMany
|
||||
{
|
||||
return $this->hasMany(Domain::class);
|
||||
}
|
||||
|
||||
public function sitemaps(): HasMany
|
||||
{
|
||||
return $this->hasMany(Sitemap::class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class Sitemap extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'site_id',
|
||||
'url',
|
||||
'last_checked_at',
|
||||
'is_valid',
|
||||
'last_error',
|
||||
'is_active',
|
||||
'url_count',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'last_checked_at' => 'datetime',
|
||||
'is_valid' => 'boolean',
|
||||
'is_active' => 'boolean',
|
||||
'url_count' => 'integer',
|
||||
];
|
||||
|
||||
public function site(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Site::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if sitemap has errors
|
||||
*/
|
||||
public function hasErrors(): bool
|
||||
{
|
||||
return !$this->is_valid || !empty($this->last_error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the status badge color
|
||||
*/
|
||||
public function getStatusBadgeClass(): string
|
||||
{
|
||||
if (!$this->last_checked_at) {
|
||||
return 'bg-secondary';
|
||||
}
|
||||
|
||||
return $this->is_valid ? 'bg-success' : 'bg-danger';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the status text
|
||||
*/
|
||||
public function getStatusText(): string
|
||||
{
|
||||
if (!$this->last_checked_at) {
|
||||
return 'Not Checked';
|
||||
}
|
||||
|
||||
return $this->is_valid ? 'Valid' : 'Invalid';
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark sitemap as valid
|
||||
*/
|
||||
public function markAsValid(?int $urlCount = null): void
|
||||
{
|
||||
$this->update([
|
||||
'is_valid' => true,
|
||||
'last_error' => null,
|
||||
'last_checked_at' => now(),
|
||||
'url_count' => $urlCount,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark sitemap as invalid
|
||||
*/
|
||||
public function markAsInvalid(string $error): void
|
||||
{
|
||||
$this->update([
|
||||
'is_valid' => false,
|
||||
'last_error' => $error,
|
||||
'last_checked_at' => now(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,16 @@ class User extends Authenticatable
|
||||
'email',
|
||||
'password',
|
||||
'notification_preferences',
|
||||
'notification_channels',
|
||||
'slack_webhook_url',
|
||||
'telegram_chat_id',
|
||||
'discord_webhook_url',
|
||||
'teams_webhook_url',
|
||||
'google_chat_webhook_url',
|
||||
'webhook_url',
|
||||
'sms_phone_number',
|
||||
'opsgenie_api_key',
|
||||
'pagerduty_integration_key',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -47,9 +57,43 @@ class User extends Authenticatable
|
||||
'email_verified_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
'notification_preferences' => 'array',
|
||||
'notification_channels' => 'array',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get enabled notification channels for a specific alert type
|
||||
*/
|
||||
public function getNotificationChannelsFor(string $alertType): array
|
||||
{
|
||||
$channels = $this->notification_channels ?? [];
|
||||
return $channels[$alertType] ?? ['database'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Route notification for Slack
|
||||
*/
|
||||
public function routeNotificationForSlack(): ?string
|
||||
{
|
||||
return $this->slack_webhook_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Route notification for Telegram
|
||||
*/
|
||||
public function routeNotificationForTelegram(): ?string
|
||||
{
|
||||
return $this->telegram_chat_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Route notification for Discord
|
||||
*/
|
||||
public function routeNotificationForDiscord(): ?string
|
||||
{
|
||||
return $this->discord_webhook_url;
|
||||
}
|
||||
|
||||
public function sites(): HasMany
|
||||
{
|
||||
return $this->hasMany(Site::class);
|
||||
|
||||
Reference in New Issue
Block a user