Nothing to see here

Go Back"; require_once "../includes/footer.php"; exit(); } $contact_row = mysqli_fetch_assoc($sql); // raw, for the helpers - $row gets reused below $row = $contact_row; $client_id = intval($row['client_id']); $client_name = escapeHtml($row['client_name']); $contact_name = escapeHtml($row['contact_name']); $contact_title = escapeHtml($row['contact_title']); $contact_department = escapeHtml($row['contact_department']); $contact_email = escapeHtml($row['contact_email']); $contact_pin = escapeHtml($row['contact_pin']); $contact_notes = escapeHtml($row['contact_notes']); $contact_primary = intval($row['contact_primary']); $contact_archived_at = $row['contact_archived_at']; $contact_created_at = escapeHtml($row['contact_created_at']); $contact_phone_link = contactPhoneLink($row['contact_phone'], $row['contact_phone_country_code'], $row['contact_extension']); $contact_mobile_link = contactPhoneLink($row['contact_mobile'], $row['contact_mobile_country_code']); $contact_phone_copy = escapeHtml(formatPhoneNumber($row['contact_phone'], $row['contact_phone_country_code'])); $contact_mobile_copy = escapeHtml(formatPhoneNumber($row['contact_mobile'], $row['contact_mobile_country_code'])); $contact_dial = $row['contact_phone'] ? 'phone' : ($row['contact_mobile'] ? 'mobile' : ''); $contact_portal = contactPortalAccess($row['contact_user_id'], $row['user_auth_method']); $contact_portal_mfa = $contact_portal === 'Password' && trim((string) $row['user_token']) !== ''; $contact_portal_last = $contact_portal ? portalContactLastSignIn($row['contact_user_id']) : null; // How they joined, when it was by an invite or signing up (functions/portal_invite.php) $contact_portal_joined = $contact_portal ? portalContactJoined($contact_id) : null; // View as contact - read access to clients and support is checked again when it starts (functions/portal.php) $can_view_as = $config_client_portal_enable && !$row['contact_archived_at'] && lookupUserPermission('module_support') >= 1; $contact_role_line = implode(' · ', array_filter([$contact_title, $contact_department])); $can_edit = lookupUserPermission('module_client') >= 2; $can_delete = lookupUserPermission('module_client') >= 3; $can_credentials = lookupUserPermission('module_credential') >= 1; $can_credentials_edit = lookupUserPermission('module_credential') >= 2; $can_support = lookupUserPermission('module_support') >= 1; $can_support_edit = lookupUserPermission('module_support') >= 2; // Override Tab Title // No Sanitizing needed as this var will only be used in the tab title $page_title = $row['contact_name']; // Tags - functions/tags.php $contact_tags_display = tagPills('contact', $contact_id, tagsForRecord('contact', $contact_id), "contacts.php?client_id=$client_id&"); // Assets assigned to them $sql_related_assets = mysqli_query($mysqli, "SELECT asset_id, asset_name, asset_description, asset_type, asset_make, asset_model, asset_serial, asset_status, asset_favorite, interface_ip FROM assets LEFT JOIN asset_interfaces ON interface_asset_id = asset_id AND interface_primary = 1 WHERE asset_contact_id = $contact_id AND asset_archived_at IS NULL ORDER BY asset_name ASC" ); $asset_count = mysqli_num_rows($sql_related_assets); // Credentials - only for agents who may see them $related_credentials = $can_credentials ? credentialRows("credential_contact_id = $contact_id AND credential_client_id = $client_id") : []; $credential_count = count($related_credentials); // Tickets they raised or are the contact on - open ones first $related_tickets = []; $ticket_open_count = 0; if ($can_support) { $related_tickets = ticketRows("tickets.ticket_contact_id = $contact_id"); $ticket_open_count = count(array_filter(array_column($related_tickets, 'is_open'))); } $ticket_count = count($related_tickets); // Recurring tickets $recurring_ticket_count = 0; if ($can_support) { $sql_related_recurring_tickets = mysqli_query($mysqli, "SELECT recurring_ticket_id, recurring_ticket_subject, recurring_ticket_priority, recurring_ticket_frequency, recurring_ticket_next_run, recurring_ticket_paused_at FROM recurring_tickets WHERE recurring_ticket_contact_id = $contact_id ORDER BY recurring_ticket_next_run ASC" ); $recurring_ticket_count = mysqli_num_rows($sql_related_recurring_tickets); } // Licenses they hold a seat on, with each one's seats in use and the key they were given $held_software = $can_support ? softwareHeldBy('contact', $contact_id) : []; $software_count = count($held_software); // Documents $sql_linked_documents = mysqli_query($mysqli, "SELECT documents.document_id, document_name, document_description, document_created_at, document_updated_at, user_name FROM contact_documents JOIN documents ON documents.document_id = contact_documents.document_id LEFT JOIN users ON document_created_by = user_id WHERE contact_documents.contact_id = $contact_id AND document_archived_at IS NULL ORDER BY document_name ASC" ); $document_count = mysqli_num_rows($sql_linked_documents); // Files $sql_linked_files = mysqli_query($mysqli, "SELECT files.file_id, file_name, file_description, file_ext, file_size, file_created_at FROM contact_files JOIN files ON files.file_id = contact_files.file_id WHERE contact_files.contact_id = $contact_id AND file_archived_at IS NULL ORDER BY file_name ASC" ); $file_count = mysqli_num_rows($sql_linked_files); // Services // The services they are a contact for - most important first $linked_services = servicesFor('contact', $contact_id); $service_count = count($linked_services); // Notes $sql_related_notes = mysqli_query($mysqli, "SELECT contact_note, contact_note_created_at, contact_note_id, contact_note_type, user_name FROM contact_notes LEFT JOIN users ON contact_note_created_by = user_id WHERE contact_note_contact_id = $contact_id AND contact_note_archived_at IS NULL ORDER BY contact_note_created_at DESC" ); $note_count = mysqli_num_rows($sql_related_notes); // Note type icons, read from the categories list so the seeded icons stay the single source of truth $note_type_icons = []; $sql_note_type_icons = mysqli_query($mysqli, "SELECT category_name, category_icon FROM categories WHERE category_type = 'contact_note_type'"); while ($row = mysqli_fetch_assoc($sql_note_type_icons)) { $note_type_icons[escapeHtml($row['category_name'])] = escapeHtml($row['category_icon']); } // The tabs, in the order a tech reaches for them // Its history, from the audit log $history = auditLogHistory('Contact', $contact_id); $contact_tabs = [ 'assets' => ['label' => 'Assets', 'icon' => 'fa-desktop', 'count' => $asset_count], 'credentials' => ['label' => 'Credentials', 'icon' => 'fa-key', 'count' => $credential_count], 'tickets' => ['label' => 'Tickets', 'icon' => 'fa-life-ring', 'count' => $ticket_count, 'badge' => $ticket_open_count], 'recurring' => ['label' => 'Recurring', 'icon' => 'fa-redo-alt', 'count' => $recurring_ticket_count], 'licenses' => ['label' => 'Licenses', 'icon' => 'fa-cube', 'count' => $software_count], 'documents' => ['label' => 'Documents', 'icon' => 'fa-file-alt', 'count' => $document_count], 'files' => ['label' => 'Files', 'icon' => 'fa-paperclip', 'count' => $file_count], 'services' => ['label' => 'Services', 'icon' => 'fa-stream', 'count' => $service_count], 'notes' => ['label' => 'Notes', 'icon' => 'fa-sticky-note', 'count' => $note_count], 'history' => ['label' => 'History', 'icon' => 'fa-history', 'count' => $history['count']], ]; if (!$can_credentials) { unset($contact_tabs['credentials']); } if (!$can_support) { // Assets and documentation are Support's too unset($contact_tabs['assets'], $contact_tabs['tickets'], $contact_tabs['recurring'], $contact_tabs['licenses'], $contact_tabs['documents'], $contact_tabs['files'], $contact_tabs['services']); } ?>
" target="_blank" rel="noopener" title="Open photo">

Archived

Reach

Phone
Mobile
Email
No phone or email recorded.

Details

Location
PIN
to verify them on a call
Portal
$contact_portal" . ($contact_portal_mfa ? ' and a code' : '') . "" : 'No access' ?>
' . timeAgo($contact_portal_last) . '' : 'Has not signed in yet' ?>
on
Ticket emails
And about the company's tickets:
Added

Quick notes