| 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 |
|
| 33 |
if ( ! defined( 'ABSPATH' ) ) { |
| 34 |
exit; |
| 35 |
} |
| 36 |
|
| 37 |
global $mlsimport; |
| 38 |
|
| 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(); |
| 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(); |
| 47 |
|
| 48 |
// Step 2: no SaaS account token — nothing on this tab can work. |
| 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 |
} |
| 55 |
|
| 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'] ?? '' ) : ''; |
| 68 |
} |
| 69 |
|
| 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; |
| 73 |
} |
| 74 |
|
| 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>'; |
| 94 |
} |
| 95 |
|
| 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() ); |
| 101 |
|
| 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 |
); |
| 116 |
} else { |
| 117 |
echo '<div class="mlsimport_warning mlsimport_validated">' . esc_html__( 'We need to gather some information about your MLS. Please Stand By! ', 'mlsimport' ) . '</div>'; |
| 118 |
} |
| 119 |
?> |
| 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' ) ); ?>"> |
| 122 |
|