Plugin Page

VetCarePress – Veterinary Client Portal

View Plugin

Developer Reference

VetCarePress is built with modern PHP practices and provides multiple extension points for developers who need to customize or integrate with the plugin.

Architecture Overview

  • PHP Version: 8.1+ required, with strict types enabled throughout.
  • Autoloading: PSR-4 autoloading via Composer. The VetCarePress namespace maps to the includes/ directory.
  • Plugin Instance: Singleton pattern via VetCarePressPlugin::instance().
  • Dependency Injection: Lightweight DI container accessible via Plugin::instance()->container()->make(ClassName::class).

Admin UI

Gutenberg is disabled for all VetCarePress custom post types. The admin interface uses a metabox-based UI with custom meta fields. This ensures a consistent editing experience regardless of the active theme or editor preferences.

Template System

Frontend templates can be overridden by copying them from the plugin directory into your active theme:

  • Plugin path: vetcarepress/templates/frontend/
  • Theme override path: your-theme/vetcarepress/

The plugin checks for a theme override first. If none is found, the bundled template is used.

See the Template Reference for the full list of overridable templates.

Extensibility Points

Settings System

  • vcp_settings_tabs filter — Add or modify settings tabs in the plugin settings page.
  • vcp_settings_fields_{tab} action — Inject custom fields into a specific settings tab.
  • vcp_settings_saved action — React to settings being saved.

Hooks and Filters

VetCarePress provides action hooks and filters for customizing permission checks, post-save logic, metabox rendering, and more.

See Hooks & Filters for the complete reference.

Data Storage

VetCarePress uses a combination of custom database tables (for customers, sessions, messages, and tokens) and WordPress custom post types (for patients, medical records, vaccinations, and lab data).

Key Developer Resources

ResourceDescription
Hooks & FiltersAction hooks and filters for extending the plugin
Template ReferenceOverridable frontend templates
Database TablesCustom table schemas
Custom Post TypesCPT definitions and meta fields
Roles & CapabilitiesPermission system reference

Hooks & Filters

VetCarePress provides action hooks and filters that allow developers to extend and customize plugin behavior without modifying core files. This reference covers all public extension points.

Filters

vcp_settings_tabs

Modify the array of settings tabs displayed on the VetCarePress settings page.

  • Receives: array<string, string> — associative array of slug => label.
  • Returns: Modified array.

Usage: Add a custom settings tab.

add_filter('vcp_settings_tabs', function (array $tabs): array {
    $tabs['my_custom_tab'] = 'My Custom Tab';
    return $tabs;
});

vcp_patient_query_args

Modify the WP_Query arguments used when listing patients via the REST API.

  • Receives: array $args — the query arguments array.
  • Returns: Modified array.

Usage: Add custom ordering, meta queries, or tax queries to the patient list endpoint.

add_filter('vcp_patient_query_args', function (array $args): array {
    $args['meta_key'] = '_vcp_birthdate';
    $args['orderby'] = 'meta_value';
    return $args;
});

vcp_patient_rest_response

Modify the formatted patient data returned by the REST API.

  • Receives: array $data — the formatted patient response array.
  • Returns: Modified array.

vcp_medical_record_rest_response

Modify the formatted medical record data returned by the REST API.

  • Receives: array $data — the formatted record response array.
  • Returns: Modified array.

vcp_medical_record_types

Add or modify the available medical record types.

  • Receives: array $types — associative array of slug => label.
  • Returns: Modified array.

Usage: Register a custom record type.

add_filter('vcp_medical_record_types', function (array $types): array {
    $types['cytology'] = 'Cytology';
    return $types;
});

vcp_lab_cpt_pairs

Register additional lab CPT pairs (panel + marker CPT combinations) for custom lab types.

  • Receives: array $pairs — array of registered CPT pairs.
  • Returns: Modified array.

Usage: Add a custom lab panel type (e.g., cytology panels with their own CPT).

vcp_rest_permission_staff

Override the staff permission check for REST API endpoints.

  • Receives: bool — current permission result.
  • Returns: booltrue to allow, false to deny.

Usage: Grant access to a custom role or external authentication system.

add_filter('vcp_rest_permission_staff', function (bool $allowed): bool {
    if (current_user_can('my_custom_capability')) {
        return true;
    }
    return $allowed;
});

vcp_rest_permission_public

Override the public permission check for REST API endpoints.

  • Receives: bool — current permission result.
  • Returns: booltrue to allow, false to deny.

Usage: Restrict otherwise-public endpoints (e.g., require a nonce or IP whitelist).

Actions

