WP Residence Help WP Residence Help

  • WpEstate
  • WPRESIDENCE
  • Video Tutorials
  • Client Support
  • API
Home / 29. WPResidence CRM / WPResidence CRM Enquiries — Developer Reference

WPResidence CRM Enquiries — Developer Reference

3 views 0

WPResidence CRM Enquiries — Developer Reference

This article documents how the Enquiries module is implemented in the WPResidence real estate CRM plugin. It covers the database table, the CRUD API, the AJAX endpoints, the auto-contact linking logic, status picklists, and the hooks you can use to extend the module.

All references are against plugin version 5.2.2 (wp-content/plugins/wpestate-crm/). Text domain: wpestate-crm.

Storage — wp_wpresidence_crm_enquiries

Enquiries are stored in a dedicated custom table — not as a CPT. The table is created in libs/db-setup.php around lines 128-161 via dbDelta.

Schema

Column Purpose
enquiry_id Primary key, auto-increment
user_id Owner (the agent the enquiry belongs to)
lead_id FK to wp_wpresidence_crm_leads (nullable)
contact_id FK to wp_wpresidence_crm_contacts
enquiry_type Picklist crm_enquiry_types
enquiry_status Picklist crm_enquiry_statuses
enquiry_source Phone / Walk-in / Email / Social Media / Referral / Other
enquiry_user_type Buyer / Seller / Tenant / Landlord / Investor / Other
enquiry_to Assigned recipient
enquiry_message Free-text message body
property_id FK to estate_property post ID (nullable)
property_type, property_status, property_city, property_area, property_country, property_state Denormalized property metadata
min_price, max_price, min_bedrooms, max_bedrooms, min_bathrooms, max_bathrooms, min_area_size, max_area_size Search criteria from the prospect
enquiry_meta longtext for JSON-encoded extra data
created_at, updated_at Timestamps with CURRENT_TIMESTAMP

Indexes

  • idx_lead_id on lead_id
  • idx_user_id on user_id
  • idx_status on enquiry_status

CRUD API

All functions live in libs/enquiry-crud.php. They accept and return plain arrays / objects; no CPT APIs are used.

Function Signature Purpose
wpestate_crm_insert_enquiry ($data) : int|WP_Error Insert a new row, return enquiry_id
wpestate_crm_get_enquiry ($enquiry_id) : object|null Fetch one row by ID
wpestate_crm_get_enquiries ($args) : array Fetch multiple rows with filters
wpestate_crm_update_enquiry ($enquiry_id, $data) : true|WP_Error Update a row
wpestate_crm_delete_enquiry ($enquiry_id) : true|WP_Error Delete a row
wpestate_crm_bulk_delete_enquiries ($ids) : int Delete many, return affected count
wpestate_crm_count_enquiries ($args) : int Count rows matching filters
wpestate_crm_sanitize_enquiry_data ($data) : array Whitelist + sanitize an input array

Accepted Arguments for get_enquiries()

  • user_id — ownership filter
  • status — enquiry_status value
  • enquiry_type
  • contact_id, lead_id
  • date_from, date_to — range on created_at
  • search — fuzzy match on enquiry_message, property_city, property_type
  • orderby — default created_at; allowed: enquiry_id, enquiry_status, enquiry_type, created_at, updated_at
  • order — ASC or DESC
  • limit — default 20
  • offset — for pagination

Sanitization

Every write path goes through wpestate_crm_sanitize_enquiry_data(). It applies sanitize_text_field(), sanitize_email(), and typed casts to numeric fields. Non-Latin input is preserved because sanitize_text_field() is UTF-8 safe.

Page Template — wpestate-crm-dashboard_enquiries.php

File: page-templates/wpestate-crm-dashboard_enquiries.php. The template has two modes selected by the enquiry_edit query parameter:

  • ?enquiry_edit=new — add form (edit_id = 0).
  • ?enquiry_edit={id} — edit form, pre-filled from wpestate_crm_get_enquiry().
  • No parameter — list view with pagination (crm_page query var, 20 per page).

