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/FunnelStep.php
<?php

namespace App\Model;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
use App\Library\Traits\HasUid;
use App\Library\Contracts\TemplateSubjectInterface;
use App\Library\GeneralTagResolver;
use App\Library\HtmlHandler\TransformTag;
use App\Services\TemplateService;
use League\Pipeline\PipelineBuilder;
use Validator;

/**
 * @property \App\Model\Funnel|null $funnel
 * @property \App\Model\Template|null $template
 */
class FunnelStep extends Model implements TemplateSubjectInterface
{
    use HasUid;

    protected $fillable = [
        'name', 'type', 'slug', 'sort_order', 'settings', 'is_published',
    ];

    protected $casts = [
        'settings'     => 'array',
        'is_published' => 'boolean',
        'sort_order'   => 'integer',
    ];

    // Step types
    public const TYPE_LANDING        = 'landing';
    public const TYPE_OPTIN          = 'optin';
    public const TYPE_THANK_YOU      = 'thank_you';
    public const TYPE_SALES          = 'sales';
    public const TYPE_PRODUCT_DETAIL = 'product_detail';
    public const TYPE_CART           = 'cart';
    public const TYPE_CHECKOUT       = 'checkout';
    public const TYPE_UPSELL         = 'upsell';
    public const TYPE_DOWNSELL       = 'downsell';
    public const TYPE_CUSTOM         = 'custom';

    public static function stepTypes()
    {
        return [
            self::TYPE_LANDING,
            self::TYPE_OPTIN,
            self::TYPE_THANK_YOU,
            self::TYPE_SALES,
            self::TYPE_PRODUCT_DETAIL,
            self::TYPE_CART,
            self::TYPE_CHECKOUT,
            self::TYPE_UPSELL,
            self::TYPE_DOWNSELL,
            self::TYPE_CUSTOM,
        ];
    }

    // -------------------------------------------------------------------------
    // Boot
    // -------------------------------------------------------------------------

    protected static function boot()
    {
        parent::boot();

        static::creating(function ($step) {
            if (empty($step->slug) && $step->name) {
                $step->slug = $step->generateUniqueSlug($step->name);
            }
        });
    }

    // -------------------------------------------------------------------------
    // Relationships
    // -------------------------------------------------------------------------

    public function funnel()
    {
        return $this->belongsTo(Funnel::class);
    }

    public function template()
    {
        return $this->belongsTo(Template::class);
    }

    public function hasTemplate(): bool
    {
        return !is_null($this->template_id) && $this->template()->exists();
    }

    public function getThumbUrl(): string
    {
        return $this->template
            ? $this->template->getThumbUrl()
            : url('images/placeholder.jpg');
    }

    public function setTemplate($template, string $name): void
    {
        TemplateService::for($this)->setTemplate($template, $name);
    }

    public function removeTemplate(): void
    {
        TemplateService::for($this)->removeTemplate();
    }

    public function setTemplateContent($content, $json): void
    {
        $this->template->updateContent($json, $content);
    }

    public function getTemplateContent(): string
    {
        return $this->template->content;
    }

    // -------------------------------------------------------------------------
    // Scopes
    // -------------------------------------------------------------------------

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

    public function scopePublished($query)
    {
        return $query->where('is_published', true);
    }

    public function scopeOrdered($query)
    {
        return $query->orderBy('sort_order');
    }

    // -------------------------------------------------------------------------
    // CRUD helpers
    // -------------------------------------------------------------------------

    public function fillParams($params)
    {
        $this->name = $params['name'] ?? $this->name;
        $this->type = $params['type'] ?? $this->type;

        if (!empty($params['slug'])) {
            $this->slug = $params['slug'];
        }

        if (isset($params['is_published'])) {
            $this->is_published = (bool) $params['is_published'];
        }

        if (isset($params['settings'])) {
            $this->settings = $params['settings'];
        }
    }

    public function saveFromParams($params)
    {
        $this->fillParams($params);

        $validator = Validator::make($params, [
            'name' => 'required|max:255',
            'type' => 'required|in:' . implode(',', self::stepTypes()),
        ]);

        if ($validator->fails()) {
            return $validator;
        }

        $this->save();

        return $validator;
    }

    // -------------------------------------------------------------------------
    // Slug
    // -------------------------------------------------------------------------

    public function generateUniqueSlug($name)
    {
        $slug = Str::slug($name);
        $original = $slug;
        $count = 1;

        while (self::where('funnel_id', $this->funnel_id)
            ->where('slug', $slug)
            ->where('id', '!=', $this->id ?? 0)
            ->exists()
        ) {
            $slug = $original . '-' . $count++;
        }

        return $slug;
    }

    // -------------------------------------------------------------------------
    // URL
    // -------------------------------------------------------------------------

    public function getPublicUrl()
    {
        return url('f/' . $this->funnel->slug . '/' . $this->slug);
    }

    // -------------------------------------------------------------------------
    // Content rendering
    // -------------------------------------------------------------------------

    public function renderedContent($content = null)
    {
        if (!$content && $this->template) {
            $content = $this->template->content;
        }

        if (!$content) {
            return '';
        }

        $resolvers = array_values(array_filter([
            new GeneralTagResolver(),
            $this->funnel?->mailList,
        ]));

        return (new PipelineBuilder())
            ->add(new TransformTag(...$resolvers))
            ->build()
            ->process($content);
    }

    public function isStageExcluded(string $name): bool
    {
        return false;
    }

    // -------------------------------------------------------------------------
    // Duplicate
    // -------------------------------------------------------------------------

    public function duplicateTo(Funnel $targetFunnel)
    {
        $copy = $this->replicate(['uid', 'slug']);
        $copy->funnel_id = $targetFunnel->id;
        $copy->slug = $copy->generateUniqueSlug($this->name);
        $copy->template_id = null;
        $copy->save();

        if ($this->template) {
            TemplateService::for($copy)->setTemplate($this->template, $copy->name);
        }

        return $copy;
    }

    public function deleteAndCleanup()
    {
        TemplateService::for($this)->removeTemplate();
        $this->delete();
    }
}