vcp_patient_created

Fired after a patient is successfully created via the REST API.

  • Parameter: int $post_id — the new patient post ID.

vcp_patient_updated

Fired after a patient is successfully updated via the REST API.

  • Parameter: int $post_id — the updated patient post ID.

vcp_medical_record_created

Fired after a medical record is successfully created via the REST API.

  • Parameter: int $post_id — the new record post ID.

vcp_medical_record_updated

Fired after a medical record is successfully updated via the REST API.

  • Parameter: int $post_id — the updated record post ID.

vcp_medical_record_deleted

Fired after a medical record is successfully deleted via the REST API.

  • Parameter: int $post_id — the deleted record post ID.

vcp_settings_saved

Fired when a settings group is saved.

  • Parameter 1: string $group — the option group name being saved.
  • Parameter 2: array $post_data — the raw form data submitted.

Usage: React to settings changes, such as clearing a cache or syncing with an external service.

add_action('vcp_settings_saved', function (string $group, array $post_data): void {
    if ($group === 'vcp_sms_settings') {
        // Re-validate SMS credentials
    }
}, 10, 2);

vcp_settings_fields_{tab}

Fired within each settings tab template during rendering. Replace {tab} with the tab slug.

  • Parameter: string $group_key — the option group key for the current tab.

Usage: Add custom fields to an existing or custom settings tab.

add_action('vcp_settings_fields_my_custom_tab', function (string $group_key): void {
    echo '<tr>';
    echo '<th><label for="my_field">My Field</label></th>';
    echo '<td><input type="text" id="my_field" name="my_field" /></td>';
    echo '</tr>';
});

vcp_metabox_saved

Fired after a metabox saves its fields on a custom post type edit screen.

  • Usage: Add custom post-save logic, such as updating related records or triggering notifications.

vcp_metabox_fields_after

Fired at the end of metabox field rendering.

  • Usage: Append custom fields to an existing metabox without overriding its template.

vcp_cleanup_expired

Daily cron action that handles cleanup of expired data.

  • Default behavior: Removes expired OTP tokens, expired customer sessions, and other stale data.
  • Usage: Hook into this action to add your own daily cleanup tasks.
add_action('vcp_cleanup_expired', function (): void {
    // Custom daily cleanup logic
});

WordPress Hooks Used by VetCarePress

VetCarePress hooks into the following standard WordPress actions during its lifecycle:

HookPurpose
plugins_loadedPlugin boot, version check, upgrade routines
initRegister custom post types, taxonomies, rewrite rules
rest_api_initRegister all REST API routes
admin_menuRegister admin pages and menu items
admin_initRegister settings, handle admin form submissions

Best Practices

  • Always check that VetCarePress is active before referencing its hooks. Use class_exists('VetCarePressPlugin') or check defined('VCP_VERSION').
  • Place custom hook code in a separate plugin or in your theme’s functions.php to ensure it persists across VetCarePress updates.
  • Use appropriate priority values (default is 10) to control execution order when multiple callbacks are attached to the same hook.

See also: Developer Reference, Roles & Capabilities

Template Reference

VetCarePress uses a template system that allows theme developers to override any frontend template without modifying plugin files.

Template Override System

  • Plugin templates: Located in vetcarepress/templates/frontend/.
  • Theme overrides: Copy any template to your-theme/vetcarepress/ and modify it.
  • Priority: The plugin checks for a theme override first. If no override exists, the bundled plugin template is used.

Template List

Page Templates

Template FilePurpose
customer-login.phpOTP/PIN login form for customers
staff-login.phpStaff login form
customer-dashboard.phpCustomer dashboard layout
customer-view.phpCustomer view of a single patient
staff-dashboard.phpStaff dashboard layout

Patient View Templates

Template FilePurpose
patient-view.phpPatient profile (router — selects layout variant)
patient-view--tabs.phpTabs layout variant
patient-view--sidebar.phpSidebar layout variant
patient-view--card.phpCard layout variant

Record Templates

Template FilePurpose
medical-record-view.phpSingle medical record detail view

Partial Templates

Partials are included by the main templates and handle specific sections of the UI.