The form partial is templates/crm_add_enquiry.php. Deletion is handled inline via a GET parameter delete_enquiry_id with a capability check, after which the template redirects back to the enquiries URL.

Scoping the List

Non-administrators pass their own user ID into get_enquiries() via user_id. Administrators omit the argument to see all rows. Scope is resolved with wpestate_return_agent_list() at the top of the template.

AJAX Endpoint — Save Enquiry

One AJAX action handles both create and update.

Property Value
Action name wpestate_crm_save_enquiry
Handler wpestate_crm_ajax_save_enquiry() — lines 357-428 of enquiry-crud.php
Nonce action wpestate_crm_save_enquiry
Nonce source in JS wpestate_crm_vars.nonces.save_enquiry
Capability wpestate_crm_user_can('contacts', 'create')
Form element #crm-enquiry-form
JS submit binding Lines 1588-1600 in js/crm-dashboard.js

Handler Flow

  1. Verify nonce (check_ajax_referer).
  2. Check capability; return JSON error on failure.
  3. Collect $_POST fields: enquiry_source, enquiry_type, enquiry_status, enquiry_user_type, enquiry_message, property_id, property_city, property_type, contact_name, contact_email, contact_phone.
  4. Call wpestate_crm_find_contact_by_email($email) (line 388).
  5. If the contact exists, attach its contact_id to the data payload. If not, call wpestate_crm_insert_contact() with the split name, email, phone, lead_source = enquiry_source, lifecycle_stage = 'new_lead', and attach the new ID.
  6. If enquiry_id > 0, call wpestate_crm_update_enquiry(). Otherwise call wpestate_crm_insert_enquiry().
  7. Return wp_send_json_success(['enquiry_id' => ...]) or wp_send_json_error().

Auto-Contact Linking

This is the key design decision for Enquiries: there is no explicit “convert” action. Every enquiry save runs the email-match pipeline, so by the time the row is written the contact_id column is always populated.

Status Picklist

Two settings in libs/settings.php drive the picklists:

  • crm_enquiry_statuses — default: "New, Open, Responded, Closed" (lines 41, 161).
  • crm_enquiry_types — default: "Property Enquiry, General Enquiry, Valuation Request, Viewing Request".

Both are stored as comma-separated strings in the CRM settings and are editable from the CRM Settings admin page. Add or rename values there — the form and filters pick up the changes automatically.

Form Template — crm_add_enquiry.php

File: templates/crm_add_enquiry.php. The template renders four sections (Enquiry Details, Contact Info, Property Details, Message) and includes two hidden fields:

  • enquiry_id — 0 for new, positive integer for edit (line 92).
  • property_id — populated by the property title autocomplete (line 96).
  • Nonce field uses action wpestate_crm_save_enquiry (line 100).

Permissions and Nonces

Operation Capability key Nonce action
Save enquiry wpestate_crm_user_can('contacts', 'create') wpestate_crm_save_enquiry
Delete enquiry wpestate_crm_user_can('enquiries', 'delete') WP nonce on the delete URL

The permissions matrix is defined per role in libs/permissions.php.

Notifications

Email notifications are rendered by wpestate_crm_resolve_placeholders() (libs/notifications.php lines 32-107), which supports 20 placeholders including {contact_name}, {contact_email}, {listing_title}, {agent_name}, {site_name}, and {crm_contact_url}.

Emails are wrapped by wpestate_crm_wrap_email_template() (lines 124-150), which uses templates/email_templates/base_email_template.php and respects the theme option wpestate_email_type (html or text).

Scheduled reminders fire from the cron events registered during activation — in particular wpestate_crm_daily_notifications and wpestate_crm_process_automations.

