Files
animexe/app/Models/Ad.php
T
2026-07-14 00:01:48 +03:00

79 lines
2.4 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Models;
use App\Support\MediaUrl;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
class Ad extends Model
{
protected $fillable = [
'name', 'type', 'placement', 'file_path', 'external_url', 'click_url',
'skip_after', 'weight', 'is_active', 'starts_at', 'ends_at',
'impressions', 'clicks',
];
protected $casts = [
'is_active' => 'boolean',
'starts_at' => 'datetime',
'ends_at' => 'datetime',
];
/** Aktif + zamanlaması uygun reklamlar */
public function scopeLive(Builder $q): Builder
{
return $q->where('is_active', true)
->where(fn($s) => $s->whereNull('starts_at')->orWhere('starts_at', '<=', now()))
->where(fn($s) => $s->whereNull('ends_at')->orWhere('ends_at', '>=', now()));
}
/**
* Medya URL'si — yüklenen dosya veya dış URL.
* Yüklenen dosyalar /media/{path} route'undan servis edilir (MediaController);
* public/storage symlink'ine bağımlı değil — kapaklar/avatarlarla aynı yol.
*/
public function getMediaUrlAttribute(): ?string
{
if ($this->file_path) return MediaUrl::fromStoragePath($this->file_path);
if ($this->external_url) return $this->external_url;
return null;
}
/** CTR yüzdesi */
public function getCtrAttribute(): float
{
return $this->impressions > 0
? round($this->clicks / $this->impressions * 100, 2)
: 0.0;
}
/** Ağırlıklı rastgele seçim — pre-roll video reklam */
public static function pickVideo(): ?self
{
return self::weightedPick(
self::live()->where('type', 'video')->where('placement', 'preroll')->get()
);
}
/** Ağırlıklı rastgele seçim — banner (placement bazlı) */
public static function pickBanner(string $placement): ?self
{
return self::weightedPick(
self::live()->where('type', 'banner')->where('placement', $placement)->get()
);
}
private static function weightedPick($ads): ?self
{
if ($ads->isEmpty()) return null;
$total = max(1, $ads->sum('weight'));
$roll = random_int(1, $total);
foreach ($ads as $ad) {
$roll -= max(1, $ad->weight);
if ($roll <= 0) return $ad;
}
return $ads->first();
}
}