Template FilePurpose
partials/patient-header.phpPatient info header/sidebar
partials/patient-tab-overview.phpOverview tab content
partials/patient-tab-clinical-notes.phpClinical notes tab
partials/patient-tab-diagnoses.phpDiagnoses tab
partials/patient-tab-laboratory.phpLab results tab
partials/patient-tab-imaging.phpImaging tab
partials/patient-tab-treatments.phpTreatments tab
partials/patient-tab-vaccinations.phpVaccinations tab
partials/patient-tab-messages.phpMessages tab
partials/patient-weight-graph.phpWeight chart and measurement table
partials/patient-temperature-history.phpTemperature history display
partials/patient-pagination.phpPagination controls
partials/customer-messages.phpCustomer-facing message view
partials/staff-customer-messages.phpStaff-facing message thread
partials/bloodwork-marker-table.phpLab marker results table
partials/medical-record-clinical-note.phpClinical note record rendering
partials/medical-record-diagnose.phpDiagnose record rendering
partials/medical-record-imaging.phpImaging record rendering
partials/medical-record-lab-result.phpLab result record rendering
partials/medical-record-treatment.phpTreatment record rendering
partials/medical-record-vaccination.phpVaccination record rendering

Override Example

To override the customer login template:

  1. Create a vetcarepress directory inside your active theme folder.
  2. Copy wp-content/plugins/vetcarepress/templates/frontend/customer-login.php to wp-content/themes/your-theme/vetcarepress/customer-login.php.
  3. Edit the copied file as needed.

For partial templates, maintain the subdirectory structure:

wp-content/themes/your-theme/vetcarepress/partials/patient-header.php

Guidelines for Template Overrides

  • Maintain variable names: Templates receive specific variables from the plugin. Do not rename or remove expected variables, as this will cause errors.
  • Preserve structure: Keep the same general HTML structure to ensure JavaScript interactions continue to work. VetCarePress frontend JS binds to specific CSS classes and data attributes.
  • Check for updates: After updating VetCarePress, review the changelog for template changes. Compare your overridden templates against the new plugin versions to incorporate any structural updates or new variables.
  • Partial independence: You can override individual partials without overriding the parent template. For example, override only partials/patient-tab-overview.php to customize the overview tab while keeping all other tabs at their defaults.

See also: Developer Reference, Custom Post Types

Database Tables

VetCarePress creates 7 custom database tables to store customer data, authentication tokens, sessions, notifications, share links, and messages. All tables use the standard WordPress table prefix (e.g., wp_).

Tables are created on plugin activation using dbDelta() for safe creation and upgrades. Schema upgrades are applied automatically on plugins_loaded when the plugin version changes.

wp_vcp_customers

Stores customer (pet owner) records. Customers do not require WordPress user accounts.

ColumnTypeDescription
idBIGINT UNSIGNED AUTO_INCREMENTPrimary key
first_nameVARCHAR(100)First name
last_nameVARCHAR(100)Last name
phoneVARCHAR(30)Phone number
phone_country_prefixVARCHAR(10)Country code (e.g., +1, +44)
emailVARCHAR(200)Email address
address_line1VARCHAR(255)Address line 1
address_line2VARCHAR(255)Address line 2
cityVARCHAR(100)City
stateVARCHAR(100)State/Province
postal_codeVARCHAR(20)Postal code
countryVARCHAR(100)Country
pinVARCHAR(255)Hashed PIN for quick login
notesTEXTAdmin notes
created_atDATETIMECreation timestamp
updated_atDATETIMELast update (auto-updated)

Indexes: phone, email, (last_name, first_name)

wp_vcp_otp_tokens

Stores one-time password tokens for customer authentication.

ColumnTypeDescription
idBIGINT UNSIGNEDPrimary key
customer_idBIGINT UNSIGNEDFK to customers
codeVARCHAR(64)OTP code
channelENUM(‘sms’,’email’)Delivery channel
destinationVARCHAR(200)Email address or phone number
expires_atDATETIMECode expiry time
used_atDATETIMEWhen used (NULL if unused)
created_atDATETIMECreation timestamp

Indexes: customer_id, (destination, code, expires_at)

wp_vcp_customer_sessions

Tracks active customer sessions created after successful OTP or PIN verification.

ColumnTypeDescription
idBIGINT UNSIGNEDPrimary key
customer_idBIGINT UNSIGNEDFK to customers
tokenVARCHAR(128)Session token (UNIQUE)
ip_addressVARCHAR(45)Client IP address
user_agentVARCHAR(500)Browser user agent string
expires_atDATETIMESession expiry time
created_atDATETIMECreation timestamp

Indexes: token (UNIQUE), customer_id, expires_at

wp_vcp_notification_log

Records all outbound notifications (email and SMS) with delivery status and provider details.

