customer-riverside/web/modules/custom/riverside_pt/riverside_pt.module
Philip Peterson 797e580cc0 Create custom /contact page with details and appointment CTAs
- Refactor AboutController to PageController to handle multiple static pages:
  - /about
  - /services/{slug} (diagnostic, sports, pre-post, neuro)
  - /contact (new)

- New template riverside-pt-contact.html.twig:
  - Contact details (address, phone, email)
  - Office hours
  - 'Send us a message' section directing to booking tool
  - Multiple 'Make an Appointment' links back to /home#book-an-appointment

- Updated riverside_pt.routing.yml with riverside_pt.contact route
- Registered 'riverside_pt_contact' theme in riverside_pt.module
- Updated riverside_pt.install to skip legacy node creation for 'Contact' (and previously About/Services) to avoid alias conflicts
- Minor updates to home template, header handling, libraries (scroll support), and other controllers for consistency with page flows and email/booking features

All details pages (/about, /services/*, /contact) now include clear links back to 'Make an Appointment'.
2026-06-03 23:55:02 -07:00

154 lines
4.6 KiB
Text
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
use Drupal\Core\Breadcrumb\Breadcrumb;
use Drupal\Core\Link;
use Drupal\Core\Routing\RouteMatchInterface;
function riverside_pt_page_attachments(array &$attachments): void {
$route = \Drupal::routeMatch()->getRouteName() ?? '';
if (!str_starts_with($route, 'riverside_pt.')) {
return;
}
$attachments['#attached']['library'][] = 'riverside_pt/app';
}
function riverside_pt_theme(): array {
return [
'riverside_pt_header' => [
'variables' => [
'site_name' => NULL,
'home_url' => NULL,
'menu_items' => [],
'current_path' => NULL,
],
],
'riverside_pt_home' => [
'variables' => [],
],
'riverside_pt_about' => [
'variables' => [],
],
'riverside_pt_service' => [
'variables' => [
'slug' => NULL,
'title' => NULL,
'description' => NULL,
'long_description' => NULL,
'what_to_expect' => NULL,
'benefits' => [],
],
],
'riverside_pt_contact' => [
'variables' => [],
],
];
}
function riverside_pt_page_top(array &$page_top): void {
$route = \Drupal::routeMatch()->getRouteName() ?? '';
if (!str_starts_with($route, 'riverside_pt.')) {
return;
}
$page_top['rpt_header'] = [
'#theme' => 'riverside_pt_header',
'#cache' => ['contexts' => ['url.path', 'route']],
];
}
function riverside_pt_preprocess_riverside_pt_header(array &$variables): void {
$variables['site_name'] = \Drupal::config('system.site')->get('name');
$variables['home_url'] = \Drupal\Core\Url::fromRoute('<front>')->toString();
$tree_service = \Drupal::service('menu.link_tree');
$params = new \Drupal\Core\Menu\MenuTreeParameters();
$params->setMaxDepth(1);
$tree = $tree_service->load('main', $params);
$tree = $tree_service->transform($tree, [
['callable' => 'menu.default_tree_manipulators:checkAccess'],
['callable' => 'menu.default_tree_manipulators:generateIndexAndSort'],
]);
$seen = [];
$items = [];
foreach ($tree as $element) {
if (!$element->access->isAllowed()) {
continue;
}
$url = $element->link->getUrlObject()->toString();
if (in_array($url, $seen, TRUE)) {
continue;
}
$seen[] = $url;
$title = (string) $element->link->getTitle();
$items[] = [
'title' => $title,
'url' => $url,
'is_cta' => ($title === 'Book An Appointment' || $title === 'Contact'),
];
}
$variables['menu_items'] = $items;
$variables['current_path'] = \Drupal::request()->getPathInfo();
}
function riverside_pt_mail(string $key, array &$message, array $params): void {
$service_map = [
'diagnostic' => 'Diagnostic Assessment',
'sports' => 'Sports Rehabilitation',
'surgical' => 'Surgery Rehabilitation',
'neuro' => 'Neurological Therapy',
];
$service_label = $service_map[$params['service'] ?? ''] ?? 'Appointment';
if ($key === 'booking_request') {
$start = new \DateTime($params['start']);
$end = new \DateTime($params['end']);
$message['subject'] = 'Booking request — ' . $start->format('M j, Y g:i A');
$lines = [
'Name: ' . ($params['first_name'] ?? '') . ' ' . ($params['last_name'] ?? ''),
'Email: ' . ($params['email'] ?? ''),
'Service: ' . $service_label,
'Phone: ' . ($params['phone'] ?? ''),
'Slot: ' . $start->format('l, F j, Y') . ', ' . $start->format('g:i A') . '' . $end->format('g:i A'),
];
if (!empty($params['comments'])) {
$lines[] = 'Comments: ' . $params['comments'];
}
$message['body'][] = implode("\n", $lines);
return;
}
if ($key === 'booking_confirmation') {
$start = new \DateTime($params['start']);
$end = new \DateTime($params['end']);
$first = $params['first_name'] ?? 'Patient';
$message['subject'] = 'Your appointment is confirmed — ' . $start->format('M j, Y g:i A');
$lines = [
'Dear ' . $first . ',',
'',
'Your appointment is *confirmed* for:',
$start->format('l, F j, Y') . ', ' . $start->format('g:i A') . '' . $end->format('g:i A') . ' PST',
'',
'Service: ' . $service_label,
];
$full_name = trim(($params['first_name'] ?? '') . ' ' . ($params['last_name'] ?? ''));
if ($full_name) {
$lines[] = 'Name: ' . $full_name;
}
if (!empty($params['phone'])) {
$lines[] = 'Phone: ' . $params['phone'];
}
$lines[] = '';
$lines[] = 'We look forward to seeing you at Riverside Physical Therapy.';
$lines[] = 'If you need to cancel or reschedule, please contact us as soon as possible.';
$message['body'][] = implode("\n", $lines);
return;
}
}