Havenlytics ships a large library of global helper functions — procedural PHP functions prefixed hvnly_ — that give theme and plugin developers a stable, public surface for reading property and agent data, rendering fields, resolving prices, generating avatars and wiring up the Contact Agent module. These helpers live in includes/Functions/ and are loaded early in the boot sequence, so they are available from theme templates, shortcodes, widgets and your own integrations. This Havenlytics developer guide documents the most useful helpers grouped by domain, with exact signatures, return types and runnable examples.
Note: Every helper on this page is prefixed
hvnly_and lives in the global namespace (they are procedural functions, not methods). They are the recommended, forward-compatible way to read Havenlytics data — prefer them over calling internalHvnlyNab\classes directly. If a function name is not documented here or in the source, do not rely on it.
Why use the helpers instead of internal classes
Havenlytics follows a single-source-of-truth (SSOT) architecture: a small number of internal services own each concern (price resolution, avatar resolution, agent lookup, gallery loading), and the global helpers are thin, documented facades over those services. Calling a helper such as hvnly_resolve_property_price() means you automatically benefit from the plugin’s caching, fallbacks and future refactors. Calling the underlying class directly couples your code to internals that may change between releases.
- Stability — helper signatures are treated as public API.
- Caching — most helpers cache results (static request caches and/or the object cache group
havenlytics). - Fallbacks — helpers degrade gracefully (empty arrays, sensible defaults) rather than throwing.
Agent helpers
Defined in includes/Functions/agent-functions.php. These read the Agent custom post type (hvnly_agent), resolve property↔agent relationships and expose agency (taxonomy hvnly_agent_agency) data. Under the hood agent lookups route through hvnly_agent_repository(), which returns an implementation of AgentRepositoryInterface.
| Signature | Purpose | Return |
|---|---|---|
hvnly_get_agent_post_type() | Get the Agent CPT slug. | string (hvnly_agent) |
hvnly_is_agent_post( int $post_id = 0 ) | Whether a post is an agent. | bool |
hvnly_agent_repository() | Get the agent repository service. | ?AgentRepositoryInterface |
hvnly_get_agent( int $agent_id = 0 ) | Structured data for a single agent. | array |
hvnly_is_valid_agent( int $agent_id ) | Whether an agent ID is valid/published. | bool |
hvnly_get_agents( array $args = [] ) | Query a list of agents. | array |
hvnly_get_property_agent_ids( int $property_id = 0 ) | Agent IDs linked to a property. | array |
hvnly_get_property_agents( int $property_id ) | Full agent records for a property. | array |
hvnly_get_primary_property_agent( int $property_id ) | The primary/lead agent record. | array |
hvnly_get_sidebar_property_agents( int $property_id ) | Agents shown in the single-property sidebar. | array |
hvnly_get_default_sidebar_contact() | Fallback contact when no agent is assigned. | array |
hvnly_get_agent_agency_term( int $term_id = 0 ) | Agency taxonomy term data. | array |
hvnly_get_agency_profile( int $term_id = 0 ) | Agency profile (name, logo, meta). | array |
hvnly_get_agency_properties_query( int $term_id = 0, array $args ) | Query properties for an agency. | ?WP_Query |
hvnly_get_agent_property_count( int $agent_id ) | Number of properties for an agent. | int |
hvnly_get_agent_availability_status( int $agent_id ) | Availability label. | string |
hvnly_agent_accepts_inquiries( int $agent_id ) | Whether the agent accepts inquiries. | bool |
hvnly_render_agent_availability_badge( int $agent_id ) | Availability badge HTML. | string |
hvnly_get_agent_card_badges( int $agent_id ) | Badges to show on an agent card. | array |
hvnly_get_agent_avatar_url( int $agent_id = 0, int $user_id = 0, int $size = 96, string $image_size = 'medium' ) | Avatar URL for an agent (routes to AvatarService). | string |
hvnly_get_user_avatar_url( int $user_id, int $size = 96 ) | Avatar URL for a WP user. | string |
Tip:
hvnly_get_agent()and its siblings always return anarray, nevernull. Check for a truthyid(orempty()) rather than a null check — this keeps template code branch-free and safe.
Property, rendering, price and time helpers
The property helpers span includes/Functions/property-functions.php and the template loaders in includes/Functions/template-functions.php. They cover structured data access, field rendering, view counts, relative time, currency and price. Price and currency helpers ultimately resolve through the price SSOT, HvnlyNab\Services\Hvnly_Price_Resolver (documented below).
Data access & rendering
| Signature | Purpose | Return |
|---|---|---|
hvnly_get_property_data( int $property_id ) | Structured property record (title, permalink, price, meta). Statically request-cached. | array |
hvnly_get_property_gallery_ids( int $property_id ) | Canonical gallery attachment IDs (SSOT loader). Statically request-cached. | array |
hvnly_render_field( string $field_type, int $property_id, array $property_data = [], string $mode = 'default', array $field = [] ) | Render a single configured field. | string |
hvnly_is_field_configured( array $sections, string $field_type ) | Whether a field type is enabled in the builder config. | bool |
hvnly_has_avatar_section( array $sections ) | Whether an avatar section exists. | bool |
hvnly_get_configured_field_types( array $sections ) | List of configured field types. | array |
hvnly_get_property_card_renderer() | The card renderer service. | renderer object |
hvnly_get_property_single_renderer() | The single-property renderer service. | renderer object |
hvnly_get_default_field_template_mapping() | Default field→template map. | array |
hvnly_get_field_template_mapping() | Active field→template map. | array |
hvnly_get_property_image( int $property_id ) | Featured/first property image. | string |
hvnly_get_property_status( int $property_id ) | Status term(s) for a property. | array/string |
hvnly_get_property_types( int $property_id ) | Property type term(s). | array |
hvnly_get_property_meta( int $property_id ) | Common property meta values. | array |
hvnly_get_property_features_list( int $property_id ) | Features list. | array |
hvnly_get_property_amenities_list( int $property_id ) | Amenities list. | array |
hvnly_get_property_documents( int $property_id ) | Attached documents. | array |
hvnly_get_property_agent( int $property_id ) | Agent record for a property. | array |
Views & relative time
| Signature | Purpose | Return |
|---|---|---|
hvnly_get_property_views( int $property_id ) | Raw view count. | int |
hvnly_get_formatted_property_views( int $property_id ) | Human-formatted view count. | string |
hvnly_get_smart_property_views( int $property_id ) | View count with smart suffix (e.g. 1.2k). | string |
hvnly_get_relative_time( int $timestamp ) | Relative time string. | string |
hvnly_get_time_ago( int $timestamp ) | “X ago” label. | string |
hvnly_is_new_property( int $property_id, int $days = 7 ) | Whether a property is within the “new” window. | bool |
hvnly_get_author_property_ratings( int $author_id = 0 ) | Aggregated ratings for an author. | array |
hvnly_get_author_review_count( int $author_id = 0 ) | Review count for an author. | int |
Currency & price
| Signature | Purpose | Return |
|---|---|---|
hvnly_get_currency_settings() | Currency configuration array. | array |
hvnly_get_currency_symbol( string $code = 'USD' ) | Symbol for a currency code. | string |
hvnly_get_current_currency_symbol() | Active currency symbol. | string |
hvnly_get_current_currency_code() | Active currency code. | string |
hvnly_format_number_with_separators( $number ) | Thousands-separated number. | string |
hvnly_format_large_number_with_suffix( $number ) | Suffix-abbreviated number (k/M). | string |
hvnly_safe_price_to_float( $price ) | Coerce a raw price to a float safely. | float |
hvnly_format_price( $price ) | Format a numeric price with currency. | string |
hvnly_resolve_property_price( int $property_id = null ) | Resolve the display price via the price SSOT. | string/float |
Performance:
hvnly_get_property_data()andhvnly_get_property_gallery_ids()keep a per-request static cache keyed by property ID. Calling them repeatedly inside a loop for the same property is effectively free after the first call — you do not need to memoize results yourself.
Avatar helpers (AvatarService-backed)
All avatar output flows through a single source of truth: HvnlyNab\Common\AvatarService (includes/Common/AvatarService.php). The resolution order is uploaded photo → Gravatar → Havenlytics placeholder. The global helpers hvnly_get_agent_avatar_url() and hvnly_get_user_avatar_url() are facades over this service; the service also filters WordPress core avatars via pre_get_avatar_data, so get_avatar() in a theme returns the correct Havenlytics avatar too.
| Method | Purpose | Return |
|---|---|---|
resolve_url( int $agent_id = 0, int $user_id = 0, int $size = 96, string $image_size = 'medium' ) | Resolve the best avatar URL (SSOT entry point). | string |
resolve_for_user( int $user_id, int $size = 96 ) | Resolve an avatar for a WP user. | string |
placeholder_url() | The Havenlytics placeholder avatar URL. | string |
user_has_gravatar( int $user_id ) | Whether a user has a Gravatar (day-cached). | bool |
clear_gravatar_cache( int $user_id ) | Invalidate the cached Gravatar check. | void |
linked_user_id( int $agent_id ) | WP user ID linked to an agent. | int |
find_agent_id_for_user( int $user_id ) | Agent ID linked to a user. | int |
img_html( string $url, array $atts = [] ) | Build an <img> tag for an avatar URL. | string |
register_hooks() | Register the pre_get_avatar_data filter. | void |
The service exposes DEFAULT_SIZE = 96 and caches Gravatar checks under the prefix hvnly_has_gravatar_ (a per-user transient with a one-day TTL).
Common mistake: Do not build avatar URLs by reading the agent photo meta directly. That bypasses the Gravatar and placeholder fallbacks and will render broken images for agents without an uploaded photo. Always call
hvnly_get_agent_avatar_url()orAvatarService::resolve_url().
Contact Agent helpers
Defined in includes/Functions/contact-agent-functions.php. These drive the Contact Agent inquiry module — rendering the button, checking feature flags, reading rate-limit configuration and localizing the front-end script. The module object is returned by hvnly_contact_agent_module().
| Signature | Purpose | Return |
|---|---|---|
hvnly_contact_agent_module() | The Contact Agent module instance. | ?ContactAgentModule |
hvnly_is_contact_agent_enabled() | Whether the module is enabled. | bool |
hvnly_render_contact_agent_button( int $property_id = 0, array $args = [] ) | Echo the Contact Agent button/modal markup. | void |
hvnly_localize_contact_agent_script( int $property_id = 0 ) | Localize the front-end inquiry script. | void |
hvnly_contact_agent_get_client_ip() | Best-effort client IP (for rate limiting). | string |
hvnly_contact_agent_inquiries_table_exists() | Whether the inquiries table is installed. | bool |
hvnly_contact_agent_notify_agent_enabled() | Whether agent notifications are on. | bool |
hvnly_contact_agent_notify_admin_enabled() | Whether admin notifications are on. | bool |
hvnly_contact_agent_notify_sender_enabled() | Whether sender auto-reply is on. | bool |
hvnly_contact_agent_honeypot_enabled() | Whether the honeypot spam trap is on. | bool |
hvnly_contact_agent_rate_limit_max() | Max submissions per window. | int |
hvnly_contact_agent_rate_limit_window() | Rate-limit window length (seconds). | int |
Security:
hvnly_render_contact_agent_button()echoes markup directly. Call it only inside a template output context, never in a REST or AJAX callback that returns JSON. The button and its modal already handle nonces, the honeypot and rate limiting — do not reimplement the submission flow yourself.
Field option helpers
Defined in includes/Functions/field-options.php. These supply the canonical option sets for select fields (heating, cooling, water, location, country) and provide the hydration utilities the builder uses to populate select controls.
| Signature | Purpose | Return |
|---|---|---|
hvnly_get_heating_field_options() | Heating select options. | array |
hvnly_get_cooling_field_options() | Cooling select options. | array |
hvnly_get_water_field_options() | Water select options. | array |
hvnly_get_location_field_options() | Location select options. | array |
hvnly_get_country_field_options() | Country select options. | array |
hvnly_get_registered_field_options() | All registered option sets. | array |
hvnly_get_field_options( string $field_name ) | Options for a named field. | array |
hvnly_hydrate_select_field_options( array $field ) | Populate a single field’s options. | array |
hvnly_hydrate_fields_select_options( array $fields ) | Populate options across many fields. | array |
The Helpers class (HvnlyNab\Helpers)
Alongside the procedural helpers, Havenlytics has an internal Helpers singleton at includes/Helpers.php. It is reachable via HvnlyNab\Helpers::get_instance() or through the plugin accessor HVNLY_NAB()->get_helper(). Its instance methods back some of the global functions (image sizing, gallery images, property IDs, ratings, currency) and use the object cache group havenlytics. Prefer the global hvnly_* helpers in application code; reach for the class only when you are extending the plugin internally.
| Method group | Methods |
|---|---|
| Image sizes | add_property_image_sizes(), get_property_image(), get_property_gallery_images() |
| Property ID | generate_property_id(), get_property_id() |
| Data accessors | get_meta_value(), get_array_value(), data_exists() |
| Currency / price | get_currency_settings(), format_price(), get_max_property_price() |
| Ratings | get_author_property_ratings(), get_rating_stars() |
| Filter sidebar | hvnly_filter_sidebar_get_fields(), hvnly_filter_sidebar_get_min_price_options() |
Note:
HvnlyNab\Helpersis a singleton — never instantiate it withnew. Always callHvnlyNab\Helpers::get_instance()(orHVNLY_NAB()->get_helper()) so you share the same cached state as the rest of the plugin.
The price SSOT: Hvnly_Price_Resolver
HvnlyNab\Services\Hvnly_Price_Resolver (includes/Services/Hvnly_Price_Resolver.php) is the single source of truth for property price resolution. The global helper hvnly_resolve_property_price() delegates to it. It exposes a static resolve( $property_id ) method and a get_mortgage_mode() helper for pricing display mode. Because every price surface (cards, single view, search, Workspace) routes through this resolver, using the helper guarantees consistent output across the site.
Code examples
Read structured property data and its gallery
<?php
// Inside a single-property template (get_the_ID() resolves the current post).
$property_id = get_the_ID();
$data = hvnly_get_property_data( $property_id );
if ( ! empty( $data ) ) {
printf(
'<h2>%s</h2><p class="price">%s</p>',
esc_html( $data['title'] ),
esc_html( hvnly_resolve_property_price( $property_id ) )
);
}
// Canonical gallery attachment IDs (SSOT loader).
$gallery_ids = hvnly_get_property_gallery_ids( $property_id );
foreach ( $gallery_ids as $attachment_id ) {
echo wp_get_attachment_image( $attachment_id, 'large' );
}
Render the Contact Agent button for a property
<?php
// Only render when the module is active.
if ( hvnly_is_contact_agent_enabled() ) {
hvnly_render_contact_agent_button( get_the_ID(), array(
'label' => __( 'Contact this agent', 'my-theme' ),
) );
}
Resolve an agent and its avatar
<?php
$agent = hvnly_get_agent( $agent_id );
if ( ! empty( $agent['id'] ) ) {
$avatar = hvnly_get_agent_avatar_url( $agent['id'], 0, 128, 'medium' );
printf(
'<div class="agent"><img src="%s" width="128" height="128" alt="%s" /><span>%s</span></div>',
esc_url( $avatar ),
esc_attr( $agent['name'] ?? '' ),
esc_html( $agent['name'] ?? '' )
);
}
Resolve an avatar through the SSOT service directly
<?php
use HvnlyNab\Common\AvatarService;
// uploaded photo -> Gravatar -> Havenlytics placeholder
$url = AvatarService::resolve_url( $agent_id, 0, AvatarService::DEFAULT_SIZE, 'medium' );
echo esc_url( $url );
Best practices
- Guard optional features. Wrap Contact Agent output in
hvnly_is_contact_agent_enabled()so disabling the module cleanly removes the button. - Escape on output. Helpers return raw data (URLs, strings, numbers). Escape with
esc_url(),esc_html(),esc_attr()at the point of output. - Prefer helpers over meta reads. Reading
get_post_meta()directly for price, gallery or avatar data bypasses the SSOT services and their caching/fallbacks. - Pass explicit IDs in loops. Most helpers default to the current post; passing the ID explicitly avoids surprises inside nested or custom queries.
Performance recommendations
- Lean on the built-in static request caches in
hvnly_get_property_data()andhvnly_get_property_gallery_ids()instead of duplicating your own arrays. - Avatar Gravatar checks are day-cached per user; avoid clearing that cache in hot paths.
- The
Helpersclass caches ratings and max-price lookups in thehavenlyticsobject cache group — persistent object caching (Redis/Memcached) makes these effectively free across requests.
Security notes
- Helpers do not sanitize output for you — always escape at output time.
- The Contact Agent flow includes nonces, a honeypot and rate limiting; never bypass
hvnly_render_contact_agent_button()with a hand-rolled form. - Avatar URLs may resolve to remote Gravatar images; treat them as untrusted URLs and pass through
esc_url().
Common mistakes
- Instantiating
HvnlyNab\Helperswithnewinstead ofget_instance(). - Assuming a helper returns
null— agent/property helpers return empty arrays; test withempty(). - Building price strings manually instead of calling
hvnly_resolve_property_price(), which caus