ColumnTypeDescription
idBIGINT UNSIGNEDPrimary key
customer_idBIGINT UNSIGNEDFK to customers (nullable)
channelENUM(‘sms’,’email’)Delivery channel
destinationVARCHAR(200)Recipient address or number
messageTEXTMessage content
statusENUM(‘sent’,’failed’)Delivery status
error_messageTEXTError details (nullable)
provider_responseTEXTRaw provider response (nullable)
created_atDATETIMESend timestamp

Indexes: customer_id, (channel, status), created_at

wp_vcp_share_tokens

Stores share links for patient profiles, allowing external access without authentication.

ColumnTypeDescription
idBIGINT UNSIGNEDPrimary key
patient_idBIGINT UNSIGNEDFK to patient post
tokenVARCHAR(64)Share token (UNIQUE)
expires_atDATETIMEExpiry time (nullable = never expires)
revoked_atDATETIMERevocation time (nullable)
created_byBIGINT UNSIGNEDWordPress user ID of creator
created_atDATETIMECreation timestamp

Indexes: token (UNIQUE), patient_id

wp_vcp_record_share_tokens

Stores share links for individual medical records. Same structure as wp_vcp_share_tokens but references a record instead of a patient.

ColumnTypeDescription
idBIGINT UNSIGNEDPrimary key
record_idBIGINT UNSIGNEDFK to medical record post
tokenVARCHAR(64)Share token (UNIQUE)
expires_atDATETIMEExpiry time (nullable = never expires)
revoked_atDATETIMERevocation time (nullable)
created_byBIGINT UNSIGNEDWordPress user ID of creator
created_atDATETIMECreation timestamp

Indexes: token (UNIQUE), record_id

wp_vcp_messages

Stores messages exchanged between staff and customers, optionally associated with a patient.

ColumnTypeDescription
idBIGINT UNSIGNEDPrimary key
customer_idBIGINT UNSIGNEDFK to customers
patient_idBIGINT UNSIGNEDFK to patient post (nullable)
sender_typeENUM(‘staff’,’customer’)Who sent the message
sender_idBIGINT UNSIGNEDWordPress user ID or customer ID
messageTEXTMessage content
is_readTINYINT(1)Read flag (0 = unread, 1 = read)
read_atDATETIMEWhen read (nullable)
channelENUM(‘web’,’email’,’sms’)Origin channel
external_refVARCHAR(255)External reference ID (nullable)
created_atDATETIMESend timestamp

Indexes: customer_id, patient_id, (customer_id, sender_type, is_read), created_at


See also: Developer Reference, Custom Post Types

Custom Post Types

VetCarePress registers 9 custom post types for managing patients, medical records, vaccinations, and laboratory data. All CPTs are registered during the init action.

CPT SlugLabelPublicGutenbergPurpose
vcp_patientPatientsYes (virtual URLs)NoPet profiles
vcp_medical_recordMedical RecordsNoNoClinical records (5 types)
vcp_vaccinationVaccinationsNoNoVaccination records
vcp_lab_panelBlood PanelsNoNoBloodwork panel definitions
vcp_lab_markerBlood MarkersNoNoBloodwork marker definitions
vcp_urine_panelUrine PanelsNoNoUrine panel definitions
vcp_urine_markerUrine MarkersNoNoUrine marker definitions
vcp_stool_panelStool PanelsNoNoStool panel definitions
vcp_stool_markerStool MarkersNoNoStool marker definitions

All CPTs use 'show_in_rest' => false for the default WordPress REST API. VetCarePress provides its own REST controllers for data access. Gutenberg is disabled for all VCP post types via the use_block_editor_for_post_type filter.

Detailed Reference

vcp_patient

Pet profiles linked to customer records.

  • Supports: title, thumbnail
  • Public: Yes — accessible via virtual URLs (configurable slug in Settings > Advanced)
  • Taxonomies: vcp_species
  • Custom capabilities: Uses VCP capability mapping (vcp_manage_patients)
  • Auto-generated title: Composed from pet name and species
  • Key meta fields:
    • _vcp_owner_id — FK to customer record
    • _vcp_birthdate — Date of birth
    • _vcp_sex — Sex (male, female, neutered male, spayed female)
    • _vcp_color — Coat/color description
    • _vcp_microchip — Microchip number
    • _vcp_photo_id — Attachment ID for patient photo
    • _vcp_notes — Internal notes
    • _vcp_deceased — Boolean flag indicating the patient is deceased
    • _vcp_deceased_date — Date of death

vcp_medical_record

