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/hi.naniguide.com/app/Services/PersonalizationService.php
<?php

namespace App\Services;

use App\Models\CampaignRecipient;
use App\Models\ListSubscriber;

class PersonalizationService
{
    private const STANDARD_TAG_KEYS = ['first_name', 'last_name', 'email', 'full_name', 'name', 'unsubscribe_url'];

    public function personalizeForSubscriber(string $content, ListSubscriber $subscriber, bool $replaceBareStandardTags = true): string
    {
        $fullName = trim((string) (($subscriber->first_name ?? '') . ' ' . ($subscriber->last_name ?? '')));
        $standardValues = [
            'first_name' => (string) ($subscriber->first_name ?? ''),
            'last_name' => (string) ($subscriber->last_name ?? ''),
            'email' => (string) $subscriber->email,
            'full_name' => $fullName,
            'name' => $fullName,
            'unsubscribe_url' => '',
        ];

        $replacements = [
            // Handle @ prefixed tags used in the UI (longest first)
            '@{{first_name}}' => $standardValues['first_name'],
            '@{{last_name}}' => $standardValues['last_name'],
            '@{{email}}' => $standardValues['email'],
            '@{{full_name}}' => $standardValues['full_name'],
            '@{{name}}' => $standardValues['name'],
            '@{{unsubscribe_url}}' => $standardValues['unsubscribe_url'],
            // Double brace patterns (longer)
            '{{first_name}}' => $standardValues['first_name'],
            '{{last_name}}' => $standardValues['last_name'],
            '{{email}}' => $standardValues['email'],
            '{{full_name}}' => $standardValues['full_name'],
            '{{name}}' => $standardValues['name'],
            '{{unsubscribe_url}}' => $standardValues['unsubscribe_url'],
            // Single brace patterns (shorter - must be last)
            '{first_name}' => $standardValues['first_name'],
            '{last_name}' => $standardValues['last_name'],
            '{email}' => $standardValues['email'],
            '{full_name}' => $standardValues['full_name'],
            '{name}' => $standardValues['name'],
            '{unsubscribe_url}' => $standardValues['unsubscribe_url'],
        ];

        $content = str_replace(array_keys($replacements), array_values($replacements), $content);
        if ($replaceBareStandardTags) {
            $content = $this->replaceBareStandardTags($content, $standardValues);
        }

        $custom = is_array($subscriber->custom_fields) ? $subscriber->custom_fields : [];
        return $this->replaceCustomFieldTags($content, $custom);
    }

    public function personalizeForCampaignRecipient(string $content, CampaignRecipient $recipient, bool $replaceBareStandardTags = true): string
    {
        $fullName = trim((string) (($recipient->first_name ?? '') . ' ' . ($recipient->last_name ?? '')));
        $standardValues = [
            'first_name' => (string) ($recipient->first_name ?? ''),
            'last_name' => (string) ($recipient->last_name ?? ''),
            'email' => (string) $recipient->email,
            'full_name' => $fullName,
            'name' => $fullName,
            'unsubscribe_url' => '',
        ];

        $replacements = [
            // Handle @ prefixed tags used in the UI (longest first)
            '@{{first_name}}' => $standardValues['first_name'],
            '@{{last_name}}' => $standardValues['last_name'],
            '@{{email}}' => $standardValues['email'],
            '@{{full_name}}' => $standardValues['full_name'],
            '@{{name}}' => $standardValues['name'],
            '@{{unsubscribe_url}}' => $standardValues['unsubscribe_url'],
            // Double brace patterns (longer)
            '{{first_name}}' => $standardValues['first_name'],
            '{{last_name}}' => $standardValues['last_name'],
            '{{email}}' => $standardValues['email'],
            '{{full_name}}' => $standardValues['full_name'],
            '{{name}}' => $standardValues['name'],
            '{{unsubscribe_url}}' => $standardValues['unsubscribe_url'],
            // Single brace patterns (shorter - must be last)
            '{first_name}' => $standardValues['first_name'],
            '{last_name}' => $standardValues['last_name'],
            '{email}' => $standardValues['email'],
            '{full_name}' => $standardValues['full_name'],
            '{name}' => $standardValues['name'],
            '{unsubscribe_url}' => $standardValues['unsubscribe_url'],
        ];

        $content = str_replace(array_keys($replacements), array_values($replacements), $content);
        if ($replaceBareStandardTags) {
            $content = $this->replaceBareStandardTags($content, $standardValues);
        }

        $meta = is_array($recipient->meta) ? $recipient->meta : [];
        $custom = (isset($meta['custom_fields']) && is_array($meta['custom_fields'])) ? $meta['custom_fields'] : [];

        return $this->replaceCustomFieldTags($content, $custom);
    }

