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/ai.naniguide.com/app/Model/Form.php
<?php

namespace App\Model;

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

/**
 * @property \App\Model\MailList|null $mailList
 * @property \App\Model\Template|null $template
 * @property \App\Model\Customer|null $customer
 */
class Form extends Model implements TemplateSubjectInterface
{
    use HasFactory;
    use HasUid;

    public const STATUS_DRAFT = 'draft';
    public const STATUS_PUBLISHED = 'published';

    protected $fillable = [
        'mail_list_id', 'name'
    ];

    public function mailList()
    {
        return $this->belongsTo('App\Model\MailList');
    }

    public function template()
    {
        return $this->belongsTo('App\Model\Template');
    }

    public function customer()
    {
        return $this->belongsTo(Customer::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;
    }

    public static function newDefault($customer)
    {
        $form = new self();
        $form->name = trans('messages.form.untitled');
        $form->status = self::STATUS_DRAFT;
        $form->customer_id = $customer->id;

        return $form;
    }

    public function createFromArray($params)
    {
        $this->fill($params);

        $validator = Validator::make($params, [
            'name' => 'required',
            'template_uid' => 'required',
            'mail_list_uid' => 'required',
        ]);

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

        $this->mail_list_id = \App\Model\MailList::findByUid($params['mail_list_uid'])->id;
        $selectedTemplate = Template::findByUid($params['template_uid']);
        $this->changeTemplate($selectedTemplate); // also save

        return $validator;
    }

    public function changeTemplate($selectedTemplate)
    {
        $this->setTemplate($selectedTemplate, trans('messages.form.template_name', ['name' => $this->name]));
    }

    public function scopeFilter($query, $params)
    {
        // list
        if (!empty($params['mail_list_uid'])) {
            $query = $query->where('mail_list_id', '=', \App\Model\MailList::findByUid($params['mail_list_uid'])->id);
        }

        // website
        if (!empty($params['website_uid'])) {
            if ($params['website_uid'] === 'none') {
                $query = $query->notConnectedToWebsite();
            } else {
                $website = \App\Model\Website::findByUid($params['website_uid']);
                if ($website) {
                    $query = $query->byWebsite($website);
                }
            }
        }
    }

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

    public function updateMetadata($data)
    {
        $metadata = (object) array_merge((array) $this->getMetadata(), $data);
        $this['metadata'] = json_encode($metadata);

        $this->save();
    }

    public function getMetadata($name = null)
    {
        if (!$this['metadata']) {
            return json_decode('{}', true);
        }

        $data = json_decode($this['metadata'], true);

        if ($name != null) {
            if (isset($data[$name])) {
                return $data[$name];
            } else {
                return null;
            }
        } else {
            return $data;
        }
    }

    public function saveSettingsFromArray($params)
    {
        if (!empty($params['mail_list_uid'])) {
            $list = \App\Model\MailList::findByUid($params['mail_list_uid']);
            if ($list) {
                $this->mail_list_id = $list->id;
            }
        }

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

        $this->updateMetadata([
            'overlay_opacity' => $params['overlay_opacity'] ?? null,
            'display' => $params['display'] ?? null,
            'wait_time' => $params['wait_time'] ?? null,
            'element_id' => $params['element_id'] ?? null,
        ]);
    }

    public function connect($site)
    {
        $this->updateMetadata([
            'website_uid' => $site->uid,
        ]);
    }

    public function getWebsite()
    {
        return $this->getMetadata('website_uid') ? \App\Model\Website::findByUid($this->getMetadata('website_uid')) : null;
    }

    public function disconnect()
    {
        $this->updateMetadata([
            'website_uid' => null,
        ]);
    }

    public static function scopeByWebsite($query, $website)
    {
        $query = $query->where('metadata', 'like', '%'.$website->uid.'%');
    }

    public function scopeNotConnectedToWebsite($query)
    {
        $query->where(function ($q) {
            $q->whereNull('metadata')
              ->orWhere('metadata', 'not like', '%website_uid%')
              ->orWhere('metadata', 'like', '%"website_uid":null%');
        });
    }

    public function getBuilderTags()
    {
        $result = [];

        $tags = [
            ['name' => 'LIST_NAME', 'required' => false],
            ['name' => 'CURRENT_YEAR', 'required' => false],
            ['name' => 'CURRENT_MONTH', 'required' => false],
            ['name' => 'CURRENT_DAY', 'required' => false],
        ];

        foreach ($tags as $tag) {
            $result[] = [
                'type' => 'label',
                'text' => '{'.$tag['name'].'}',
                'tag' => '{'.$tag['name'].'}',
                'required' => true,
            ];
        }

        return $result;
    }

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

        return (new PipelineBuilder())
            ->add(new TransformTag(new GeneralTagResolver(), $this->mailList))
            ->build()
            ->process($content);
    }

    public function publish()
    {
        $this->status = self::STATUS_PUBLISHED;
        $this->save();
    }

    public function unpublish()
    {
        $this->status = self::STATUS_DRAFT;
        $this->save();
    }

    public static function scopePublished($query)
    {
        $query = $query->where('status', '=', self::STATUS_PUBLISHED);
    }

    public function isPublished()
    {
        return $this->status == self::STATUS_PUBLISHED;
    }

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

    /**
     * Reserved input name used by every TermsOfServiceElement instance.
     *
     * Re-exported from `TermsAcceptanceService` (the canonical owner of
     * compliance domain logic) so legacy callers + tests that already
     * referenced `Form::TERMS_RESERVED_NAME` continue to work without
     * changes. The validation walker, pre-flight gate, and any future
     * compliance widgets live in the service layer — see
     * `app/Services/Forms/TermsAcceptanceService.php`.
     */
    public const TERMS_RESERVED_NAME = \App\Services\Forms\TermsAcceptanceService::RESERVED_INPUT_NAME;
}