b6df4dbb92
MLS plugin fixes from this session: - Fix silent insert failures: location column NOT NULL was rejecting wpdb->insert calls, causing ~18k new properties since Dec 2025 to be lost. Inserts now build raw SQL with ST_PointFromText so the spatial column is populated atomically. - Auto-refresh expired media URLs in MLS_Media_Handler::fetch_and_cache(), guarded by a property-level GET_LOCK so concurrent fetches share one API refresh. - Normalize WP_Error to null in mls_get_property_image() so callers can rely on the documented string|null contract. - Support comma-separated property_type filters in MLS_Query and MLS_Cluster so the homepage "View All Commercial" link (?property_type=Commercial+Sale,Land,Farm) actually filters correctly. - Incremental sync now looks back 10 minutes past the latest modification timestamp as a safety margin against missed records. - Smart sync exits silently (info-level, not warning) when a full sync is in progress. Operational: - New cron: weekly full sync Sundays at 3 AM (/usr/local/bin/mls-full-sync). - New cron: hourly 2GB cap on mls-thumbnails/ and cache/transformed-images/ (/usr/local/bin/mls-image-cache-cap). - Logrotate config for wp-content/debug.log (2-day retention, daily rotation, delaycompress). Repo policy: - CLAUDE.md updated with explicit "commit everything except build artifacts" policy. - .gitignore: untrack runtime image caches and debug.log rotations. Other modifications in this snapshot are pre-existing in-flight theme/plugin/db_content_updates work. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
283 lines
12 KiB
PHP
Executable File
283 lines
12 KiB
PHP
Executable File
<?php
|
|
/**
|
|
* Template Name: Property Inquiry
|
|
* Template for property information request form
|
|
*
|
|
* @package HomeProz
|
|
*/
|
|
|
|
// Prevent direct access
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
// Get MLS listing key from URL
|
|
$listing_key = isset($_GET['listing']) ? sanitize_text_field($_GET['listing']) : '';
|
|
|
|
// Redirect to properties page if no listing specified
|
|
if (!$listing_key || !function_exists('mls_get_property')) {
|
|
wp_redirect(get_post_type_archive_link('property'));
|
|
exit;
|
|
}
|
|
|
|
// Fetch property from MLS database
|
|
$property = mls_get_property($listing_key);
|
|
|
|
if (!$property) {
|
|
wp_redirect(get_post_type_archive_link('property'));
|
|
exit;
|
|
}
|
|
|
|
// Extract property data
|
|
$price = $property->list_price;
|
|
$listing_id = $property->listing_id;
|
|
$agent_mls_id = $property->list_agent_mls_id;
|
|
$office_name = $property->list_office_name;
|
|
|
|
// Check if this is a HomeProz listing
|
|
$is_homeproz_listing = false;
|
|
if ($office_name) {
|
|
$is_homeproz_listing = (stripos($office_name, 'HomeProz') !== false || stripos($office_name, 'Home Proz') !== false);
|
|
}
|
|
|
|
// For HomeProz listings, look up the agent from Agent CPT by MLS ID
|
|
$homeproz_agent_id = null;
|
|
$homeproz_agent_email = '';
|
|
$homeproz_agent_name = '';
|
|
if ($is_homeproz_listing && $agent_mls_id) {
|
|
$agent_query = new WP_Query(array(
|
|
'post_type' => 'agent',
|
|
'posts_per_page' => 1,
|
|
'post_status' => 'publish',
|
|
'meta_query' => array(
|
|
array(
|
|
'key' => 'agent_mls_id',
|
|
'value' => $agent_mls_id,
|
|
'compare' => '=',
|
|
),
|
|
),
|
|
));
|
|
if ($agent_query->have_posts()) {
|
|
$homeproz_agent_id = $agent_query->posts[0]->ID;
|
|
$homeproz_agent_name = get_the_title($homeproz_agent_id);
|
|
$agent_disabled = get_field('agent_disabled', $homeproz_agent_id);
|
|
if (!$agent_disabled) {
|
|
$homeproz_agent_email = get_field('agent_email', $homeproz_agent_id);
|
|
}
|
|
}
|
|
wp_reset_postdata();
|
|
}
|
|
|
|
// Format address
|
|
$address_parts = array();
|
|
if ($property->street_number) {
|
|
$address_parts[] = $property->street_number;
|
|
}
|
|
if ($property->street_name) {
|
|
$address_parts[] = $property->street_name;
|
|
}
|
|
if ($property->street_suffix) {
|
|
$address_parts[] = $property->street_suffix;
|
|
}
|
|
if ($property->unit_number) {
|
|
$address_parts[] = '#' . $property->unit_number;
|
|
}
|
|
$street_address = implode(' ', $address_parts);
|
|
|
|
$full_address = $street_address;
|
|
if ($property->city) {
|
|
$full_address .= ', ' . $property->city;
|
|
}
|
|
if ($property->state_or_province) {
|
|
$full_address .= ', ' . $property->state_or_province;
|
|
}
|
|
if ($property->postal_code) {
|
|
$full_address .= ' ' . $property->postal_code;
|
|
}
|
|
|
|
// Property URL
|
|
$property_url = home_url('/properties/?listing=' . $listing_key);
|
|
|
|
// Display message (shown to user - no MLS#)
|
|
$display_message = "Hello,\n\nI would like to get additional information on property " . $full_address . ".";
|
|
|
|
get_header();
|
|
?>
|
|
|
|
<main id="primary" class="site-main property-inquiry-page-main">
|
|
|
|
<?php
|
|
// Get inquiry page content from ACF
|
|
$hero_title = get_field('inquiry_hero_title') ?: 'Request Property Information';
|
|
$hero_subtitle = get_field('inquiry_hero_subtitle') ?: 'Get more details about this listing';
|
|
?>
|
|
<!-- Hero -->
|
|
<section class="archive-hero">
|
|
<div class="container">
|
|
<h1 class="archive-hero-title"><?php echo esc_html($hero_title); ?></h1>
|
|
<p class="archive-hero-subtitle"><?php echo esc_html($hero_subtitle); ?></p>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Inquiry Form Section -->
|
|
<section class="property-inquiry-section">
|
|
<div class="container">
|
|
<div class="property-inquiry-grid">
|
|
<!-- Form -->
|
|
<div class="property-inquiry-form-wrapper">
|
|
<?php
|
|
// Check for Contact Form 7
|
|
if (function_exists('wpcf7_contact_form')) {
|
|
$inquiry_form = get_page_by_title('Property Inquiry Form', OBJECT, 'wpcf7_contact_form');
|
|
if ($inquiry_form) {
|
|
echo do_shortcode('[contact-form-7 id="' . $inquiry_form->ID . '" title="Property Inquiry Form"]');
|
|
} else {
|
|
// Fallback form
|
|
?>
|
|
<form class="property-inquiry-form" action="" method="post">
|
|
<input type="hidden" name="listing-key" value="<?php echo esc_attr($listing_key); ?>">
|
|
<input type="hidden" name="listing-id" value="<?php echo esc_attr($listing_id); ?>">
|
|
<input type="hidden" name="property-address" value="<?php echo esc_attr($full_address); ?>">
|
|
<input type="hidden" name="property-price" value="<?php echo esc_attr($price); ?>">
|
|
<input type="hidden" name="property-url" value="<?php echo esc_attr($property_url); ?>">
|
|
<input type="hidden" name="agent-email" value="<?php echo esc_attr($homeproz_agent_email); ?>">
|
|
<input type="hidden" name="agent-name" value="<?php echo esc_attr($homeproz_agent_name); ?>">
|
|
<input type="hidden" name="default-message" value="">
|
|
|
|
<div class="form-group">
|
|
<label for="inquiry-message">Your Inquiry</label>
|
|
<textarea id="inquiry-message" rows="4" readonly class="readonly-message"><?php echo esc_textarea($display_message); ?></textarea>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="inquiry-name">Your Name <span class="required">*</span></label>
|
|
<input type="text" id="inquiry-name" name="name" required>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-row form-row-2col">
|
|
<div class="form-group">
|
|
<label for="inquiry-email">Email <span class="required">*</span></label>
|
|
<input type="email" id="inquiry-email" name="email" required>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="inquiry-phone">Phone <span class="required">*</span></label>
|
|
<input type="tel" id="inquiry-phone" name="phone" required>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="inquiry-comments">Additional Comments</label>
|
|
<textarea id="inquiry-comments" name="comments" rows="4" placeholder="Any specific questions or information you'd like to know..."></textarea>
|
|
</div>
|
|
|
|
<button type="submit" class="btn btn-primary btn-lg">Send Inquiry</button>
|
|
</form>
|
|
<?php
|
|
}
|
|
}
|
|
?>
|
|
</div>
|
|
|
|
<!-- Property Preview -->
|
|
<div class="property-inquiry-preview">
|
|
<?php $preview_title = get_field('inquiry_preview_title') ?: "Property You're Inquiring About"; ?>
|
|
<h3 class="preview-title"><?php echo esc_html($preview_title); ?></h3>
|
|
<?php
|
|
set_query_var('minimal_property', $property);
|
|
get_template_part('template-parts/property/property-card-minimal');
|
|
?>
|
|
|
|
<?php if ($homeproz_agent_id) : ?>
|
|
<?php
|
|
set_query_var('minimal_agent_id', $homeproz_agent_id);
|
|
get_template_part('template-parts/property/agent-card-minimal');
|
|
?>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
</main>
|
|
|
|
<script>
|
|
(function() {
|
|
var listingKey = <?php echo json_encode($listing_key); ?>;
|
|
var listingId = <?php echo json_encode($listing_id); ?>;
|
|
var propertyAddress = <?php echo json_encode($full_address); ?>;
|
|
var propertyUrl = <?php echo json_encode($property_url); ?>;
|
|
var thankYouUrl = <?php echo json_encode(home_url('/inquiry-thank-you/?listing=' . $listing_key)); ?>;
|
|
var displayMessage = <?php echo json_encode($display_message); ?>;
|
|
|
|
// Build submission message (includes MLS#, URL, and will include user comments)
|
|
function buildSubmissionMessage(userComments) {
|
|
var msg = "Hello,\n\nI would like to get additional information on property " + propertyAddress + " (MLS# " + listingId + ").\n\n";
|
|
msg += propertyUrl + "\n\n";
|
|
if (userComments && userComments.trim()) {
|
|
msg += "User Comments:\n\n" + userComments.trim();
|
|
}
|
|
return msg;
|
|
}
|
|
|
|
// Populate CF7 hidden fields if the form exists
|
|
var form = document.querySelector('.wpcf7-form');
|
|
if (form) {
|
|
var fields = {
|
|
'listing-key': listingKey,
|
|
'listing-id': listingId,
|
|
'property-address': propertyAddress,
|
|
'property-price': <?php echo json_encode(number_format($price)); ?>,
|
|
'property-url': propertyUrl,
|
|
'agent-email': <?php echo json_encode($homeproz_agent_email); ?>,
|
|
'agent-name': <?php echo json_encode($homeproz_agent_name); ?>
|
|
};
|
|
|
|
for (var name in fields) {
|
|
var input = form.querySelector('input[name="' + name + '"]');
|
|
if (input) {
|
|
input.value = fields[name];
|
|
}
|
|
}
|
|
|
|
// Populate the display textarea with the user-friendly message
|
|
var displayTextarea = form.querySelector('.readonly-message-display, .readonly-message');
|
|
if (displayTextarea) {
|
|
displayTextarea.textContent = displayMessage;
|
|
}
|
|
|
|
// Build and set the submission message before form submit
|
|
form.addEventListener('submit', function() {
|
|
var commentsField = form.querySelector('textarea[name="comments"]');
|
|
var userComments = commentsField ? commentsField.value : '';
|
|
var messageField = form.querySelector('input[name="default-message"]');
|
|
if (messageField) {
|
|
messageField.value = buildSubmissionMessage(userComments);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Handle fallback form submission message building
|
|
var fallbackForm = document.querySelector('.property-inquiry-form');
|
|
if (fallbackForm && !fallbackForm.classList.contains('wpcf7-form')) {
|
|
fallbackForm.addEventListener('submit', function() {
|
|
var commentsField = fallbackForm.querySelector('#inquiry-comments');
|
|
var userComments = commentsField ? commentsField.value : '';
|
|
var messageField = fallbackForm.querySelector('input[name="default-message"]');
|
|
if (messageField) {
|
|
messageField.value = buildSubmissionMessage(userComments);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Redirect to thank you page after successful CF7 submission
|
|
document.addEventListener('wpcf7mailsent', function(event) {
|
|
window.location.href = thankYouUrl;
|
|
}, false);
|
|
})();
|
|
</script>
|
|
|
|
<?php
|
|
get_footer();
|