Integrations and Extensibility

  • HubSpot. Enquiry-created and contact-created events can push to HubSpot. See HubSpot CRM integration for WPResidence.
  • Webhooks. Outbound webhooks are dispatched from libs/webhook-functions.php.
  • Automations. 27 default rules are seeded at activation; rules with enquiry triggers run in the wpestate_crm_process_automations cron.
  • Extending fields. Store extra data in the enquiry_meta longtext column as JSON — no schema change required. Render it via the custom field renderer in libs/field-renderer.php.

Where to Read the Code

  • libs/db-setup.php — table creation (lines 128-161).
  • libs/enquiry-crud.php — CRUD and the save AJAX handler.
  • libs/settings.php — picklists for types and statuses.
  • libs/notifications.php — email placeholders and template wrapper.
  • page-templates/wpestate-crm-dashboard_enquiries.php — list + edit routing.
  • templates/crm_add_enquiry.php — the form partial.
  • js/crm-dashboard.js — form submission at lines 1588-1600.
29. WPResidence CRM

Related Articles

  • Managing Leads in the WPResidence CRM
  • WPResidence CRM Leads — Developer Reference
  • Managing Contacts in the WPResidence CRM
  • WPResidence CRM Contacts — Developer Reference

WP Residence Documentation

  • 01. Getting Started
    • How to Get Support
    • Get your buyer license code.
    • Use SSL / https
    • Server / Theme Requirements
  • 02. Installation & Setup
  • 03. Installation FAQ
  • 06. Search & Filtering
    • Advanced Search Display Settings
    • Advanced Search Form
    • Geolocation Search for Half Map
    • Save Search Theme Options
    • Advanced Search Colors
  • 09. Agent, Agency & Developers
  • 08. Property Pages & Layouts
  • 07. Property Lists, Categories & Archive
  • 13. WPResidence Elementor Studio
  • 10. Blog Posts & Blog List
  • 11. Shortcodes
    • Contact Form
    • Featured Agency/Developer
    • Membership Packages
    • Testimonials
    • Google Map with Property Marker
    • Listings per Agent, Agency or Developer
    • Display Categories
    • Agent List
    • Recent Items Slider
    • Recent items
    • List Properties or Articles by ID
    • Featured Agent
    • Featured Article
    • Featured Property
    • Login & Register Form
    • Icon Content Box Shortcode
  • 12. Widgets
  • 04. Theme Options & Global Settings
    • General Settings
    • User Types Settings
    • Appearance
    • Logos & Favicon
    • Header
    • Footer Style and Colors
    • Price & Currency
    • Property Custom Fields
    • Features & Amenities
    • Listing Labels
    • Theme Slider
    • Permalinks
    • Splash Page
    • Social & Contact
    • Map Settings
    • Pin Management
    • How read from file works
    • General Design Settings
    • Custom Colors Settings
    • Header Design & Colors
    • Mobile Menu Colors
    • User Dashboard Colors
    • Print PDF Design
    • Property, Agent, Blog Lists Design Settings
    • Sidebar Widget Design
    • Font management
    • How to add custom CSS
    • Custom Property Card Unit – Beta version
    • Email Management
    • Import & Export theme options
    • reCaptcha settings
    • YELP API Integration
    • iHomefinder Optima Express IDX
    • MEMBERSHIP & PAYMENT Settings
    • Property Submission Page
    • PayPal Setup
    • Stripe Setup
    • Wire Transfer Payment Method
  • 20. Translations & Languages
  • 26. FAQ
  • 10. Pages
  • 11. Header
  • 12. Footer
  • 05. Maps & Location Settings
  • 18. Payments & Monetization
  • Plugins
    • 19. Included Plugins
    • 22. Third Party Plugins – IDX Compatibility
    • 21. Third-Party Plugins – Multi-Language
    • 23. Third party Plugins – Other
  • Technical
    • 24. Technical how to | Custom Code Required
    • 25. Technical: Child Theme

Join Us On

Powered by WP Estate - All Rights Reserved
  • WpEstate
  • WPRESIDENCE
  • Video Tutorials
  • Client Support
  • API