    public function replaceCustomFieldTags(string $content, array $customFields): string
    {
        if ($content === '') {
            return '';
        }

        return (string) preg_replace_callback('/(?:@?\{\{cf[:_]?([a-zA-Z][a-zA-Z0-9_]*)\}\})|(?:@?\{cf[:_]?([a-zA-Z][a-zA-Z0-9_]*)\})/', function ($m) use ($customFields) {
            $key = (string) (($m[1] ?? '') !== '' ? ($m[1] ?? '') : ($m[2] ?? ''));
            $value = $customFields[$key] ?? '';

            if ($value === null) {
                return '';
            }

            if (is_scalar($value)) {
                return (string) $value;
            }

            return '';
        }, $content);
    }

    public function convertPlaceholdersToZeptoMergeTags(string $content, bool $replaceBareStandardTags = true): string
    {
        $content = str_replace(
            ['{first_name}', '{last_name}', '{email}', '{full_name}', '{name}', '{unsubscribe_url}', '@{{first_name}}', '@{{last_name}}', '@{{email}}', '@{{full_name}}', '@{{name}}', '@{{unsubscribe_url}}'],
            ['{{first_name}}', '{{last_name}}', '{{email}}', '{{full_name}}', '{{full_name}}', '{{unsubscribe_url}}', '{{first_name}}', '{{last_name}}', '{{email}}', '{{full_name}}', '{{full_name}}', '{{unsubscribe_url}}'],
            $content
        );

        if ($replaceBareStandardTags) {
            $content = $this->replaceBareStandardTags($content, [
                'first_name' => '{{first_name}}',
                'last_name' => '{{last_name}}',
                'email' => '{{email}}',
                'full_name' => '{{full_name}}',
                'name' => '{{full_name}}',
                'unsubscribe_url' => '{{unsubscribe_url}}',
            ]);
        }

        return (string) preg_replace_callback('/(?:@?\{\{cf[:_]?([a-zA-Z][a-zA-Z0-9_]*)\}\})|(?:@?\{cf[:_]?([a-zA-Z][a-zA-Z0-9_]*)\})/', function ($m) {
            $key = (string) (($m[1] ?? '') !== '' ? ($m[1] ?? '') : ($m[2] ?? ''));
            if ($key === '') {
                return '';
            }
            return '{{cf_' . $key . '}}';
        }, $content);
    }

    private function replaceBareStandardTags(string $content, array $values): string
    {
        if ($content === '' || empty($values)) {
            return $content;
        }

        $availableKeys = array_values(array_intersect(self::STANDARD_TAG_KEYS, array_keys($values)));
        if (empty($availableKeys)) {
            return $content;
        }

        $pattern = '/(?<![a-zA-Z0-9_])(' . implode('|', array_map('preg_quote', $availableKeys)) . ')(?![a-zA-Z0-9_])/i';

        return (string) preg_replace_callback($pattern, function ($match) use ($values) {
            $key = strtolower((string) ($match[1] ?? ''));
            return array_key_exists($key, $values) ? (string) $values[$key] : (string) ($match[0] ?? '');
        }, $content);
    }
}