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();
}
}
}