'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(); } 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) { if ($em->getStorage('node')->loadByProperties(['title' => $title, 'type' => 'page'])) { 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:', '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 nav-cta--primary'], ['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(); } }