2026-05-01 04:24:10 -08:00
|
|
|
<?php
|
|
|
|
|
|
2026-05-14 19:05:46 -08:00
|
|
|
use Drupal\node\Entity\Node;
|
2026-05-01 04:24:10 -08:00
|
|
|
use Drupal\node\Entity\NodeType;
|
2026-05-14 19:05:46 -08:00
|
|
|
use Drupal\menu_link_content\Entity\MenuLinkContent;
|
|
|
|
|
use Drupal\path_alias\Entity\PathAlias;
|
2026-05-12 16:28:47 -08:00
|
|
|
use Drupal\user\Entity\Role;
|
|
|
|
|
use Drupal\field\Entity\FieldStorageConfig;
|
|
|
|
|
use Drupal\field\Entity\FieldConfig;
|
2026-05-01 04:24:10 -08:00
|
|
|
|
|
|
|
|
function riverside_pt_install() {
|
2026-05-14 19:39:30 -08:00
|
|
|
// Pass 1: types, roles, and field storages (no inter-dependencies).
|
|
|
|
|
NodeType::create([
|
|
|
|
|
'type' => 'appointment',
|
|
|
|
|
'name' => 'Appointment',
|
|
|
|
|
'description' => 'A booking between a Patient and a Provider at a particular time.',
|
|
|
|
|
'new_revision' => FALSE,
|
|
|
|
|
'display_submitted' => FALSE,
|
|
|
|
|
])->save();
|
|
|
|
|
|
|
|
|
|
NodeType::create([
|
|
|
|
|
'type' => 'provider_availability',
|
|
|
|
|
'name' => 'Provider Availability',
|
|
|
|
|
'description' => 'A window of time during which a Provider is available for appointments.',
|
|
|
|
|
'new_revision' => FALSE,
|
|
|
|
|
'display_submitted' => FALSE,
|
|
|
|
|
])->save();
|
|
|
|
|
|
|
|
|
|
Role::create(['id' => 'provider', 'label' => 'Provider'])->save();
|
|
|
|
|
|
|
|
|
|
FieldStorageConfig::create([
|
|
|
|
|
'field_name' => 'field_appointment_date',
|
|
|
|
|
'entity_type' => 'node',
|
|
|
|
|
'type' => 'datetime',
|
|
|
|
|
'settings' => ['datetime_type' => 'datetime'],
|
|
|
|
|
])->save();
|
|
|
|
|
|
|
|
|
|
FieldStorageConfig::create([
|
|
|
|
|
'field_name' => 'field_duration_minutes',
|
|
|
|
|
'entity_type' => 'node',
|
|
|
|
|
'type' => 'integer',
|
|
|
|
|
])->save();
|
|
|
|
|
|
|
|
|
|
FieldStorageConfig::create([
|
|
|
|
|
'field_name' => 'field_service_type',
|
|
|
|
|
'entity_type' => 'node',
|
|
|
|
|
'type' => 'list_string',
|
|
|
|
|
'settings' => [
|
|
|
|
|
'allowed_values' => [
|
|
|
|
|
'diagnostic' => 'Diagnostic',
|
|
|
|
|
'sports_rehab' => 'Sports Rehab',
|
|
|
|
|
'pre_post_surgical_rehab' => 'Pre/Post-Surgical Rehab',
|
|
|
|
|
'neurological_pt' => 'Neurological PT',
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
])->save();
|
|
|
|
|
|
|
|
|
|
FieldStorageConfig::create([
|
|
|
|
|
'field_name' => 'field_provider',
|
|
|
|
|
'entity_type' => 'node',
|
|
|
|
|
'type' => 'entity_reference',
|
|
|
|
|
'settings' => ['target_type' => 'user'],
|
|
|
|
|
])->save();
|
|
|
|
|
|
|
|
|
|
FieldStorageConfig::create([
|
|
|
|
|
'field_name' => 'field_start_datetime',
|
|
|
|
|
'entity_type' => 'node',
|
|
|
|
|
'type' => 'datetime',
|
|
|
|
|
'settings' => ['datetime_type' => 'datetime'],
|
|
|
|
|
])->save();
|
|
|
|
|
|
|
|
|
|
FieldStorageConfig::create([
|
|
|
|
|
'field_name' => 'field_end_datetime',
|
|
|
|
|
'entity_type' => 'node',
|
|
|
|
|
'type' => 'datetime',
|
|
|
|
|
'settings' => ['datetime_type' => 'datetime'],
|
|
|
|
|
])->save();
|
|
|
|
|
|
|
|
|
|
// Clear field definition cache so FieldConfig::preSave() can find the storages.
|
|
|
|
|
\Drupal::service('entity_field.manager')->clearCachedFieldDefinitions();
|
|
|
|
|
|
|
|
|
|
// Pass 2: field configs (depend on storages being in the DB).
|
|
|
|
|
FieldConfig::create([
|
|
|
|
|
'field_name' => 'field_appointment_date',
|
|
|
|
|
'entity_type' => 'node',
|
|
|
|
|
'bundle' => 'appointment',
|
|
|
|
|
'label' => 'Appointment Date',
|
|
|
|
|
'required' => TRUE,
|
|
|
|
|
])->save();
|
|
|
|
|
|
|
|
|
|
FieldConfig::create([
|
|
|
|
|
'field_name' => 'field_duration_minutes',
|
|
|
|
|
'entity_type' => 'node',
|
|
|
|
|
'bundle' => 'appointment',
|
|
|
|
|
'label' => 'Duration (Minutes)',
|
|
|
|
|
'required' => TRUE,
|
|
|
|
|
])->save();
|
|
|
|
|
|
|
|
|
|
FieldConfig::create([
|
|
|
|
|
'field_name' => 'field_service_type',
|
|
|
|
|
'entity_type' => 'node',
|
|
|
|
|
'bundle' => 'appointment',
|
|
|
|
|
'label' => 'Service Type',
|
|
|
|
|
'required' => TRUE,
|
|
|
|
|
])->save();
|
|
|
|
|
|
|
|
|
|
FieldConfig::create([
|
|
|
|
|
'field_name' => 'field_provider',
|
|
|
|
|
'entity_type' => 'node',
|
|
|
|
|
'bundle' => 'appointment',
|
|
|
|
|
'label' => 'Provider',
|
|
|
|
|
'required' => TRUE,
|
|
|
|
|
'settings' => [
|
|
|
|
|
'handler' => 'default:user',
|
|
|
|
|
'handler_settings' => [
|
|
|
|
|
'filter' => ['type' => '_role', 'role' => ['provider' => 'provider']],
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
])->save();
|
|
|
|
|
|
|
|
|
|
FieldConfig::create([
|
|
|
|
|
'field_name' => 'field_provider',
|
|
|
|
|
'entity_type' => 'node',
|
|
|
|
|
'bundle' => 'provider_availability',
|
|
|
|
|
'label' => 'Provider',
|
|
|
|
|
'required' => TRUE,
|
|
|
|
|
'settings' => [
|
|
|
|
|
'handler' => 'default:user',
|
|
|
|
|
'handler_settings' => [
|
|
|
|
|
'filter' => ['type' => '_role', 'role' => ['provider' => 'provider']],
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
])->save();
|
|
|
|
|
|
|
|
|
|
FieldConfig::create([
|
|
|
|
|
'field_name' => 'field_start_datetime',
|
|
|
|
|
'entity_type' => 'node',
|
|
|
|
|
'bundle' => 'provider_availability',
|
|
|
|
|
'label' => 'Start',
|
|
|
|
|
'required' => TRUE,
|
|
|
|
|
])->save();
|
|
|
|
|
|
|
|
|
|
FieldConfig::create([
|
|
|
|
|
'field_name' => 'field_end_datetime',
|
|
|
|
|
'entity_type' => 'node',
|
|
|
|
|
'bundle' => 'provider_availability',
|
|
|
|
|
'label' => 'End',
|
|
|
|
|
'required' => TRUE,
|
|
|
|
|
])->save();
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
_riverside_pt_build_navigation();
|
|
|
|
|
}
|
|
|
|
|
catch (\Exception $e) {
|
|
|
|
|
\Drupal::logger('riverside_pt')->error('Navigation setup failed: @msg', ['@msg' => $e->getMessage()]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
\Drupal::configFactory()->getEditable('system.site')
|
|
|
|
|
->set('page.front', '/home')
|
|
|
|
|
->save();
|
2026-05-14 19:05:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function _riverside_pt_build_navigation(): void {
|
|
|
|
|
$em = \Drupal::entityTypeManager();
|
|
|
|
|
|
|
|
|
|
foreach ($em->getStorage('menu_link_content')->loadByProperties(['menu_name' => 'main']) as $link) {
|
|
|
|
|
$link->delete();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (['Services', 'About', 'FAQ', 'Contact'] as $title) {
|
2026-05-14 19:39:30 -08:00
|
|
|
if ($em->getStorage('node')->loadByProperties(['title' => $title, 'type' => 'page'])) {
|
2026-05-14 19:05:46 -08:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
$node = Node::create(['type' => 'page', 'title' => $title, 'status' => 1]);
|
|
|
|
|
$node->save();
|
|
|
|
|
PathAlias::create([
|
|
|
|
|
'path' => '/node/' . $node->id(),
|
|
|
|
|
'alias' => '/' . strtolower($title),
|
|
|
|
|
'langcode' => 'en',
|
|
|
|
|
])->save();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$defs = [
|
|
|
|
|
['title' => 'Home', 'uri' => 'route:<front>', 'weight' => 0, 'class' => NULL],
|
|
|
|
|
['title' => 'Services', 'uri' => 'internal:/services', 'weight' => 1, 'class' => NULL],
|
|
|
|
|
['title' => 'About', 'uri' => 'internal:/about', 'weight' => 2, 'class' => NULL],
|
|
|
|
|
['title' => 'FAQ', 'uri' => 'internal:/faq', 'weight' => 3, 'class' => NULL],
|
|
|
|
|
['title' => 'Contact', 'uri' => 'internal:/contact', 'weight' => 4, 'class' => 'nav-cta'],
|
|
|
|
|
['title' => 'Book An Appointment', 'uri' => 'internal:/schedule', 'weight' => 5, 'class' => 'nav-cta nav-cta--primary'],
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
foreach ($defs as $def) {
|
|
|
|
|
$options = $def['class'] ? ['attributes' => ['class' => explode(' ', $def['class'])]] : [];
|
|
|
|
|
MenuLinkContent::create([
|
|
|
|
|
'title' => $def['title'],
|
|
|
|
|
'link' => ['uri' => $def['uri'], 'options' => $options],
|
|
|
|
|
'menu_name' => 'main',
|
|
|
|
|
'weight' => $def['weight'],
|
|
|
|
|
'enabled' => TRUE,
|
|
|
|
|
])->save();
|
|
|
|
|
}
|
2026-05-12 16:28:47 -08:00
|
|
|
}
|