Clinical records attached to a patient. Supports 5 record types: clinical notes, diagnoses, medical imaging, treatments, and lab results.

  • Supports: title, editor
  • Public: No
  • Taxonomies: None
  • Custom capabilities: Uses VCP capability mapping (varies by record type)
  • Auto-generated title: Composed from record type, patient name, and date
  • Key meta fields:
    • _vcp_patient_id — FK to patient post
    • _vcp_record_type — Type: clinical-note, diagnose, lab-result, medical-imaging, treatment
    • _vcp_record_date — Date of the record
    • _vcp_description — Record description/content
    • _vcp_staff_id — WordPress user ID of the creating staff member
    • _vcp_clinical_note_attachment — Attachment IDs for clinical note records
    • _vcp_diagnosis_attachment — Attachment IDs for diagnose records
    • _vcp_lab_attachment — Attachment IDs for lab result records
    • _vcp_imaging_attachment — Attachment IDs for imaging records
    • _vcp_imaging_dicom — DICOM file attachment IDs (imaging records only)
    • _vcp_treatment_attachment — Attachment IDs for treatment records

vcp_vaccination

Vaccination records linked to a patient with reminder scheduling.

  • Supports: title
  • Public: No
  • Taxonomies: vcp_vaccination_type, vcp_vaccine_product, vcp_vaccine_manufacturer
  • Custom capabilities: Uses VCP capability mapping (vcp_manage_patients)
  • Auto-generated title: Composed from vaccine name and patient name
  • Key meta fields:
    • _vcp_patient_id — FK to patient post
    • _vcp_vaccine_name — Name of the vaccine
    • _vcp_vaccination_date — Date administered
    • _vcp_next_due_date — Next vaccination due date
    • _vcp_batch_number — Vaccine batch/lot number
    • _vcp_administered_by — Staff member who administered
    • _vcp_notes — Additional notes

vcp_lab_panel

Defines groupings of blood markers (e.g., "Complete Blood Count", "Liver Panel").

  • Supports: title
  • Public: No
  • Taxonomies: vcp_species (panels are species-specific)
  • Custom capabilities: Uses VCP capability mapping (vcp_manage_laboratory)
  • Key meta fields:
    • _vcp_panel_order — Display order

vcp_lab_marker

Individual blood marker definitions within a panel (e.g., "WBC", "RBC", "ALT").

  • Supports: title
  • Public: No
  • Taxonomies: None
  • Custom capabilities: Uses VCP capability mapping (vcp_manage_laboratory)
  • Key meta fields:
    • _vcp_panel_id — FK to lab panel post
    • _vcp_unit — Unit of measurement
    • _vcp_min_value — Reference range minimum
    • _vcp_max_value — Reference range maximum
    • _vcp_marker_order — Display order within panel

vcp_urine_panel

Defines groupings of urine test markers. Structure mirrors vcp_lab_panel.

  • Supports: title
  • Public: No
  • Taxonomies: vcp_species
  • Custom capabilities: Uses VCP capability mapping (vcp_manage_laboratory)
  • Key meta fields:
    • _vcp_panel_order — Display order

vcp_urine_marker

Individual urine marker definitions. Structure mirrors vcp_lab_marker.

  • Supports: title
  • Public: No
  • Taxonomies: None
  • Custom capabilities: Uses VCP capability mapping (vcp_manage_laboratory)
  • Key meta fields:
    • _vcp_panel_id — FK to urine panel post
    • _vcp_unit — Unit of measurement
    • _vcp_min_value — Reference range minimum
    • _vcp_max_value — Reference range maximum
    • _vcp_marker_order — Display order within panel

vcp_stool_panel

Defines groupings of stool test markers. Structure mirrors vcp_lab_panel.

  • Supports: title
  • Public: No
  • Taxonomies: vcp_species
  • Custom capabilities: Uses VCP capability mapping (vcp_manage_laboratory)
  • Key meta fields:
    • _vcp_panel_order — Display order

vcp_stool_marker

Individual stool marker definitions. Structure mirrors vcp_lab_marker.

  • Supports: title
  • Public: No
  • Taxonomies: None
  • Custom capabilities: Uses VCP capability mapping (vcp_manage_laboratory)
  • Key meta fields:
    • _vcp_panel_id — FK to stool panel post
    • _vcp_unit — Unit of measurement
    • _vcp_min_value — Reference range minimum
    • _vcp_max_value — Reference range maximum
    • _vcp_marker_order — Display order within panel

Metabox Classes

Each CPT has an associated metabox class that handles the admin editing UI. Metabox classes:

  • Render form fields on the post edit screen
  • Save meta data on save_post
  • Fire vcp_metabox_saved after saving
  • Fire vcp_metabox_fields_after at the end of field rendering

See also: Developer Reference, Database Tables, Hooks & Filters