customer-riverside/scripts/seed_availability.php
2026-05-13 14:55:52 -07:00

133 lines
4.1 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* Seed provider_availability nodes for the next calendar month.
*
* Usage: drush php-script scripts/seed_availability.php
*
* Options (env vars):
* SEED_DRY_RUN=1 Print what would be created without saving.
* SEED_WIPE=1 Delete existing availability for the period first.
*/
$dryRun = (bool) getenv('SEED_DRY_RUN');
$wipe = (bool) getenv('SEED_WIPE');
// --- Date range: next full calendar month ---
$start = new DateTimeImmutable('first day of next month 00:00:00');
$end = new DateTimeImmutable('last day of next month 23:59:59');
// --- Load providers ---
$providerIds = \Drupal::entityQuery('user')
->condition('roles', 'provider')
->condition('status', 1)
->accessCheck(FALSE)
->execute();
if (empty($providerIds)) {
echo "No active users with the 'provider' role found. Aborting.\n";
return;
}
$providers = \Drupal\user\Entity\User::loadMultiple($providerIds);
echo sprintf("Found %d provider(s): %s\n",
count($providers),
implode(', ', array_map(fn($u) => $u->getDisplayName(), $providers))
);
// --- Optionally wipe existing availability in the range ---
if ($wipe) {
$existing = \Drupal::entityQuery('node')
->condition('type', 'provider_availability')
->condition('field_start_datetime', $start->format('Y-m-d\TH:i:s'), '>=')
->condition('field_start_datetime', $end->format('Y-m-d\TH:i:s'), '<=')
->accessCheck(FALSE)
->execute();
if ($existing) {
echo sprintf("Deleting %d existing availability node(s)...\n", count($existing));
if (!$dryRun) {
$storage = \Drupal::entityTypeManager()->getStorage('node');
$storage->delete($storage->loadMultiple($existing));
}
}
}
// --- Slot generation config ---
// Working hours: 8am4pm (slots are 1 hour, last slot starts at 4pm)
const SLOT_DURATION_MINUTES = 60;
const SLOT_START_HOUR = 8;
const SLOT_END_HOUR = 16;
const SLOT_HOURS = [8, 9, 10, 11, 13, 14, 15, 16]; // skip noon
// Per-provider noise: each provider gets an independent random pattern.
// We use a seeded approach so the same provider always generates the same
// schedule for a given run, but differs from other providers.
function providerSeed(\Drupal\user\Entity\User $user): int {
return crc32($user->getDisplayName() . $user->id());
}
function noisySlotCount(int $providerSeed, DateTimeImmutable $date): int {
// Combine provider seed with day-of-year for per-day variance.
$daySeed = $providerSeed ^ (int) $date->format('z') * 2654435761;
// Map to 05, weighted toward 13.
$raw = abs($daySeed) % 12;
return [0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4, 5][$raw];
}
// --- Generate nodes ---
$created = 0;
$current = $start;
while ($current <= $end) {
foreach ($providers as $provider) {
$count = noisySlotCount(providerSeed($provider), $current);
if ($count === 0) {
$current = $current->modify('+1 day');
continue 2;
}
// Pick $count distinct hours from SLOT_HOURS without replacement.
$hours = SLOT_HOURS;
shuffle($hours);
$selectedHours = array_slice($hours, 0, $count);
sort($selectedHours);
foreach ($selectedHours as $hour) {
$slotStart = $current->setTime($hour, 0);
$slotEnd = $slotStart->modify('+' . SLOT_DURATION_MINUTES . ' minutes');
$label = sprintf('%s — %s',
$provider->getDisplayName(),
$slotStart->format('Y-m-d H:i')
);
if ($dryRun) {
echo "[DRY RUN] Would create: $label\n";
} else {
\Drupal\node\Entity\Node::create([
'type' => 'provider_availability',
'title' => $label,
'status' => 1,
'uid' => 1,
'field_provider' => ['target_id' => $provider->id()],
'field_start_datetime' => $slotStart->format('Y-m-d\TH:i:s'),
'field_end_datetime' => $slotEnd->format('Y-m-d\TH:i:s'),
])->save();
}
$created++;
}
}
$current = $current->modify('+1 day');
}
$verb = $dryRun ? 'Would create' : 'Created';
echo sprintf("%s %d availability slot(s) across %d provider(s) for %s.\n",
$verb,
$created,
count($providers),
$start->format('F Y')
);