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/database/seeders/Demo/Stage07_MailListsSeeder.php
<?php

namespace Database\Seeders\Demo;

use App\Model\MailList;
use App\Model\Segment;

/**
 * Stage 07 — mail lists, custom fields, segments, list templates.
 *
 * Each customer gets `lists` count from DemoConfig — typically 2-6 lists.
 * Each list has:
 *   - the mandatory EMAIL field (auto-created via createField with isEmail=true)
 *   - 4-6 extra custom fields (FIRST_NAME, LAST_NAME, COMPANY, etc.)
 *   - 2-3 segments with realistic matching rules
 *   - default mail list templates (signup form, confirmation, etc.)
 *
 * Stores each created list in self::$created[$customer_key] = [MailList, ...]
 * so Stage08_SubscribersSeeder can iterate over them.
 */
class Stage07_MailListsSeeder extends AbstractDemoSeeder
{
    protected int $fakerOffset = 7;

    /** customer_key → MailList[] */
    public static array $created = [];

    public function run(): void
    {
        $customers = Stage03_CustomersSeeder::$created;
        $f = $this->faker();

        foreach (DemoConfig::customers() as $cfg) {
            $customer = $customers[$cfg['key']] ?? null;
            if (!$customer) continue;

            self::$created[$cfg['key']] = [];
            $companySlug = preg_replace('/[^a-z0-9]/', '', strtolower($cfg['company']));
            $domain      = $companySlug . '.demo';

            for ($i = 0; $i < ($cfg['lists'] ?? 0); $i++) {
                $list = $customer->newMailList();
                $list->name             = DemoFaker::listName($i, $cfg['company']);
                $list->from_email       = 'newsletter@' . $domain;
                $list->from_name        = DemoFaker::fromName($cfg['company']);
                $list->remind_message   = "You're receiving this email because you signed up at " . $domain;
                $list->email_subscribe   = 'newsletter@' . $domain;
                $list->email_unsubscribe = 'newsletter@' . $domain;
                $list->email_daily       = 'newsletter@' . $domain;
                $list->send_welcome_email      = $f->boolean(70);
                $list->unsubscribe_notification = $f->boolean(50);
                $list->subscribe_confirmation   = $f->boolean(50) ? 1 : 0;
                // Spread list create dates across last 30 days so dashboard
                // "recent activity" widgets show realistic timestamps instead
                // of all-now. Eloquent respects pre-set timestamps on insert.
                $listCreatedAt = now()->subDays(mt_rand(0, 30))->subSeconds(mt_rand(0, 86399));
                $list->created_at = $listCreatedAt;
                $list->updated_at = $listCreatedAt;
                $list->save();

                $this->seedFieldsFor($list);
                $list->resetDefaultTemplates();
                $this->seedSegmentsFor($list);

                self::$created[$cfg['key']][] = $list;
            }
            $this->log("customer {$cfg['key']}: " . count(self::$created[$cfg['key']]) . " lists");
        }
    }

    /**
     * Create the standard set of custom fields. Email field is mandatory and
     * MUST be created (with isEmail=true) so subscribers have an email column.
     */
    protected function seedFieldsFor(MailList $list): void
    {
        // Email field FIRST (required, marks itself as is_email=true).
        try {
            $list->createField('text', 'EMAIL', 'Email', '', true, true, true);
        } catch (\Throwable $e) {
            // tag exists — ignore
        }

        $extras = [
            ['text',   'FIRST_NAME',     'First Name',     false, true],
            ['text',   'LAST_NAME',      'Last Name',      false, true],
            ['text',   'COMPANY',        'Company',        false, true],
            ['text',   'ADDRESS',        'Address',        false, true],
            ['text',   'PHONE',          'Phone',          false, true],
            ['text',   'WEB',            'Web',            false, true],
            ['date',   'DATE_OF_BIRTH',  'Date of Birth',  false, true],
        ];
        foreach ($extras as [$type, $tag, $label, $required, $visible]) {
            try {
                $list->createField($type, $tag, $label, '', $required, $visible, false);
            } catch (\Throwable $e) {
                // tag exists or column conflict — skip
            }
        }
    }

    /**
     * Create 2-3 segments with realistic matching JSON.
     * `matching` is JSON like { "any|all": ..., "conditions": [...] } —
     * we use a minimal valid structure that the segments page renders.
     */
    protected function seedSegmentsFor(MailList $list): void
    {
        $f = DemoFaker::get();
        $segments = [
            [
                'name' => 'Active subscribers',
                'matching' => json_encode([
                    'match' => 'all',
                    'conditions' => [
                        ['field' => 'status', 'operator' => 'is', 'value' => 'subscribed'],
                    ],
                ]),
            ],
            [
                'name' => 'Recent signups (last 30 days)',
                'matching' => json_encode([
                    'match' => 'all',
                    'conditions' => [
                        ['field' => 'created_at', 'operator' => 'after', 'value' => now()->subDays(30)->toDateString()],
                    ],
                ]),
            ],
            [
                'name' => 'Engaged openers',
                'matching' => json_encode([
                    'match' => 'any',
                    'conditions' => [
                        ['field' => 'opens', 'operator' => 'greater_than', 'value' => 3],
                    ],
                ]),
            ],
        ];
        $count = $f->numberBetween(2, 3);
        foreach (array_slice($segments, 0, $count) as $seg) {
            $s = new Segment();
            $s->mail_list_id = $list->id;
            $s->customer_id  = $list->customer_id;
            $s->name         = $seg['name'];
            $s->matching     = $seg['matching'];
            $s->save();
        }
    }
}