Add homepage announcement module
This commit is contained in:
197
app/Models/HomepageAnnouncement.php
Normal file
197
app/Models/HomepageAnnouncement.php
Normal file
@@ -0,0 +1,197 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class HomepageAnnouncement extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
public const STATUS_DRAFT = 'draft';
|
||||
public const STATUS_PUBLISHED = 'published';
|
||||
public const STATUS_ARCHIVED = 'archived';
|
||||
|
||||
public const TYPE_ANNOUNCEMENT = 'announcement';
|
||||
public const TYPE_LAUNCH = 'launch';
|
||||
public const TYPE_NEWS = 'news';
|
||||
public const TYPE_WORLD = 'world';
|
||||
public const TYPE_EVENT = 'event';
|
||||
public const TYPE_NOTICE = 'notice';
|
||||
public const TYPE_MAINTENANCE = 'maintenance';
|
||||
|
||||
public const PLACEMENT_HOMEPAGE_AFTER_FEATURED = 'homepage_after_featured';
|
||||
|
||||
public const LINK_TYPE_NONE = 'none';
|
||||
public const LINK_TYPE_CUSTOM_URL = 'custom_url';
|
||||
public const LINK_TYPE_NEWS = 'news';
|
||||
public const LINK_TYPE_WORLD = 'world';
|
||||
public const LINK_TYPE_ARTWORK = 'artwork';
|
||||
public const LINK_TYPE_COLLECTION = 'collection';
|
||||
public const LINK_TYPE_GROUP = 'group';
|
||||
public const LINK_TYPE_PROFILE = 'profile';
|
||||
public const LINK_TYPE_EXPLORE = 'explore';
|
||||
public const LINK_TYPE_UPLOAD = 'upload';
|
||||
|
||||
public const GRADIENT_NOVA_AURORA = 'nova_aurora';
|
||||
public const GRADIENT_DEEP_SPACE = 'deep_space';
|
||||
public const GRADIENT_SUNRISE = 'sunrise';
|
||||
public const GRADIENT_OCEAN_GLOW = 'ocean_glow';
|
||||
public const GRADIENT_SPRING_VIBES = 'spring_vibes';
|
||||
public const GRADIENT_FANTASY_REALMS = 'fantasy_realms';
|
||||
public const GRADIENT_MINIMAL_LIGHT = 'minimal_light';
|
||||
public const GRADIENT_DARK_GLASS = 'dark_glass';
|
||||
|
||||
protected $table = 'homepage_announcements';
|
||||
|
||||
protected $fillable = [
|
||||
'title',
|
||||
'subtitle',
|
||||
'badge_text',
|
||||
'content_html',
|
||||
'type',
|
||||
'status',
|
||||
'is_active',
|
||||
'starts_at',
|
||||
'ends_at',
|
||||
'primary_link_label',
|
||||
'primary_link_type',
|
||||
'primary_link_url',
|
||||
'primary_link_target_type',
|
||||
'primary_link_target_id',
|
||||
'secondary_link_label',
|
||||
'secondary_link_type',
|
||||
'secondary_link_url',
|
||||
'secondary_link_target_type',
|
||||
'secondary_link_target_id',
|
||||
'background_type',
|
||||
'background_image',
|
||||
'gradient_preset',
|
||||
'theme_preset',
|
||||
'text_color',
|
||||
'overlay_opacity',
|
||||
'placement',
|
||||
'priority',
|
||||
'is_dismissible',
|
||||
'dismiss_version',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'is_active' => 'boolean',
|
||||
'starts_at' => 'datetime',
|
||||
'ends_at' => 'datetime',
|
||||
'primary_link_target_id' => 'integer',
|
||||
'secondary_link_target_id' => 'integer',
|
||||
'overlay_opacity' => 'integer',
|
||||
'priority' => 'integer',
|
||||
'is_dismissible' => 'boolean',
|
||||
'dismiss_version' => 'integer',
|
||||
];
|
||||
|
||||
public static function statuses(): array
|
||||
{
|
||||
return [
|
||||
self::STATUS_DRAFT,
|
||||
self::STATUS_PUBLISHED,
|
||||
self::STATUS_ARCHIVED,
|
||||
];
|
||||
}
|
||||
|
||||
public static function types(): array
|
||||
{
|
||||
return [
|
||||
self::TYPE_ANNOUNCEMENT,
|
||||
self::TYPE_LAUNCH,
|
||||
self::TYPE_NEWS,
|
||||
self::TYPE_WORLD,
|
||||
self::TYPE_EVENT,
|
||||
self::TYPE_NOTICE,
|
||||
self::TYPE_MAINTENANCE,
|
||||
];
|
||||
}
|
||||
|
||||
public static function placements(): array
|
||||
{
|
||||
return [
|
||||
self::PLACEMENT_HOMEPAGE_AFTER_FEATURED,
|
||||
];
|
||||
}
|
||||
|
||||
public static function linkTypes(): array
|
||||
{
|
||||
return [
|
||||
self::LINK_TYPE_NONE,
|
||||
self::LINK_TYPE_CUSTOM_URL,
|
||||
self::LINK_TYPE_NEWS,
|
||||
self::LINK_TYPE_WORLD,
|
||||
self::LINK_TYPE_ARTWORK,
|
||||
self::LINK_TYPE_COLLECTION,
|
||||
self::LINK_TYPE_GROUP,
|
||||
self::LINK_TYPE_PROFILE,
|
||||
self::LINK_TYPE_EXPLORE,
|
||||
self::LINK_TYPE_UPLOAD,
|
||||
];
|
||||
}
|
||||
|
||||
public static function gradientPresets(): array
|
||||
{
|
||||
return [
|
||||
self::GRADIENT_NOVA_AURORA,
|
||||
self::GRADIENT_DEEP_SPACE,
|
||||
self::GRADIENT_SUNRISE,
|
||||
self::GRADIENT_OCEAN_GLOW,
|
||||
self::GRADIENT_SPRING_VIBES,
|
||||
self::GRADIENT_FANTASY_REALMS,
|
||||
self::GRADIENT_MINIMAL_LIGHT,
|
||||
self::GRADIENT_DARK_GLASS,
|
||||
];
|
||||
}
|
||||
|
||||
public function scopePublished(Builder $query): Builder
|
||||
{
|
||||
return $query->where('status', self::STATUS_PUBLISHED);
|
||||
}
|
||||
|
||||
public function scopeActive(Builder $query): Builder
|
||||
{
|
||||
return $query->where('is_active', true);
|
||||
}
|
||||
|
||||
public function scopeVisibleNow(Builder $query, ?Carbon $now = null): Builder
|
||||
{
|
||||
$now ??= now();
|
||||
|
||||
return $query
|
||||
->where(function (Builder $builder) use ($now): void {
|
||||
$builder->whereNull('starts_at')
|
||||
->orWhere('starts_at', '<=', $now);
|
||||
})
|
||||
->where(function (Builder $builder) use ($now): void {
|
||||
$builder->whereNull('ends_at')
|
||||
->orWhere('ends_at', '>=', $now);
|
||||
});
|
||||
}
|
||||
|
||||
public function scopeForPlacement(Builder $query, string $placement): Builder
|
||||
{
|
||||
return $query->where('placement', $placement);
|
||||
}
|
||||
|
||||
public function createdBy(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updatedBy(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user