locate_template($slug, $name);
if ($template === '') {
return;
}
include $template;
}
/**
* Render an admin template under `templates/admin/`.
*
* @since 1.0.0
*
* @param string $view Template basename without `.php`.
* @param object $viewModel View model passed as `$viewModel` in the template scope.
*/
public function render_admin(string $view, object $viewModel): void
{
$template = BIZDEX_UPLISTING_PLUGIN_DIR . 'templates/admin/' . $view . '.php';
if (!is_readable($template)) {
echo '
'
. esc_html__('Error: View file not found.', 'advanced-connector-for-uplisting')
. '
';
return;
}
include $template;
}
/**
* Render a template file by absolute path (gateway modules, etc.).
*
* @since 1.0.0
*
* @param string $absolute_path Absolute path to the template file.
* @param object $vm View model passed as `$vm` in the template scope.
*/
public function render_file(string $absolute_path, object $vm): void
{
if (!is_readable($absolute_path)) {
return;
}
include $absolute_path;
}
/**
* Capture rendered template output as a string.
*
* @since 1.0.0
*
* @param string $slug Template base name.
* @param object $vm View model passed as `$vm` in the template scope.
* @param string $name Optional template suffix.
*/
public function capture(string $slug, object $vm, string $name = ''): string
{
ob_start();
$this->render($slug, $vm, $name);
return (string) ob_get_clean();
}
/**
* Load a plugin template part with theme override support.
*
* WordPress {@see load_template()} only exposes the `$args` array itself; it does
* not extract keys into local variables. Reservation/single templates expect vars
* like `$booking`, so we extract here.
*
* @since 1.0.0
*
* @param string $slug Template base name.
* @param string $name Optional template suffix.
* @param array $args Variables for the template (`$args` and extracted keys).
*/
public function get_template_part(string $slug, string $name = '', array $args = []): void
{
$template = $this->locate_template($slug, $name);
if ($template === '') {
return;
}
/**
* Fires before a template file is loaded.
*
* @param string $template Absolute path to the template.
* @param bool $load_once Whether the file was require_once'd (always false here).
* @param array $args Template arguments.
*/
do_action('bizdex_uplisting_before_load_template', $template, false, $args);
do_action('wp_before_load_template', $template, false, $args); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- WordPress core template-load action.
$this->include_template_file($template, $args);
/**
* Fires after a template file is loaded.
*
* @param string $template Absolute path to the template.
* @param bool $load_once Whether the file was require_once'd (always false here).
* @param array $args Template arguments.
*/
do_action('bizdex_uplisting_after_load_template', $template, false, $args);
do_action('wp_after_load_template', $template, false, $args); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- WordPress core template-load action.
}
/**
* Include a template in an isolated scope with `$args` locals.
*
* @param string $template Absolute template path.
* @param array $args Template variables.
*/
private function include_template_file(string $template, array $args): void
{
(static function (string $template_file, array $args): void {
extract($args, EXTR_SKIP);
require $template_file;
})($template, $args);
}
/**
* Render the pricing breakdown mount point.
*
* @since 1.0.0
*
* @param PropertyDetails|false|null $property Optional property model.
*/
public function render_pricing_breakdown($property = null): void
{
if (!$property) {
$property = function_exists('bizdex_uplisting_resolve_template_property')
? bizdex_uplisting_resolve_template_property(null)
: false;
}
$this->get_template_part('single-property/pricing-breakdown-template', '', [
'property' => $property,
]);
}
/**
* Locate a template file in the theme override path or plugin templates.
*
* @since 1.0.0
*
* @return string Absolute path, or empty when not found.
*/
private function locate_template(string $slug, string $name): string
{
$template = '';
if ($name !== '') {
$template = (string) locate_template([
"wp-uplisting-connector/{$slug}-{$name}.php",
"{$slug}-{$name}.php",
]);
}
if ($template === '') {
$template = (string) locate_template([
"wp-uplisting-connector/{$slug}.php",
"{$slug}.php",
]);
}
if ($template === '') {
if ($name !== '') {
$plugin_template = BIZDEX_UPLISTING_PLUGIN_DIR . "templates/{$slug}-{$name}.php";
if (is_readable($plugin_template)) {
$template = $plugin_template;
}
}
if ($template === '') {
$plugin_template = BIZDEX_UPLISTING_PLUGIN_DIR . "templates/{$slug}.php";
if (is_readable($plugin_template)) {
$template = $plugin_template;
}
}
}
return $template;
}
}
add_action('the_post', 'bizdex_uplisting_setup_property_data');
if (!function_exists('bizdex_uplisting_setup_property_data')) {
/**
* Set the global `$bizdex_uplisting_property` model when looping over property posts.
*
* Hooked to `the_post`. No-op for non-`bizdexul_property` post types.
*
* @param \WP_Post $post Current post from the main query loop.
* @return void
*/
function bizdex_uplisting_setup_property_data($post)
{
if ($post->post_type !== 'bizdexul_property') {
return;
}
global $bizdex_uplisting_property;
$bizdex_uplisting_property = bizdex_uplisting_get_property($post);
}
}
// Meta scripts and inputs
add_action('bizdex_uplisting_before_single_property', 'bizdex_uplisting_template_single_meta', 10);
// Gallery & Lightbox
add_action('bizdex_uplisting_before_single_property_summary', 'bizdex_uplisting_template_single_gallery', 10);
// Title & capacity meta live in the main content column
add_action('bizdex_uplisting_single_property_main_content', 'bizdex_uplisting_template_single_title', 5);
// Main content + sticky booking sidebar
add_action('bizdex_uplisting_single_property_summary', 'bizdex_uplisting_template_single_tabs', 10);
add_action('bizdex_uplisting_single_property_summary', 'bizdex_uplisting_template_single_booking', 20);
// Inner Left Main Content Column Sections
add_action('bizdex_uplisting_single_property_main_content', 'bizdex_uplisting_template_single_description', 10);
add_action('bizdex_uplisting_single_property_main_content', 'bizdex_uplisting_template_single_amenities', 20);
add_action('bizdex_uplisting_single_property_main_content', 'bizdex_uplisting_template_single_house_rules', 40);
// Booking Form Date & Guest Input Fields
add_action('bizdex_uplisting_single_property_booking_fields', 'bizdex_uplisting_template_single_booking_date', 10);
add_action('bizdex_uplisting_single_property_booking_fields', 'bizdex_uplisting_template_single_booking_guest', 20);
// Booking card structural sections (pricing, contact footer)
add_action('bizdex_uplisting_booking_card_after_fields', 'bizdex_uplisting_template_single_booking_pricing_breakdown', 10);
add_action('bizdex_uplisting_booking_card_footer', 'bizdex_uplisting_template_booking_card_contact', 20);
// Booking Form Pricing Breakdown
add_action('bizdex_uplisting_single_property_booking_pricing_breakdown', 'bizdex_uplisting_template_single_booking_pricing_breakdown', 10);
// Payment gateways are managed by ReservationService.
// Register custom gateways via the 'uplisting_payment_gateways' filter (class names).
// Dynamic Booking Form Layouts
add_action('bizdex_uplisting_single_property_booking_form', 'bizdex_uplisting_template_single_booking_form_wrapper', 10);
// reservation fields hook mapping
add_action('bizdex_uplisting_reservation_fields', 'bizdex_uplisting_reservation_fields_personal', 10);
// reservation submit hook mapping
add_action('bizdex_uplisting_reservation_submit', 'bizdex_uplisting_reservation_terms_submit', 10);
// reservation summary card mapping
add_action('bizdex_uplisting_reservation_summary', 'bizdex_uplisting_reservation_booking_review', 10);
// Contact phone filter callback
add_filter('bizdex_uplisting_property_contact_phone', 'bizdex_uplisting_default_contact_phone', 10, 2);
/**
* Loop / Archive Hooks Mapping
*/
// Loop Item
add_action('bizdex_uplisting_before_property_loop_item', 'bizdex_uplisting_template_loop_property_thumbnail', 10);
add_action('bizdex_uplisting_before_property_loop_item_title', 'bizdex_uplisting_template_loop_property_link_open', 10);
add_action('bizdex_uplisting_property_loop_item_title', 'bizdex_uplisting_template_loop_property_title', 10);
add_action('bizdex_uplisting_after_property_loop_item_title', 'bizdex_uplisting_template_loop_property_meta', 5);
add_action('bizdex_uplisting_after_property_loop_item', 'bizdex_uplisting_template_loop_property_link_close', 5);
add_action('bizdex_uplisting_after_property_loop_item', 'bizdex_uplisting_template_loop_property_footer', 10);
// Archive
add_action('bizdex_uplisting_before_property_archive', 'bizdex_uplisting_template_archive_search_filter', 10, 3);
add_action('bizdex_uplisting_before_property_loop', 'bizdex_uplisting_template_archive_results_header', 10, 3);
add_action('bizdex_uplisting_property_archive_no_results', 'bizdex_uplisting_template_archive_no_results', 10);
add_action('bizdex_uplisting_archive_description', 'bizdex_uplisting_template_archive_description', 10);
// Content wrappers (WooCommerce-style )
add_action('bizdex_uplisting_before_main_content', 'bizdex_uplisting_output_content_wrapper', 10);
add_action('bizdex_uplisting_after_main_content', 'bizdex_uplisting_output_content_wrapper_end', 10);
/**
* Template Render Functions
*/
if (!function_exists('bizdex_uplisting_template_single_title')) {
/**
* Render the single property title block.
*
* Hook: `uplisting_property_main_content_before`.
* Template: `templates/single-property/title.php`.
*/
function bizdex_uplisting_template_single_title()
{
bizdex_uplisting_get_template_part('single-property/title');
}
}
if (!function_exists('bizdex_uplisting_template_single_meta')) {
/**
* Render property meta/scripts injected before the single property layout.
*
* Hook: `uplisting_before_single_property`.
* Template: `templates/single-property/meta.php`.
*/
function bizdex_uplisting_template_single_meta()
{
$args = FrontendManager::get_single_property_meta_template_args([]);
if ($args === false) {
return;
}
bizdex_uplisting_get_template_part('single-property/meta', '', $args);
}
}
if (!function_exists('bizdex_uplisting_template_single_booking')) {
/**
* Render sidebar booking form wrapper on single property.
*
* Hook: `uplisting_single_property_summary` (priority 20).
* Template: `templates/single-property/booking-form.php`.
*/
function bizdex_uplisting_template_single_booking()
{
bizdex_uplisting_get_template_part('single-property/booking-form');
}
}
if (!function_exists('bizdex_uplisting_template_single_gallery')) {
/**
* Render property image gallery and lightbox markup.
*
* Hook: `uplisting_before_single_property_summary`.
* Template: `templates/single-property/gallery.php`.
*/
function bizdex_uplisting_template_single_gallery()
{
bizdex_uplisting_get_template_part('single-property/gallery');
}
}
if (!function_exists('bizdex_uplisting_template_single_tabs')) {
/**
* Render tabbed content shell (description/amenities/rules).
*
* Hook: `uplisting_single_property_summary`.
* Template: `templates/single-property/tabs.php`.
*/
function bizdex_uplisting_template_single_tabs()
{
bizdex_uplisting_get_template_part('single-property/tabs');
}
}
if (!function_exists('bizdex_uplisting_template_single_description')) {
/**
* Render the single property description template part.
*/
function bizdex_uplisting_template_single_description()
{
bizdex_uplisting_get_template_part('single-property/description');
}
}
if (!function_exists('bizdex_uplisting_template_single_amenities')) {
/**
* Render the single property amenities template part.
*/
function bizdex_uplisting_template_single_amenities()
{
bizdex_uplisting_get_template_part('single-property/amenities');
}
}
if (!function_exists('bizdex_uplisting_template_single_house_rules')) {
/**
* Render the single property house rules template part.
*/
function bizdex_uplisting_template_single_house_rules()
{
bizdex_uplisting_get_template_part('single-property/house-rules');
}
}
if (!function_exists('bizdex_uplisting_template_single_booking_date')) {
/**
* Render the booking form date picker template part.
*/
function bizdex_uplisting_template_single_booking_date()
{
bizdex_uplisting_get_template_part('single-property/date');
}
}
if (!function_exists('bizdex_uplisting_template_single_booking_guest')) {
/**
* Render the booking form guest selector template part.
*/
function bizdex_uplisting_template_single_booking_guest()
{
bizdex_uplisting_get_template_part('single-property/guest');
}
}
/**
* Filter the reservation submit button label (Stripe → "Pay & Confirm").
*/
add_filter('bizdex_uplisting_reservation_submit_label', 'bizdex_uplisting_reservation_submit_label_filter', 10, 2);
if (!function_exists('bizdex_uplisting_reservation_submit_label_filter')) {
/**
* Filter callback for {@see uplisting_reservation_submit_label}.
*
* @param string $label Default button label from reservation template.
* @param mixed $booking {@see BookingService} instance or null.
* @return string Updated label when Stripe gateway is enabled.
*/
function bizdex_uplisting_reservation_submit_label_filter($label, $booking)
{
$gateway = ReservationService::instance()->get_checkout_gateway($booking);
if ($gateway) {
return (string) apply_filters(
'bizdex_uplisting_gateway_submit_button_label_' . $gateway->get_id(),
$gateway->submit_button_label($label, $booking),
$booking,
$gateway
);
}
return $label;
}
}
if (!function_exists('bizdex_uplisting_reservation_fields_personal')) {
/**
* Render the reservation personal details fields template part.
*
* @param BookingDetails|null $booking Current booking object.
*/
function bizdex_uplisting_reservation_fields_personal($booking = null)
{
bizdex_uplisting_get_template_part('reservation/fields-personal', '', array('booking' => $booking));
}
}
if (!function_exists('bizdex_uplisting_template_booking_card_calendar_rates')) {
/**
* Render Calendar Rates UI in the booking card footer when enabled.
*
* Hook: `uplisting_booking_card_footer` (priority 10).
* Template: `templates/single-property/calendar-rates.php`.
*
* @param PropertyDetails|null $property Current property model.
*/
function bizdex_uplisting_template_booking_card_calendar_rates($property = null): void
{
$property = bizdex_uplisting_resolve_template_property($property);
if (!$property || !$property->should_show_calendar_rates()) {
return;
}
bizdex_uplisting_get_template_part('single-property/calendar-rates', '', [
'property' => $property,
]);
}
}
if (!function_exists('bizdex_uplisting_template_booking_card_contact')) {
/**
* Render booking card contact footer.
*
* Hook: `uplisting_booking_card_footer` (priority 20).
* Template: `templates/single-property/booking-card-contact.php`.
*
* @param PropertyDetails|null $property Current property model.
*/
function bizdex_uplisting_template_booking_card_contact($property = null): void
{
$property = bizdex_uplisting_resolve_template_property($property);
if (!$property) {
return;
}
bizdex_uplisting_get_template_part('single-property/booking-card-contact', '', [
'property' => $property,
]);
}
}
if (!function_exists('bizdex_uplisting_template_single_booking_pricing_breakdown')) {
/**
* Render the booking form pricing breakdown mount point.
*
* Hook: `uplisting_single_property_booking_pricing_breakdown`
* and `uplisting_booking_card_after_fields`.
* Template: `templates/single-property/pricing-breakdown-template.php`.
*
* @param PropertyDetails|false|null $property Current property model.
* @return void
*/
function bizdex_uplisting_template_single_booking_pricing_breakdown($property = null)
{
$property = bizdex_uplisting_resolve_template_property($property);
if (!$property || !$property->booking_card_uses_calendar_form()) {
return;
}
bizdex_uplisting_render_pricing_breakdown_template($property);
}
}
if (!function_exists('bizdex_uplisting_reservation_terms_submit')) {
/**
* Render the reservation terms and submit button template part.
*
* @param BookingDetails|null $booking Current booking object.
*/
function bizdex_uplisting_reservation_terms_submit($booking = null)
{
bizdex_uplisting_get_template_part('reservation/terms-submit', '', array('booking' => $booking));
}
}
if (!function_exists('bizdex_uplisting_reservation_booking_review')) {
/**
* Render the reservation booking review / price summary card.
*
* Hook: `uplisting_reservation_summary`. Builds args via
* {@see FrontendManager::get_booking_review_data()} and loads
* `templates/reservation/booking-review.php` when data is available.
*
* @param BookingDetails|null $booking Active reservation booking object.
* @return void
*/
function bizdex_uplisting_reservation_booking_review($booking = null)
{
if (!empty($GLOBALS['bizdex_uplisting_reservation_review_args'])) {
bizdex_uplisting_get_template_part('reservation/booking-review', '', $GLOBALS['bizdex_uplisting_reservation_review_args']);
return;
}
$args = FrontendManager::get_booking_review_data($booking);
if ($args !== false) {
bizdex_uplisting_get_template_part('reservation/booking-review', '', $args);
}
}
}
if (!function_exists('bizdex_uplisting_default_contact_phone')) {
/**
* Default filter callback for property contact phone.
*
* @param string $phone Current phone value.
* @param mixed $property Property model instance.
* @return string
*/
function bizdex_uplisting_default_contact_phone($phone, $property)
{
return $phone; // Return the passed default or custom set
}
}
if (!function_exists('bizdex_uplisting_template_single_booking_form_wrapper')) {
/**
* Render the WordPress booking card for the current property.
*
* Hook: `uplisting_single_property_booking_form`.
* Template: `templates/single-property/booking-form-default.php`.
*/
function bizdex_uplisting_template_single_booking_form_wrapper()
{
$property = bizdex_uplisting_resolve_template_property(null);
if (!$property) {
return;
}
bizdex_uplisting_get_template_part('single-property/booking-form-default', '', ['property' => $property]);
}
}
/**
* Loop / Archive Render Functions
*/
if (!function_exists('bizdex_uplisting_template_loop_property_link_open')) {
/**
* Render the loop property link open template part.
*/
function bizdex_uplisting_template_loop_property_link_open()
{
bizdex_uplisting_get_template_part('loop/link-open');
}
}
if (!function_exists('bizdex_uplisting_template_loop_property_link_close')) {
/**
* Render the loop property link close template part.
*/
function bizdex_uplisting_template_loop_property_link_close()
{
bizdex_uplisting_get_template_part('loop/link-close');
}
}
if (!function_exists('bizdex_uplisting_template_loop_property_thumbnail')) {
/**
* Render the loop property thumbnail template part.
*/
function bizdex_uplisting_template_loop_property_thumbnail()
{
bizdex_uplisting_get_template_part('loop/thumbnail', '', [
'enable_carousel' => get_option('bizdex_uplisting_enable_carousel', '1') === '1',
]);
}
}
if (!function_exists('bizdex_uplisting_template_loop_property_title')) {
/**
* Render the loop property title template part.
*/
function bizdex_uplisting_template_loop_property_title()
{
bizdex_uplisting_get_template_part('loop/title');
}
}
if (!function_exists('bizdex_uplisting_template_loop_property_meta')) {
/**
* Render the loop property meta template part.
*/
function bizdex_uplisting_template_loop_property_meta()
{
bizdex_uplisting_get_template_part('loop/meta');
}
}
if (!function_exists('bizdex_uplisting_template_loop_property_price')) {
/**
* Render the loop property price template part.
*/
function bizdex_uplisting_template_loop_property_price()
{
bizdex_uplisting_get_template_part('loop/price');
}
}
if (!function_exists('bizdex_uplisting_template_loop_property_footer')) {
/**
* Render archive card footer (price).
*/
function bizdex_uplisting_template_loop_property_footer()
{
echo '';
}
}
if (!function_exists('bizdex_uplisting_template_archive_search_filter')) {
/**
* Render the property search/filter bar above the archive listing.
*
* @param \WP_Query $properties_query Property query from the shortcode.
* @param array $atts Shortcode attributes.
* @param string $current_view Active view mode.
*/
function bizdex_uplisting_template_archive_search_filter($properties_query, $atts, $current_view)
{
if (($atts['show_filter'] ?? '') !== 'yes') {
return;
}
$filter = $atts['filter'] ?? [];
$visible = [
'location' => true,
'date' => true,
'guest' => true,
'more_filters' => true,
'clear' => true,
'submit' => true,
'bedrooms' => true,
'beds' => true,
'bathrooms' => true,
];
if (!empty($atts['search_visible']) && is_array($atts['search_visible'])) {
foreach ($atts['search_visible'] as $key => $enabled) {
$visible[sanitize_key((string) $key)] = (bool) $enabled;
}
}
$listing_url = '';
if (!empty($atts['search_listing_url'])) {
$listing_url = (string) $atts['search_listing_url'];
} elseif (is_singular()) {
$listing_url = (string) get_permalink();
}
if ($listing_url === '') {
$listing_url = FrontendManager::get_listing_page_url();
}
bizdex_uplisting_get_template_part('archive/search-filter', '', array_merge($filter, [
'current_view' => $current_view,
'locations' => ListingQuery::get_location_options(),
'listing_url' => $listing_url,
'found_posts' => $properties_query instanceof \WP_Query ? (int) $properties_query->found_posts : 0,
'visible' => $visible,
]));
}
}
if (!function_exists('bizdex_uplisting_template_archive_results_header')) {
/**
* Render the archive results header (count + view toggles).
*
* @param \WP_Query $properties_query Property query from the archive.
* @param array $atts Archive attributes.
* @param string $current_view Active view mode.
*/
function bizdex_uplisting_template_archive_results_header($properties_query, $atts, $current_view)
{
$atts = is_array($atts) ? $atts : [];
$enabled_views = FrontendManager::resolve_enabled_views($atts);
bizdex_uplisting_get_template_part('archive/results-header', '', [
'properties_query' => $properties_query,
'current_view' => $current_view,
'show_grid' => in_array('grid', $enabled_views, true),
'show_list' => in_array('list', $enabled_views, true),
'show_slider' => in_array('slider', $enabled_views, true),
'view_urls' => [
'grid' => ListingQuery::build_listing_view_url('grid'),
'list' => ListingQuery::build_listing_view_url('list'),
'slider' => ListingQuery::build_listing_view_url('slider'),
],
]);
}
}
if (!function_exists('bizdex_uplisting_template_archive_description')) {
/**
* Output taxonomy/archive descriptions above the property loop.
*/
function bizdex_uplisting_template_archive_description(): void
{
if (is_tax('bizdexul_amenity')) {
$description = term_description();
if (!empty($description)) {
echo '' . wp_kses_post($description) . '
';
}
}
}
}
if (!function_exists('bizdex_uplisting_output_content_wrapper')) {
/**
* Output the start of the page wrapper (``).
*
* Hook: `bizdex_uplisting_before_main_content`.
* Template: `templates/global/wrapper-start.php`.
*
* @since 1.0.0
*/
function bizdex_uplisting_output_content_wrapper(): void
{
bizdex_uplisting_get_template_part('global/wrapper-start');
}
}
if (!function_exists('bizdex_uplisting_output_content_wrapper_end')) {
/**
* Output the end of the page wrapper (``).
*
* Hook: `bizdex_uplisting_after_main_content`.
* Template: `templates/global/wrapper-end.php`.
*
* @since 1.0.0
*/
function bizdex_uplisting_output_content_wrapper_end(): void
{
bizdex_uplisting_get_template_part('global/wrapper-end');
}
}
if (!function_exists('bizdex_uplisting_template_archive_no_results')) {
/**
* Render the empty-state message when no properties match filters.
*/
function bizdex_uplisting_template_archive_no_results()
{
echo '';
echo '
' . esc_html__('No properties found', 'advanced-connector-for-uplisting') . '
';
echo '
' . esc_html__('Try adjusting your search filters.', 'advanced-connector-for-uplisting') . '
';
echo '
';
}
}
if (!function_exists('bizdex_uplisting_get_template_part')) {
/**
* Template helpers that call existing model / renderer APIs.
*/
function bizdex_uplisting_get_template_part($slug, $name = '', $args = [])
{
Bizdex_Uplisting_Template_Renderer::instance()->get_template_part($slug, $name, $args);
}
}
if (!function_exists('bizdex_uplisting_render_pricing_breakdown_template')) {
/**
* Render the pricing breakdown mount point template.
*
* @param PropertyDetails|false|null $property Optional property model.
*/
function bizdex_uplisting_render_pricing_breakdown_template($property = null): void
{
Bizdex_Uplisting_Template_Renderer::instance()->render_pricing_breakdown($property);
}
}
if (!function_exists('bizdex_uplisting_get_property')) {
/**
* Resolve a PropertyDetails instance from a post ID, object, or the global post.
*
* @param int|\WP_Post|null $post Property post ID or object; null uses global post.
* @return PropertyDetails|false
*/
function bizdex_uplisting_get_property($post = null)
{
if (empty($post)) {
global $post;
}
if (empty($post)) {
return false;
}
$property = new PropertyDetails($post);
return $property->get_id() > 0 ? $property : false;
}
}
if (!function_exists('bizdex_uplisting_resolve_template_property')) {
/**
* Resolve a property from a model instance, template args, or loop/global context.
*
* @param PropertyDetails|array|null $args Property model, template args, or null.
* @return PropertyDetails|false
*/
function bizdex_uplisting_resolve_template_property($args = null)
{
if ($args instanceof PropertyDetails) {
return $args;
}
if (is_array($args)) {
if (!empty($args['property']) && $args['property'] instanceof PropertyDetails) {
return $args['property'];
}
}
global $bizdex_uplisting_property;
if (isset($bizdex_uplisting_property) && $bizdex_uplisting_property instanceof PropertyDetails) {
return $bizdex_uplisting_property;
}
return bizdex_uplisting_get_property();
}
}
if (!function_exists('bizdex_uplisting_resolve_template_booking')) {
/**
* Resolve the booking object passed into an admin or email template.
*
* @param array|null $args Template args from load_template().
* @return BookingDetails|null
*/
function bizdex_uplisting_resolve_template_booking($args = null)
{
if (!is_array($args) || empty($args['booking'])) {
return null;
}
return $args['booking'] instanceof BookingDetails ? $args['booking'] : null;
}
}
if (!function_exists('bizdex_uplisting_get_booking_data')) {
/**
* Return booking meta as an associative array for template helpers.
*
* @param int $booking_id Booking post ID.
* @return array
*/
function bizdex_uplisting_get_booking_data($booking_id)
{
$booking = new BookingDetails((int) $booking_id);
$data = [
'property_id' => $booking->get_property_id(),
'first_name' => $booking->get_first_name(),
'last_name' => $booking->get_last_name(),
'email' => $booking->get_email(),
'phone' => $booking->get_phone(),
'check_in' => $booking->get_check_in(),
'check_out' => $booking->get_check_out(),
'adults' => $booking->get_adults(),
'kids' => $booking->get_kids(),
'total_amount' => $booking->get_total_amount(),
'booking_id' => (int) $booking_id,
'property_title' => get_the_title($booking->get_property_id()),
'property_url' => get_permalink($booking->get_property_id()),
'edit_url' => admin_url('post.php?post=' . (int) $booking_id . '&action=edit'),
'site_name' => get_bloginfo('name'),
];
return apply_filters('bizdex_uplisting_get_booking_data', $data, $booking_id);
}
}