PluginProbe
MLSImport: IDX Plugin & MLS Plugin for Real Estate Listings / 7.1.2
MLSImport: IDX Plugin & MLS Plugin for Real Estate Listings v7.1.2
7.2.1 7.2 7.1.2 7.1.1 7.1 7.0.4 7.0.6 7.0.7 6.3.8 6.3.7 6.3.6 6.3.5 6.3.4 6.3.3 6.3.1 trunk 5.7.3 5.7.5 5.8.1 5.8.2 5.8.3 5.8.4 5.8.6 6.0.4 6.0.5 All 36 releases
mlsimport / includes / standalone / listing-card.php

listing-card.php in MLSImport: IDX Plugin & MLS Plugin for Real Estate Listings 7.1.2, at includes/standalone/listing-card.php

92 lines 4.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Standalone (theme_id 990) listing-card view model + hook surface.
4 *
5 * Every property grid renders through Mlsimport_Standalone_Render::render_cards(),
6 * which picks the card template (v1/v2/v3) via mlsimport_standalone_card_template().
7 * Each card template builds its data once from this one helper, so the three
8 * designs stay consistent and a new card design is a thin template, not a new data
9 * pass. The card action slots below are the WooCommerce-style extension points
10 * fired inside every card template.
11 *
12 * Card action slots (each fired with ( WP_Post $post, object|null $row )):
13 * action mlsimport_card_before — just after <article> opens (ribbons/badges)
14 * action mlsimport_card_after_media — direct child of <article>, after the media/link
15 * (favorite heart, gallery count); positioned over
16 * the photo via CSS, so it sits OUTSIDE the card's
17 * <a> link and fires on thumbnail-less cards too
18 * action mlsimport_card_body_start — top of the card body
19 * action mlsimport_card_body_end — bottom of the card body (CTA buttons)
20 * action mlsimport_card_after — just before </article> closes
21 * Filter:
22 * filter mlsimport_card_view ( array $view, WP_Post $post, object|null $row )
23 *
24 * @package Mlsimport
25 */
26
27 if ( ! defined( 'ABSPATH' ) ) {
28 exit;
29 }
30
31 /**
32 * Build one listing card's view model from the post + its listings row. Pulls the
33 * clean RESO address, formatted price, spec line, status and agency, so the card
34 * templates only lay out — they don't re-derive.
35 *
36 * @param WP_Post $post The listing post.
37 * @param object|null $row The mlsimport_listings row (searchable scalars).
38 * @return array
39 */
40 function mlsimport_card_view( $post, $row ): array {
41 // Cast the post ID once for the meta/permalink/thumbnail lookups below.
42 $pid = (int) $post->ID;
43
44 // Address: the clean RESO UnparsedAddress is the heading; the raw post title
45 // (often an importer concatenation) is only the fallback.
46 $address = trim( (string) get_post_meta( $pid, 'mlsimport_UnparsedAddress', true ) );
47 if ( '' === $address ) {
48 $address = get_the_title( $pid );
49 }
50
51 // Price: keep null when the row has none; otherwise format as "$ 1,234,567".
52 $price = ( isset( $row->price ) && null !== $row->price && '' !== $row->price ) ? (float) $row->price : null;
53 $price_fmt = null !== $price ? '$ ' . number_format( $price ) : '';
54
55 // Spec line: only the parts present.
56 $specs = array();
57 // Beds — pluralized; drop the decimal for whole numbers.
58 if ( isset( $row->bedrooms ) && null !== $row->bedrooms && '' !== $row->bedrooms ) {
59 $b = (float) $row->bedrooms;
60 $specs[] = sprintf( _n( '%s bed', '%s beds', (int) ceil( $b ), 'mlsimport' ), number_format_i18n( $b, ( $b === (float) (int) $b ) ? 0 : 1 ) );
61 }
62 // Baths — pluralized; drop the decimal for whole numbers.
63 if ( isset( $row->bathrooms ) && null !== $row->bathrooms && '' !== $row->bathrooms ) {
64 $ba = (float) $row->bathrooms;
65 $specs[] = sprintf( _n( '%s bath', '%s baths', (int) ceil( $ba ), 'mlsimport' ), number_format_i18n( $ba, ( $ba === (float) (int) $ba ) ? 0 : 1 ) );
66 }
67 // Living area — formatted number plus the ft² unit.
68 if ( isset( $row->living_area ) && null !== $row->living_area && '' !== $row->living_area ) {
69 $specs[] = number_format_i18n( (float) $row->living_area ) . ' ' . __( 'ft²', 'mlsimport' );
70 }
71
72 // Assemble the view model the card templates lay out (no further deriving).
73 $view = array(
74 'id' => $pid,
75 'permalink' => (string) get_permalink( $pid ),
76 'address' => $address,
77 'price' => $price,
78 'price_fmt' => $price_fmt,
79 'status' => isset( $row->status ) ? trim( (string) $row->status ) : '',
80 'specs' => $specs,
81 'office' => trim( (string) get_post_meta( $pid, 'mlsimport_ListOfficeName', true ) ),
82 'logo' => function_exists( 'mlsimport_standalone_mls_logo_url' ) ? mlsimport_standalone_mls_logo_url() : '',
83 'has_thumb' => has_post_thumbnail( $pid ),
84 // Photo URL for the card media — rendered as a CSS background-image (never an
85 // <img>), the same convention as the map/featured cards.
86 'thumb' => has_post_thumbnail( $pid ) ? (string) get_the_post_thumbnail_url( $pid, 'large' ) : '',
87 );
88
89 /** Filter one card's view model before the template lays it out. @since 6.4 */
90 return (array) apply_filters( 'mlsimport_card_view', $view, $post, $row );
91 }
92