Developer documentation for the viewed-listings tracker in the WPResidence real estate CRM. Lives in libs/viewed-functions.php.
Storage – wp_wpresidence_crm_viewed_listings
Columns: id (PK), contact_id, listing_id, viewed_at. No UNIQUE constraint, so multiple views are permitted. Indexes on contact_id, listing_id, and composite (contact_id, viewed_at).
Contact Resolution
wpestate_crm_resolve_contact_id() returns the current contact ID using:
- Cookie priority: reads wpestate_crm_contact_id cookie and validates the value exists in the contacts table.
- Logged-in user fallback: if the user is logged in, looks up a contact row by wp_user_id; if not found, then by user_id.
- Returns 0 if nothing resolves.
Cookie Setting
Set by libs/auto-create.php after a contact is created or matched by a form submission:
- Name: wpestate_crm_contact_id
- Lifetime: 1 year (YEAR_IN_SECONDS).
- Flags: HttpOnly, SameSite=Lax, Secure on HTTPS.
- Set only when HTTP headers have not been sent.
Tracking Hook
Registered on template_redirect:
wpestate_crm_track_viewed_listing()
Flow:
- If not on a single estate_property page, return.
- Resolve contact ID via wpestate_crm_resolve_contact_id(). If 0, return.
- Insert a row into wp_wpresidence_crm_viewed_listings.
- Record a viewed_listing activity via wpestate_crm_record_activity_v2() with meta: {listing_id, listing_title, listing_price}.
- Fire do_action(‘wpestate_crm_after_viewed_listing’, $contact_id, $listing_id).
Helpers
| Function | Returns |
|---|---|
| wpestate_crm_resolve_contact_id() | Current contact ID or 0 |
| wpestate_crm_get_viewed_count_by_contact($contact_id) | Int – total views for that contact |
AJAX Endpoint
| Action | Nonce |
|---|---|
| wpestate_crm_get_viewed_listings | wpestate_crm_nonce (security param) |
GET params: contact_id. Returns JSON with listings (array of objects with id, listing_id, title, thumbnail, price, viewed_at, permalink) and total.
Downstream Automation Hook
The wpestate_crm_after_viewed_listing action is consumed by the event-based dispatcher in libs/automations-cron.php. Default rule 26 (3+ views in 24 hours → create follow-up task) listens on this event and evaluates the computed viewed_listing_count_last_24h condition.
Retention
There is no automatic purging. For sites that care about GDPR minimization, add a cron job to delete rows older than N months. The table has a viewed_at index, so the delete can be done efficiently with DELETE FROM wp_wpresidence_crm_viewed_listings WHERE viewed_at < DATE_SUB(NOW(), INTERVAL N DAY).
Privacy & GDPR
The tracking cookie must be disclosed in the site’s privacy policy. Consider gating the cookie behind a consent banner in jurisdictions that require prior consent. Contact deletion requests should also purge viewed-listing rows keyed on the contact’s contact_id.
Extending
- To track non-property pages, add a similar hook on template_redirect for your custom post types and write rows into the same table, using listing_id to mean the entity ID of the viewed item.
- To add a session-level cookie instead of a persistent one, override the cookie write in a child plugin by running your logic earlier in the request lifecycle.