opens (ribbons) * action mlsimport_card_badges — inside the badge row over the photo, after the * status badge. The plugin's own "Featured" flag * hooks here (mlsimport_card_featured_flag(), 10). * action mlsimport_card_after_media — direct child of
, after the media/link * (favorite heart, gallery count); positioned over * the photo via CSS, so it sits OUTSIDE the card's * link and fires on thumbnail-less cards too * action mlsimport_card_body_start — top of the card body * action mlsimport_card_body_end — bottom of the card body (CTA buttons) * action mlsimport_card_after — just before
closes * Filter: * filter mlsimport_card_view ( array $view, WP_Post $post, object|null $row ) * * @package Mlsimport */ if ( ! defined( 'ABSPATH' ) ) { exit; } /** * Build one listing card's view model from the post + its listings row. Pulls the * clean RESO address, formatted price, spec line, status and agency, so the card * templates only lay out — they don't re-derive. * * @param WP_Post $post The listing post. * @param object|null $row The mlsimport_listings row (searchable scalars). * @return array */ function mlsimport_card_view( $post, $row ): array { // Cast the post ID once for the meta/permalink/thumbnail lookups below. $pid = (int) $post->ID; // Address: the clean RESO UnparsedAddress is the heading; the raw post title // (often an importer concatenation) is only the fallback. $address = trim( (string) get_post_meta( $pid, 'mlsimport_UnparsedAddress', true ) ); if ( '' === $address ) { $address = get_the_title( $pid ); } // Price: keep null when the row has none; otherwise format as "$ 1,234,567". $price = ( isset( $row->price ) && null !== $row->price && '' !== $row->price ) ? (float) $row->price : null; $price_fmt = null !== $price ? '$ ' . number_format( $price ) : ''; // Spec line: only the parts present. $specs = array(); // Beds — pluralized; drop the decimal for whole numbers. if ( isset( $row->bedrooms ) && null !== $row->bedrooms && '' !== $row->bedrooms ) { $b = (float) $row->bedrooms; $specs[] = sprintf( _n( '%s bed', '%s beds', (int) ceil( $b ), 'mlsimport' ), number_format_i18n( $b, ( $b === (float) (int) $b ) ? 0 : 1 ) ); } // Baths — pluralized; drop the decimal for whole numbers. if ( isset( $row->bathrooms ) && null !== $row->bathrooms && '' !== $row->bathrooms ) { $ba = (float) $row->bathrooms; $specs[] = sprintf( _n( '%s bath', '%s baths', (int) ceil( $ba ), 'mlsimport' ), number_format_i18n( $ba, ( $ba === (float) (int) $ba ) ? 0 : 1 ) ); } // Living area — formatted number plus the ft² unit. if ( isset( $row->living_area ) && null !== $row->living_area && '' !== $row->living_area ) { $specs[] = number_format_i18n( (float) $row->living_area ) . ' ' . __( 'ft²', 'mlsimport' ); } // Assemble the view model the card templates lay out (no further deriving). $view = array( 'id' => $pid, 'permalink' => (string) get_permalink( $pid ), 'address' => $address, 'price' => $price, 'price_fmt' => $price_fmt, 'status' => isset( $row->status ) ? trim( (string) $row->status ) : '', 'specs' => $specs, 'office' => trim( (string) get_post_meta( $pid, 'mlsimport_ListOfficeName', true ) ), 'logo' => function_exists( 'mlsimport_standalone_mls_logo_url' ) ? mlsimport_standalone_mls_logo_url() : '', 'has_thumb' => has_post_thumbnail( $pid ), // Photo URL for the card media — rendered as a CSS background-image (never an // ), the same convention as the map/featured cards. 'thumb' => has_post_thumbnail( $pid ) ? (string) get_the_post_thumbnail_url( $pid, 'large' ) : '', ); /** Filter one card's view model before the template lays it out. @since 6.4 */ return (array) apply_filters( 'mlsimport_card_view', $view, $post, $row ); } /** * Print the "Featured" flag on a featured listing's card (issue #288). * * Hooked on mlsimport_card_badges, which all three card templates fire in the * badge row over the photo, so the flag sits inline after the status badge. The flag is read from the listings row ($row->featured, copied * from the "Featured listing" checkbox by Mlsimport_Standalone_Row::upsert()), * which costs no extra query. A card with no row (live passthrough mode) or an * unfeatured listing prints nothing. * * @param WP_Post $post The property post. * @param object|null $row The mlsimport_listings row, or null. * @return void */ function mlsimport_card_featured_flag( $post, $row ): void { // Step 1: only a featured listing gets the flag. if ( empty( $row->featured ) ) { return; } // Step 2: same look as the Featured Property block's flag, plus a card-specific // class that styles it like the status badge beside it (mlsimport-listings.css). $html = '' . esc_html__( 'Featured', 'mlsimport' ) . ''; /** Filter the card's "Featured" flag markup ('' hides it). @since 7.2.2 */ echo wp_kses_post( (string) apply_filters( 'mlsimport_card_featured_flag', $html, $post, $row ) ); } add_action( 'mlsimport_card_badges', 'mlsimport_card_featured_flag', 10, 2 );