PluginProbe
MLSImport: IDX Plugin & MLS Plugin for Real Estate Listings / 7.2.1
MLSImport: IDX Plugin & MLS Plugin for Real Estate Listings v7.2.1
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 / templates / search-form.php

search-form.php in MLSImport: IDX Plugin & MLS Plugin for Real Estate Listings 7.2.1, at templates/search-form.php

100 lines 5.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Standalone listings search form. Theme-overridable: copy to your theme's
4 * mlsimport/search-form.php. Field name attributes map 1:1 to filter params.
5 * Receives $args (current filter values) for pre-filling.
6 *
7 * @package Mlsimport
8 */
9
10 if ( ! defined( 'ABSPATH' ) ) {
11 exit;
12 }
13
14 // Current filter values passed in for pre-filling; default to an empty set.
15 $mli_args = isset( $args ) && is_array( $args ) ? $args : array();
16 // Helper: return a single scalar arg as a string (array-valued args yield '').
17 $mli_val = function ( $key ) use ( $mli_args ) {
18 return isset( $mli_args[ $key ] ) && ! is_array( $mli_args[ $key ] ) ? (string) $mli_args[ $key ] : '';
19 };
20
21 // Field visibility (the listings block/shortcode's per-field on/off toggles): null
22 // means show every field (default), else only the listed keys appear. Keywords and
23 // Sort gate on their own keys; each catalog field gates on its catalog key.
24 $mli_visible = class_exists( 'Mlsimport_Standalone_Render' ) ? Mlsimport_Standalone_Render::visible_fields( $mli_args ) : null;
25 // Helper: is this field visible? null visibility means show everything.
26 $mli_show = function ( $key ) use ( $mli_visible ) {
27 return null === $mli_visible || in_array( $key, $mli_visible, true );
28 };
29
30 // Search fields per row (the listings/half-map "fields per row" setting): a CSS
31 // custom property the stylesheet turns into the grid column count. Unset/invalid
32 // emits nothing, so the listings/half-map CSS fallback column count applies.
33 $mli_cols = function_exists( 'mlsimport_search_cols_style' ) ? mlsimport_search_cols_style( $mli_val( 'fields_per_row' ) ) : '';
34 ?>
35 <form class="mlsimport-search" role="search"<?php echo $mli_cols; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- integer CSS var built internally. ?>>
36 <?php if ( $mli_show( 'keywords' ) ) : /* free-text keywords input, gated on its own key */ ?>
37 <label class="mlsimport-search__field">
38 <?php esc_html_e( 'Keywords', 'mlsimport' ); ?>
39 <input type="text" name="keywords" value="<?php echo esc_attr( $mli_val( 'keywords' ) ); ?>" placeholder="<?php esc_attr_e( 'Pool, lake view…', 'mlsimport' ); ?>">
40 </label>
41 <?php endif; ?>
42
43 <?php
44 // Every searchable field — taxonomies then fast-table columns (no geo) — from
45 // the shared catalog, so this form and the Search Form block never drift.
46 if ( class_exists( 'Mlsimport_Page_Block_Search_Fields' ) && function_exists( 'mlsimport_render_search_field' ) ) {
47 // An explicit selection also sets the ORDER, so a form can lead with the fields
48 // that matter to this site — e.g. a hero search offering Location, Type and
49 // Price should hand the visitor those same three first on the results page.
50 // Without a selection the shared catalog order applies (taxonomies, then
51 // fast-table columns), which is the long-standing default.
52 $mli_order = null !== $mli_visible
53 ? $mli_visible
54 : Mlsimport_Page_Block_Search_Fields::catalog();
55 foreach ( $mli_order as $mli_field ) {
56 // Skip fields toggled off for this form.
57 if ( ! $mli_show( $mli_field ) ) {
58 continue;
59 }
60 // Fetch the field's definition; render it when the catalog knows the field.
61 $mli_def = Mlsimport_Page_Block_Search_Fields::definition( $mli_field );
62 if ( null !== $mli_def ) {
63 echo mlsimport_render_search_field( $mli_def, $mli_args, '', 'mlsimport-search__field' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- escaped within.
64 }
65 }
66 }
67 ?>
68
69 <?php
70 // Sort is NOT a filter field: it renders in the results toolbar (count left /
71 // sort right) above the grid — see Mlsimport_Standalone_Render::render_grid(). It
72 // still drives the same AJAX repaint; mlsimport-listings.js reads its
73 // select[name="orderby"] from the toolbar, outside this form.
74
75 // Carry every ACTIVE filter that has no visible field as a hidden input.
76 //
77 // This form is the AJAX layer's only state: mlsimport-listings.js builds the request
78 // from its FormData and nothing else. So a filter that is not re-submitted here is
79 // DROPPED the first time the visitor refines or paginates — page 1 is server-rendered
80 // and looks right, page 2 silently widens. That is reachable whenever a block sets an
81 // initial-filter preset whose search field is switched off ("Miami condos", where the
82 // City field is hidden so visitors cannot change it) or has no search field at all
83 // (the map box). It used to be patched one key at a time — `limit` and `agent` each had
84 // their own hardcoded input — which fixed those two and left every other filter broken.
85 //
86 // One rule instead: a filter is either editable in the bar, or it rides along hidden.
87 // For each active-but-not-editable filter, emit hidden input(s) so it rides along on submit.
88 foreach ( mlsimport_search_form_hidden_args( $mli_args, $mli_visible ) as $mli_name => $mli_value ) :
89 // Multi-value filters (arrays) get one hidden input per value.
90 foreach ( (array) $mli_value as $mli_item ) :
91 ?>
92 <input type="hidden" name="<?php echo esc_attr( $mli_name ); ?>" value="<?php echo esc_attr( (string) $mli_item ); ?>">
93 <?php
94 endforeach;
95 endforeach;
96 ?>
97
98 <button type="submit" class="mlsimport-search__submit"><?php esc_html_e( 'Search', 'mlsimport' ); ?></button>
99 </form>
100