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

namespace App\Model;

use Illuminate\Database\Eloquent\Model;
use App\Library\Contracts\TemplateSubjectInterface;
use App\Library\GeneralTagResolver;
use App\Library\MailListTemplateTagResolver;
use App\Library\Traits\HasUid;
use League\Pipeline\PipelineBuilder;
use App\Library\HtmlHandler\GenerateSpintax;
use App\Library\HtmlHandler\DecodeHtmlSpecialChars;
use App\Library\HtmlHandler\ReplaceBareLineFeed;
use App\Library\HtmlHandler\TransformTag;
use App\Library\HtmlHandler\TransformUrl;
use App\Library\HtmlHandler\MakeInlineCss;
use App\Services\TemplateService;

/**
 * @property \App\Model\MailList|null $mailList
 * @property \App\Model\Template|null $template
 * @property string $alias
 */
class MailListTemplate extends Model implements TemplateSubjectInterface
{
    use HasUid;

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

        // When a MailListTemplate is deleted, also delete its associated Template record
        static::deleting(function ($item) {
            if ($item->template) {
                $item->template->deleteAndCleanup();
            }
        });
    }

    /**
     * Associations.
     *
     * @var object | collect
     */
    public function mailList()
    {
        return $this->belongsTo(MailList::class);
    }

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

    /**
     * Render content.
     *
     * Tag resolution flows through TagResolverInterface: each chained resolver
     * contributes a tag namespace, later resolvers override earlier ones.
     * Templates use Twig syntax ({{ TAG }} / {{ list.name }} — both casings work).
     *
     * @var html
     */
    public function renderContent($values = null, $subscriber = null, $messageId = null)
    {
        return (new PipelineBuilder())
            ->add(new TransformTag(...$this->buildResolvers($values, $subscriber, $messageId)))
            ->add(new TransformUrl($msgId = null, $domain = null, $trackLink = false))
            ->add(new DecodeHtmlSpecialChars())
            ->add(new GenerateSpintax())
            ->add(new ReplaceBareLineFeed())
            ->build()
            ->process($this->template->content);
    }

    /**
     * Render transformed subject. Same resolver chain as renderContent — subject
     * strings reference the same tag vocabulary (page_title, subscribe_button, ...).
     *
     * @var string
     */
    public function getTransformedSubject($subscriber)
    {
        $subject = trans('messages.' . $this->alias);

        if (empty($subject)) {
            return $subject;
        }

        return (new PipelineBuilder())
            ->add(new TransformTag(...$this->buildResolvers(null, $subscriber, null)))
            ->build()
            ->process($subject);
    }

    /**
     * Compose the resolver chain. Order = precedence (later wins via array_merge
     * inside TagTranslationService): GeneralTagResolver provides ISO defaults
     * (current_year, current_date, ...), MailList contributes list.* and
     * Subscriber contributes subscriber.* + global flat keys (email, name, ...).
     * MailListTemplateTagResolver runs last so it can override page-context tags
     * like current_date with the customer-localized format and unsubscribe_url
     * with the form-flow URL.
     *
     * @return array<\App\Library\Contracts\TagResolverInterface>
     */
    private function buildResolvers($values, $subscriber, $messageId): array
    {
        return array_values(array_filter([
            new GeneralTagResolver(),
            $this->mailList,
            $subscriber,
            new MailListTemplateTagResolver($this, $values, $subscriber, $messageId),
        ]));
    }


    public function tags()
    {
        // Twig-style tag labels — match the {{ TAG }} syntax that
        // {@see MailListTemplateTagResolver} + TagTranslationService resolve.
        $listTags = $this->mailList->fields->map(function ($field) {
            return ['name' => '{{ SUBSCRIBER_' . $field->tag . ' }}', 'required' => false];
        })->toArray();

        $tags = match ($this->alias) {
            'sign_up_form' => [
                ['name' => '{{ FIELDS }}', 'required' => true],
                ['name' => '{{ SUBSCRIBE_BUTTON }}', 'required' => true],
            ],
            'sign_up_confirmation_email' => [
                ['name' => '{{ SUBSCRIBE_CONFIRM_URL }}', 'required' => true],
            ],
            'sign_up_welcome_email' => [
                ['name' => '{{ UNSUBSCRIBE_URL }}', 'required' => true],
            ],
            'unsubscribe_form' => [
                ['name' => '{{ UNSUBSCRIBE_BUTTON }}', 'required' => true],
            ],
            'profile_update_email' => [
                ['name' => '{{ UPDATE_PROFILE_URL }}', 'required' => true],
            ],
            'profile_update_form' => [
                ['name' => '{{ FIELDS }}', 'required' => true],
                ['name' => '{{ UPDATE_PROFILE_BUTTON }}', 'required' => true],
                ['name' => '{{ UNSUBSCRIBE_URL }}', 'required' => true],
            ],
            'sign_up_confirmation_page',
            'sign_up_thankyou_page',
            'unsubscribe_success_page',
            'unsubscribe_goodbye_email',
            'profile_update_email_sent',
            'profile_update_success_page' => [],
            default => [],
        };

        $tags[] = ['name' => '{{ LIST_NAME }}', 'required' => false];

        if (!in_array($this->alias, ['sign_up_form'])) {
            $tags = array_merge($listTags, $tags);
        }

        return $tags;
    }

    public function restoreSystemTemplate()
    {
        \DB::transaction(function () {
            // Find system template by alias
            $originalTemplate = SystemTemplate::findByAliasOrFail($this->alias)->template;
            TemplateService::for($this)->setTemplate($originalTemplate, $this->alias);
        });
    }
}