| 1 |
<?php |
| 2 |
/** |
| 3 |
* Which supported mode is this site running in? |
| 4 |
* |
| 5 |
* The plugin writes imported listings through one adapter per supported theme, |
| 6 |
* selected by a numeric theme id (see Mlsimport_Stored_Listing_Adapter_Factory): |
| 7 |
* |
| 8 |
* 990 - Standalone: the plugin's own CPTs/taxonomies, works with ANY theme. |
| 9 |
* 991 - WpResidence 992 - Houzez 993 - Real Homes 994 - Wpestate |
| 10 |
* |
| 11 |
* That id is stored in mlsimport_admin_options['mlsimport_theme_used'] and is |
| 12 |
* normally picked by the user in the setup wizard. This file answers the same |
| 13 |
* question BEFORE the user has picked anything, so the wizard can stop asking |
| 14 |
* for information the site already knows and stop treating an unrecognised |
| 15 |
* theme as a broken system (issue #243). |
| 16 |
* |
| 17 |
* The key point: there is no "unsupported" outcome. A site whose theme is not |
| 18 |
* one of the four real-estate themes is not deficient - it is a standalone |
| 19 |
* site, which is a first-class shipped mode. |
| 20 |
* |
| 21 |
* @link https://mlsimport.com/ |
| 22 |
* @since 7.0.0 |
| 23 |
* |
| 24 |
* @package Mlsimport |
| 25 |
* @subpackage Mlsimport/includes |
| 26 |
*/ |
| 27 |
|
| 28 |
// If this file is called directly, abort. |
| 29 |
if ( ! defined( 'ABSPATH' ) ) { |
| 30 |
exit; |
| 31 |
} |
| 32 |
|
| 33 |
/** |
| 34 |
* Map of parent-theme directory slugs to their supported theme id. |
| 35 |
* |
| 36 |
* Keyed on the DIRECTORY slug (what get_template() returns), not on the theme's |
| 37 |
* display Name: the directory is stable, while the Name is editable in |
| 38 |
* style.css and is routinely changed by whitelabel resellers. Using the parent |
| 39 |
* directory also means child themes ("houzez-child") resolve to their parent |
| 40 |
* for free, because get_template() always returns the parent. |
| 41 |
* |
| 42 |
* @return array<string,int> Lowercase theme directory slug => theme id. |
| 43 |
*/ |
| 44 |
function mlsimport_theme_directory_map() { |
| 45 |
return array( |
| 46 |
'wpresidence' => 991, |
| 47 |
'houzez' => 992, |
| 48 |
'realhomes' => 993, |
| 49 |
'wpestate' => 994, |
| 50 |
); |
| 51 |
} |
| 52 |
|
| 53 |
/** |
| 54 |
* Resolve the supported theme id this site should run as. |
| 55 |
* |
| 56 |
* Step by step: |
| 57 |
* 1. If the user has already saved a theme in the plugin options, that choice |
| 58 |
* wins outright. An explicit configuration decision is never second-guessed |
| 59 |
* by detection - the saved value is what every other code path (the write |
| 60 |
* adapter, standalone mode) already acts on. |
| 61 |
* 2. Otherwise look at the active parent theme's directory slug and match it |
| 62 |
* against the four real-estate themes. |
| 63 |
* 3. No match means standalone (990). This is the normal, healthy outcome for |
| 64 |
* the majority of sites - not a failure. |
| 65 |
* |
| 66 |
* @return int One of 990, 991, 992, 993, 994. Never anything else. |
| 67 |
*/ |
| 68 |
function mlsimport_resolve_theme_id() { |
| 69 |
// Step 1: an explicit saved choice is authoritative. Only values the plugin |
| 70 |
// can actually write with are honoured; a stale or corrupt id falls through |
| 71 |
// to detection rather than routing listings to a non-existent adapter. |
| 72 |
$options = get_option( 'mlsimport_admin_options' ); |
| 73 |
$saved = ( is_array( $options ) && isset( $options['mlsimport_theme_used'] ) ) ? intval( $options['mlsimport_theme_used'] ) : 0; |
| 74 |
$supported = array( 990, 991, 992, 993, 994 ); |
| 75 |
|
| 76 |
if ( in_array( $saved, $supported, true ) ) { |
| 77 |
return $saved; |
| 78 |
} |
| 79 |
|
| 80 |
// Step 2: no saved choice - detect from the active parent theme directory. |
| 81 |
$slug = strtolower( (string) get_template() ); |
| 82 |
$map = mlsimport_theme_directory_map(); |
| 83 |
|
| 84 |
if ( isset( $map[ $slug ] ) ) { |
| 85 |
return $map[ $slug ]; |
| 86 |
} |
| 87 |
|
| 88 |
// Step 3: anything else is a standalone site. |
| 89 |
return 990; |
| 90 |
} |
| 91 |
|
| 92 |
/** |
| 93 |
* The theme's name as the wizard drops it into a sentence. |
| 94 |
* |
| 95 |
* Three later steps ("connect your %s website", "imported properties from your |
| 96 |
* MLS into %s") each carried their own copy of a theme matcher just to fill in |
| 97 |
* this word. They share this one instead. |
| 98 |
* |
| 99 |
* Standalone deliberately does not read as its selector label, "Standalone |
| 100 |
* (any theme)" - that label belongs in a dropdown, not in a sentence. A |
| 101 |
* standalone site is a WordPress site, and every one of those sentences reads |
| 102 |
* correctly with that word. |
| 103 |
* |
| 104 |
* @return string Theme name for 991-994, or 'WordPress' for standalone. |
| 105 |
*/ |
| 106 |
function mlsimport_theme_copy_label() { |
| 107 |
$theme_id = mlsimport_resolve_theme_id(); |
| 108 |
|
| 109 |
// Standalone has no host theme to name. |
| 110 |
if ( 990 === $theme_id ) { |
| 111 |
return __( 'WordPress', 'mlsimport' ); |
| 112 |
} |
| 113 |
|
| 114 |
return MLSIMPORT_THEME[ $theme_id ]; |
| 115 |
} |
| 116 |
|
| 117 |
/** |
| 118 |
* Build the theme <select> for the mlsimport_admin_options[$key] field. |
| 119 |
* |
| 120 |
* Lives here, not with the other form helpers, because both of its callers - |
| 121 |
* the wizard account step and the settings page - render exactly one list: the |
| 122 |
* supported themes, preselected with mlsimport_resolve_theme_id(). Rendering it |
| 123 |
* from the raw saved option instead left NO option marked selected on a site |
| 124 |
* that had never answered, so the browser silently fell on the first entry, |
| 125 |
* 990 Standalone, and that became the saved theme (#242). |
| 126 |
* |
| 127 |
* Step by step: |
| 128 |
* 1. Open the select, bound to the mlsimport_admin_options[$key] field. |
| 129 |
* 2. Emit one <option> per supported theme, marking the one that matches the |
| 130 |
* resolved id as selected. |
| 131 |
* 3. Close and return the markup. |
| 132 |
* |
| 133 |
* @param string $key Option key (used as the id and the name suffix). |
| 134 |
* @param mixed $value Theme id to preselect - pass mlsimport_resolve_theme_id(). |
| 135 |
* @param array $data_array Map of theme id => label (MLSIMPORT_THEME). |
| 136 |
* @return string The rendered <select> HTML. |
| 137 |
*/ |
| 138 |
function mlsiport_mls_select_list( $key, $value, $data_array ) { |
| 139 |
// Step 1 - open the select, binding it to the mlsimport_admin_options field. |
| 140 |
$select = '<select class="mlsimport-2025-select" id="' . esc_attr( $key ) . '" name="mlsimport_admin_options[' . $key . ']">'; |
| 141 |
|
| 142 |
// Only build options when given an array of choices. |
| 143 |
if ( is_array( $data_array ) ) { |
| 144 |
// Step 2 - one <option> per choice. The loop uses its own variable: it |
| 145 |
// used to reuse $key and overwrite the field name mid-render. |
| 146 |
foreach ( $data_array as $theme_id => $theme_label ) { |
| 147 |
$select .= '<option value="' . esc_attr( $theme_id ) . '"'; |
| 148 |
// Mark the option matching the resolved theme id as selected. |
| 149 |
if ( intval( $value ) === intval( $theme_id ) ) { |
| 150 |
$select .= ' selected '; |
| 151 |
} |
| 152 |
$select .= '>' . esc_html( $theme_label ) . '</option>'; |
| 153 |
} |
| 154 |
} |
| 155 |
|
| 156 |
// Step 3 - close the select and return the assembled markup. |
| 157 |
$select .= '</select>'; |
| 158 |
return $select; |
| 159 |
} |
| 160 |
|