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 / class-mlsimport-term-select.php

class-mlsimport-term-select.php in MLSImport: IDX Plugin & MLS Plugin for Real Estate Listings 7.1.2, at includes/standalone/class-mlsimport-term-select.php

151 lines 5.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Reusable searchable multi-select for picking terms from a plugin taxonomy.
4 *
5 * Anywhere the plugin needs the operator to pick one or more terms from a
6 * registered taxonomy (the standalone mlsimport_* taxonomies, or any other),
7 * render this instead of hand-rolling a <select>. It emits the same markup the
8 * Import Task City/County picker already uses — a chip row, a live filter input,
9 * and a native <select multiple> — so the existing mlsimport-searchable-select.js
10 * behaviour (live filter, click-to-toggle without Ctrl, removable chips) and the
11 * styles in mlsimport-admin.css apply with nothing new to ship.
12 *
13 * The native <select multiple> is the source of truth: it submits the usual
14 * name[]-array payload, so save handlers read $_POST[ name ] as an array.
15 *
16 * @package Mlsimport
17 */
18
19 if ( ! defined( 'ABSPATH' ) ) {
20 exit;
21 }
22
23 /**
24 * Renders a searchable, chip-backed multi-select of a taxonomy's terms.
25 */
26 class Mlsimport_Term_Select {
27
28 /**
29 * Handle for the shared dropdown multi-select component (the same one the
30 * standalone front-end search form uses).
31 */
32 const SCRIPT_HANDLE = 'mlsimport-multiselect';
33
34 /**
35 * Ensure the dropdown multi-select component (JS + CSS) is enqueued. Idempotent
36 * — call it from any screen that renders a term select.
37 *
38 * @return void
39 */
40 public static function enqueue(): void {
41 // Plugin base URL + version for cache-busting (constants when the plugin booted).
42 $base = defined( 'MLSIMPORT_PLUGIN_URL' ) ? MLSIMPORT_PLUGIN_URL : plugin_dir_url( dirname( __DIR__ ) . '/mlsimport.php' );
43 $ver = defined( 'MLSIMPORT_VERSION' ) ? MLSIMPORT_VERSION : false;
44
45 // Register the shared JS/CSS once (guarded so repeated calls don't re-register).
46 if ( ! wp_script_is( self::SCRIPT_HANDLE, 'registered' ) ) {
47 wp_register_script( self::SCRIPT_HANDLE, $base . 'public/js/mlsimport-multiselect.js', array(), $ver, true );
48 }
49 if ( ! wp_style_is( self::SCRIPT_HANDLE, 'registered' ) ) {
50 wp_register_style( self::SCRIPT_HANDLE, $base . 'public/css/mlsimport-multiselect.css', array(), $ver );
51 }
52 // Enqueue the component's assets for this request.
53 wp_enqueue_script( self::SCRIPT_HANDLE );
54 wp_enqueue_style( self::SCRIPT_HANDLE );
55 }
56
57 /**
58 * Build the term multi-select as an escaped HTML string (the caller echoes it).
59 *
60 * @param array $args {
61 * @type string $taxonomy Required. Taxonomy slug to list terms from.
62 * @type string $name Required. Field name; submitted as name[].
63 * @type array $selected Currently-selected values (term IDs, or slugs
64 * when value_field is 'slug'). Default array().
65 * @type string $label Optional label shown above the control.
66 * @type string $value_field Option value: 'term_id' (default), 'slug' or 'name'.
67 * @type string $placeholder Empty-state text shown on the control.
68 * @type string $id Select id (auto-derived when omitted).
69 * }
70 * @return string Escaped markup, or '' when the taxonomy/name is invalid.
71 */
72 public static function render( array $args ): string {
73 $args = wp_parse_args(
74 $args,
75 array(
76 'taxonomy' => '',
77 'name' => '',
78 'selected' => array(),
79 'label' => '',
80 'value_field' => 'term_id',
81 'placeholder' => __( 'Any', 'mlsimport' ),
82 'id' => '',
83 )
84 );
85
86 // Required args must be present and the taxonomy real, else render nothing.
87 $taxonomy = (string) $args['taxonomy'];
88 $name = (string) $args['name'];
89 if ( '' === $taxonomy || '' === $name || ! taxonomy_exists( $taxonomy ) ) {
90 return '';
91 }
92
93 // Pull every term (including empty ones) to build the option list.
94 $terms = get_terms(
95 array(
96 'taxonomy' => $taxonomy,
97 'hide_empty' => false,
98 )
99 );
100 // No terms (or a lookup error): nothing to select from.
101 if ( is_wp_error( $terms ) || empty( $terms ) ) {
102 return '';
103 }
104
105 // Which term property becomes the option value (default term_id); coerce the
106 // selected values to strings for the in_array comparison below.
107 $value_field = in_array( $args['value_field'], array( 'slug', 'name' ), true ) ? $args['value_field'] : 'term_id';
108 $selected = array_map( 'strval', (array) $args['selected'] );
109 // Caller-supplied id, or a stable one derived from taxonomy + field name.
110 $id = '' !== $args['id'] ? (string) $args['id'] : 'mlsimport-term-select-' . sanitize_html_class( $taxonomy . '-' . $name );
111
112 // Buffer the markup so the method can return it as a string.
113 ob_start();
114 ?>
115 <div class="mlsimport-term-select">
116 <?php if ( '' !== (string) $args['label'] ) : ?>
117 <label for="<?php echo esc_attr( $id ); ?>"><?php echo esc_html( (string) $args['label'] ); ?></label>
118 <?php endif; ?>
119 <select
120 class="mlsimport-multiselect"
121 id="<?php echo esc_attr( $id ); ?>"
122 name="<?php echo esc_attr( $name ); ?>[]"
123 multiple
124 data-placeholder="<?php echo esc_attr( (string) $args['placeholder'] ); ?>"
125 >
126 <?php
127 // One <option> per term; its value comes from the chosen value_field.
128 foreach ( $terms as $term ) {
129 if ( 'slug' === $value_field ) {
130 $value = (string) $term->slug;
131 } elseif ( 'name' === $value_field ) {
132 $value = (string) $term->name;
133 } else {
134 $value = (string) $term->term_id;
135 }
136 // Mark the option selected when its value is in the selected set.
137 printf(
138 '<option value="%s"%s>%s</option>',
139 esc_attr( $value ),
140 selected( in_array( $value, $selected, true ), true, false ),
141 esc_html( $term->name )
142 );
143 }
144 ?>
145 </select>
146 </div>
147 <?php
148 return (string) ob_get_clean();
149 }
150 }
151