HEX
Server: LiteSpeed
System: Linux s1049.use1.mysecurecloudhost.com 4.18.0-477.27.2.lve.el8.x86_64 #1 SMP Wed Oct 11 12:32:56 UTC 2023 x86_64
User: xedaptot (3356)
PHP: 8.3.31
Disabled: NONE
Upload Files
File: /home/xedaptot/be.naniguide.com/app/Model/AdTemplate.php
<?php

namespace App\Model;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use App\Library\Traits\HasUid;

class AdTemplate extends Model
{
    use HasFactory;
    use HasUid;

    const STATUS_ACTIVE = 'active'; // for HasUid trait compatibility

    const FORMAT_IMAGE = 'image';
    const FORMAT_VIDEO = 'video';
    const FORMAT_CAROUSEL = 'carousel';
    const FORMAT_STORY = 'story';
    const FORMAT_FEED = 'feed';

    const FORMATS = [
        self::FORMAT_IMAGE,
        self::FORMAT_VIDEO,
        self::FORMAT_CAROUSEL,
        self::FORMAT_STORY,
        self::FORMAT_FEED,
    ];

    const FORMAT_LABELS = [
        self::FORMAT_IMAGE => 'Image Ad',
        self::FORMAT_VIDEO => 'Video Ad',
        self::FORMAT_CAROUSEL => 'Carousel Ad',
        self::FORMAT_STORY => 'Story Ad',
        self::FORMAT_FEED => 'Feed Ad',
    ];

    const PLATFORM_UNIVERSAL = 'universal';

    protected $table = 'ad_templates';

    protected $fillable = [
        'uid',
        'customer_id',
        'name',
        'platform',
        'format',
        'thumbnail_url',
        'content',
        'category',
        'is_featured',
        'use_count',
    ];

    protected $casts = [
        'content' => 'json',
        'is_featured' => 'boolean',
        'use_count' => 'integer',
    ];

    public function customer(): BelongsTo
    {
        return $this->belongsTo(Customer::class, 'customer_id');
    }

    public function scopeOfCustomer($query, $customerId)
    {
        return $query->where('customer_id', $customerId);
    }

    public function scopeSystem($query)
    {
        return $query->whereNull('customer_id');
    }

    public function scopeAvailableTo($query, $customerId)
    {
        return $query->where(function ($q) use ($customerId) {
            $q->whereNull('customer_id')->orWhere('customer_id', $customerId);
        });
    }

    public function scopeOfPlatform($query, $platform)
    {
        if (!$platform) return $query;
        return $query->where(function ($q) use ($platform) {
            $q->where('platform', $platform)->orWhere('platform', self::PLATFORM_UNIVERSAL);
        });
    }

    public function scopeOfFormat($query, $format)
    {
        if (!$format) return $query;
        return $query->where('format', $format);
    }

    public function scopeSearch($query, $keyword)
    {
        return $keyword ? $query->where('name', 'like', '%' . $keyword . '%') : $query;
    }

    public function getFormatLabelAttribute(): string
    {
        return self::FORMAT_LABELS[$this->format] ?? ucfirst($this->format);
    }

    public function getPlatformLabelAttribute(): string
    {
        if ($this->platform === self::PLATFORM_UNIVERSAL || !$this->platform) {
            return 'Universal';
        }
        return AdPlatform::PLATFORM_LABELS[$this->platform] ?? ucfirst($this->platform);
    }

    public function isSystemTemplate(): bool
    {
        return $this->customer_id === null;
    }

    public function incrementUseCount(): void
    {
        $this->increment('use_count');
    }

    /**
     * Store thumbnail in storage (same pattern as Template model).
     * NOT in public/ — that's git-tracked and accumulates across reseeds.
     */
    public function updateThumbnailFromPath(string $absolutePath): void
    {
        if (!is_file($absolutePath)) return;
        $ext = pathinfo($absolutePath, PATHINFO_EXTENSION) ?: 'svg';
        $dest = $this->getThumbStoragePath($ext);
        if (!is_dir(dirname($dest))) {
            @mkdir(dirname($dest), 0755, true);
        }
        copy($absolutePath, $dest);
        $this->thumbnail_url = $ext; // just store extension, path derived from uid
        $this->save();
    }

    /**
     * Full storage path for the thumbnail file.
     */
    public function getThumbStoragePath(?string $ext = null): string
    {
        $ext = $ext ?: ($this->thumbnail_url ?: 'svg');
        return storage_path('app/public/ad-templates/thumb/' . $this->uid . '.' . $ext);
    }

    /**
     * Read inline SVG content for dark-mode-compatible rendering.
     * Returns null if no thumbnail exists.
     */
    public function getInlineSvg(): ?string
    {
        $path = $this->getThumbStoragePath();
        return is_file($path) ? file_get_contents($path) : null;
    }

    protected static function newFactory()
    {
        return \Database\Factories\AdTemplateFactory::new();
    }
}