PluginProbe
MLSImport: IDX Plugin & MLS Plugin for Real Estate Listings / 7.2
MLSImport: IDX Plugin & MLS Plugin for Real Estate Listings v7.2
7.2.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 All 37 releases
← All changes | admin/partials/mlsimport-admin-fields-select.php +103 -175 6.3.57.2 View file →
@@ -1,193 +1,121 @@
1 -<?php
1 +<?php
2 +/**
3 + * Read-only renderer for the Field Configuration settings tab.
4 + *
5 + * Metadata gathering owns initialization and persistence. This partial only
6 + * checks connection state, asks the deep module for an in-memory normalized
7 + * view, and renders the active fields. There is deliberately no settings form,
8 + * options.php submission, pagination state, or browser-triggered initial save;
9 + * the JavaScript controller sends compact commands to the single AJAX seam.
10 + *
11 + * PER-CONNECTION SCOPE (multi-MLS): the Field Configuration is stored per
12 + * connection (#275). This tab addresses ONE connection, resolved by the shared
13 + * scope rule (includes/mlsimport-field-mapping-scope.php): ?mls=<id> when it
14 + * names a registered connection, the current connection otherwise. With 2+
15 + * connections a selector at the top switches the scope by reloading the page;
16 + * the resolved scope is exposed to the JS in the hidden #mlsimport_field_scope
17 + * input so every mutation and gather request stays on the same connection.
18 + *
19 + * Step by step:
20 + * 1. Resolve the scope and read that connection's populated flag.
21 + * 2. Gate on the global SaaS account token (the account is install-wide).
22 + * 3. Gate on the MLS connection: the CURRENT connection keeps the historic
23 + * global flag + refresh flow; a non-current scope uses its own record's
24 + * tested status (the global flag belongs to the current connection only).
25 + * 4. With 2+ connections, render the scope selector.
26 + * 5. Render the scoped configuration, or the "gathering" notice when the
27 + * scope's metadata is not populated yet.
28 + *
29 + * @package MLSImport
30 + * @subpackage MLSImport/admin/partials
31 + */
32 +
2 33 if ( ! defined( 'ABSPATH' ) ) {
3 - exit; // Exit if accessed directly
34 + exit;
4 35 }
5 -$theme_schema= mlsimport_hardocde_theme_schema();
6 36
7 -$options = get_option( 'mlsimport_admin_options' );
8 -$mlsimport_mls_metadata_populated = get_option( 'mlsimport_mls_metadata_populated', '' );
9 -$permited_tags = mlsimport_allowed_html_tags_content();
10 -$post_type = '';
11 -if (method_exists($this->env_data, 'get_property_post_type')) {
12 - $post_type = $this->env_data->get_property_post_type();
13 -}
37 +global $mlsimport;
14 38
15 -$available_taxonomies = mlsimport_get_custom_post_type_taxonomies($post_type);
39 +// Step 1: which connection is this tab editing? (?mls=<registered id> wins,
40 +// anything else resolves to the current connection.)
41 +$mlsimport_field_scope = mlsimport_field_mapping_request_scope( isset( $_GET['mls'] ) ? wp_unslash( $_GET['mls'] ) : null ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only view selector.
42 +$mlsimport_connections = Mlsimport_Connections::all();
43 +$mlsimport_scope_is_current = $mlsimport_field_scope === mlsimport_current_mls_id();
16 44
45 +$metadata_populated = mlsimport_get_connection_option( 'mlsimport_mls_metadata_populated', '', $mlsimport_field_scope );
46 +$token = $mlsimport->admin->mlsimport_saas_get_mls_api_token_from_transient();
17 47
18 -global $mlsimport;
19 -$token = $mlsimport->admin->mlsimport_saas_get_mls_api_token_from_transient();
20 -$is_mls_connected = get_option('mlsimport_connection_test', '');
48 +// Step 2: no SaaS account token — nothing on this tab can work.
21 49 $mlsimport->admin->mlsimport_saas_setting_up();
50 +if ( '' === trim( $token ) ) {
51 + // Names the reason (no subscription vs wrong password).
52 + echo mlsimport_account_not_connected_html(); // phpcs:ignore WordPress.Security.EscapeOutput -- escaped by the builder.
53 + return;
54 +}
22 55
23 -if ('yes' !== $is_mls_connected) {
24 - $mlsimport->admin->mlsimport_saas_check_mls_connection();
25 - $is_mls_connected = get_option('mlsimport_connection_test', '');
56 +// Step 3: the MLS-connected gate, per scope.
57 +if ( $mlsimport_scope_is_current ) {
58 + // Historic flow: refresh the global connection state before deciding.
59 + $is_mls_connected = get_option( 'mlsimport_connection_test', '' );
60 + if ( 'yes' !== $is_mls_connected ) {
61 + $mlsimport->admin->mlsimport_saas_check_mls_connection();
62 + $is_mls_connected = get_option( 'mlsimport_connection_test', '' );
63 + }
64 +} else {
65 + // A non-current connection answers from its own record (#277 status).
66 + $mlsimport_scope_record = Mlsimport_Connections::get( $mlsimport_field_scope );
67 + $is_mls_connected = is_array( $mlsimport_scope_record ) ? (string) ( $mlsimport_scope_record['status'] ?? '' ) : '';
26 68 }
27 69
28 -if (trim($token) === '') {
29 - echo '<div class="mlsimport_warning">' . esc_html__('You are not connected to MlsImport - Please check your Username and Password.', 'mlsimport') . '</div>';
30 - return;
70 +if ( 'yes' !== $is_mls_connected ) {
71 + echo '<div class="mlsimport_warning">' . esc_html__( 'The connection to your MLS was NOT succesful. Please check the authentication token is correct and check your MLS Data Access Application is approved.', 'mlsimport' ) . '</div>';
72 + return;
31 73 }
32 74
33 -if ('yes' !== $is_mls_connected) {
34 - echo '<div class="mlsimport_warning">' . esc_html__('The connection to your MLS was NOT succesful. Please check the authentication token is correct and check your MLS Data Access Application is approved.', 'mlsimport') . '</div>';
35 - return;
75 +// Step 4: with 2+ connections the user picks which MLS's fields to edit.
76 +if ( count( $mlsimport_connections ) > 1 ) {
77 + echo '<div class="mlsimport-field-scope">';
78 + echo '<label for="mlsimport-field-mls-scope">' . esc_html__( 'Editing fields for', 'mlsimport' ) . '</label> ';
79 + echo '<select id="mlsimport-field-mls-scope">';
80 + foreach ( $mlsimport_connections as $mlsimport_scope_option ) {
81 + $mlsimport_scope_id = (int) $mlsimport_scope_option['mls_id'];
82 + $mlsimport_scope_label = '' !== $mlsimport_scope_option['mls_name']
83 + ? $mlsimport_scope_option['mls_name']
84 + : __( 'MLS', 'mlsimport' ) . ' ' . $mlsimport_scope_id;
85 + printf(
86 + '<option value="%d"%s>%s</option>',
87 + esc_attr( $mlsimport_scope_id ),
88 + selected( $mlsimport_field_scope, $mlsimport_scope_id, false ),
89 + esc_html( $mlsimport_scope_label )
90 + );
91 + }
92 + echo '</select>';
93 + echo '</div>';
36 94 }
37 95
38 -if ( 'yes' === $mlsimport_mls_metadata_populated ) {
39 - // We have MLS metadata, so we can show the field selection interface
40 - ?>
41 - <form method="post" class= "mlsimport-import-fields-form" name="cleanup_options" action="options.php">
42 - <?php
43 -
44 -
45 - global $mlsimport;
46 - $mlsimport->admin->mlsimport_saas_setting_up();
47 -
48 -
49 - // Add this to the beginning of the form processing
50 - $options = get_option('mlsimport_admin_fields_select', array());
51 -
52 -
53 - // Ensure all arrays are initialized
54 - if (!is_array($options) ||
55 - (is_array($options) && empty($options)) ) {
96 +// Step 5: render the scoped configuration (or the gathering notice).
97 +if ( 'yes' === $metadata_populated ) {
98 + $metadata = mlsimport_field_configuration_metadata( $mlsimport_field_scope );
99 + $theme_schema = mlsimport_hardocde_theme_schema();
100 + $configuration = mlsimport_field_configuration( $mlsimport_field_scope )->read( $metadata, $theme_schema, mlsimport_field_configuration_taxonomies() );
56 101
57 - $mlsimport_mls_metadata_mls_data = get_option( 'mlsimport_mls_metadata_mls_data', '' );
58 - $metadata_api_call_data_service_property = json_decode( $mlsimport_mls_metadata_mls_data, true );
59 - $options = array();
60 -
61 -
62 -
63 - if (!isset($options['mls-fields'])) {
64 - $options['mls-fields'] = array();
65 - }
66 -
67 - if (!isset($options['mls-fields-admin'])) {
68 - $options['mls-fields-admin'] = array();
69 - }
70 -
71 - if (!isset($options['mls-fields-label'])) {
72 - $options['mls-fields-label'] = array();
73 - }
74 -
75 - if (!isset($options['mls-fields-map-postmeta'])) {
76 - $options['mls-fields-map-postmeta'] = array();
77 - }
78 -
79 - if (!isset($options['mls-fields-map-taxonomy'])) {
80 - $options['mls-fields-map-taxonomy'] = array();
81 - }
82 -
83 -
84 - $order_item=0;
85 - if (!is_array($metadata_api_call_data_service_property)) {
86 - $metadata_api_call_data_service_property = [];
87 - }
88 -
89 - ksort($metadata_api_call_data_service_property);
90 -
91 - foreach ( $metadata_api_call_data_service_property as $key => $value ) {
92 - $description = 'no description ';
93 -
94 - $options['mls-fields'][ $key ]=0;
95 - $options['field_order'][ $key ]=$order_item++;
96 - $options['mls-fields-admin'][ $key ]=0 ;
97 - $options['mls-fields-map-postmeta'][ $key ]='';
98 -
99 - $options['mls-fields-label'][ $key ]='';
100 -
101 - if ( array_key_exists( $key, $theme_schema ) ) {
102 - $options['mls-fields'][ $key ]=1;
103 -
104 - if( isset( $theme_schema[$key]['type']) && $theme_schema[$key]['type']=='taxonomy' ){
105 - $options['mls-fields-map-taxonomy'][ $key ]=$theme_schema[$key]['name'];
106 - }else{
107 - $options['mls-fields-map-taxonomy'][ $key ]='';
108 - }
109 -
110 - }
111 - }
112 -
113 -
114 - }
115 -
116 - ?>
117 -
118 -
119 -
120 - <h3><?php esc_html_e( 'Select the extra fields you want to import', 'mlsimport' ); ?>:</h3>
121 -
122 - <?php
123 -
124 -
125 - // $options = get_option( 'mlsimport_admin_fields_select', array() );
126 - // print_r($options);
127 -
128 -
129 -
130 - // Get the current page and search parameters
131 - $current_page = isset( $_GET['mlsimport_page'] ) ? intval( $_GET['mlsimport_page'] ) : 1;
132 - $search_term = isset( $_GET['mlsimport_search'] ) ? sanitize_text_field( $_GET['mlsimport_search'] ) : '';
133 - $import_filter = isset( $_GET['mlsimport_filter'] ) ? sanitize_text_field( $_GET['mlsimport_filter'] ) : 'all';
134 - $alpha_filter = isset( $_GET['mlsimport_alpha'] ) ? sanitize_text_field( $_GET['mlsimport_alpha'] ) : '';
135 -
136 - // Set up render parameters
137 - $render_params = array(
138 - 'page' => $current_page,
139 - 'fields_per_page' => 99999, // Adjust as needed
140 - 'search_term' => $search_term,
141 - 'import_filter' => $import_filter,
142 - 'alpha_filter' => $alpha_filter,
143 - 'show_pagination' => true,
144 - 'show_filters' => true,
145 - 'show_stats' => true,
146 - 'enable_drag_drop' => true,
147 - 'form_action' => 'options.php',
148 - 'form_method' => 'post',
149 - 'form_name' => 'cleanup_options',
150 - 'nonce_field' => 'mlsimport_admin_fields_select',
151 - 'plugin_name' => 'mlsimport',
152 - );
153 -
154 -
155 -
156 -
157 -
158 -
159 -
160 -
161 - // Then in the admin page, update the function call:
162 - echo render_mls_field_selection_interface(
163 - $options,
164 - $options,
165 - $render_params,
166 - $theme_schema
167 - );
168 - ?>
169 -
170 - <input type="hidden" name="mlsimport_admin_fields_select[mls-fields-admin][force_rand]" value="<?php echo esc_attr( wp_rand() ); ?>">
171 -
172 -
173 - <?php mlsimport_add_field_selector_nonce(); ?>
174 - </form>
175 - <?php
102 + echo '<h3>' . esc_html__( 'Select the extra fields you want to import', 'mlsimport' ) . ':</h3>';
103 + echo render_mls_field_selection_interface(
104 + $metadata,
105 + $configuration,
106 + array(
107 + 'search_term' => '',
108 + 'import_filter' => 'all',
109 + 'show_filters' => true,
110 + 'show_stats' => true,
111 + 'enable_drag_drop' => true,
112 + 'plugin_name' => 'mlsimport',
113 + ),
114 + $theme_schema
115 + );
176 116 } else {
177 - // We don't have MLS metadata yet, show waiting message
178 - global $mlsimport;
179 - $token = $mlsimport->admin->mlsimport_saas_get_mls_api_token_from_transient();
180 - if ( trim( $token ) !== '' ) {
181 - ?>
182 - <div class="mlsimport_warning mlsimport_validated">
183 - <?php
184 - esc_html_e( 'We need to gather some information about your MLS. Please Stand By! ', 'mlsimport' );
185 - ?>
186 - </div>
187 - <?php
188 - } else {
189 - esc_html_e( 'You are not connected to MLS Import', 'mlsimport' );
190 - }
117 + echo '<div class="mlsimport_warning mlsimport_validated">' . esc_html__( 'We need to gather some information about your MLS. Please Stand By! ', 'mlsimport' ) . '</div>';
191 118 }
192 119 ?>
193 -<input type="hidden" id="mlsimport_saas_get_metadata" value="<?php echo esc_attr( wp_create_nonce( "mlsimport_saas_get_metadata" ) ); ?>" />
120 +<input type="hidden" id="mlsimport_field_scope" value="<?php echo esc_attr( (string) $mlsimport_field_scope ); ?>">
121 +<input type="hidden" id="mlsimport_saas_get_metadata" value="<?php echo esc_attr( wp_create_nonce( 'mlsimport_saas_get_metadata' ) ); ?>">