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 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 6.0.7 All 35 releases
mlsimport / enviroment / EstateClass.php

EstateClass.php in MLSImport: IDX Plugin & MLS Plugin for Real Estate Listings 7.2, at enviroment/EstateClass.php

254 lines 8.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Theme adapter: WpEstate.
4 *
5 * One of the per-theme adapters in enviroment/. Maps RESO-standard MLS data
6 * onto WpEstate's post type (estate_property), agent post type (estate_agent),
7 * post meta keys and its wp_estate_custom_fields / wp_estate_feature_list
8 * options. Shared persistence stays in Stored Listing Write; this adapter owns
9 * WpEstate feature flags, creation defaults, and custom-field registration.
10 *
11 * @package MLSImport
12 */
13 if ( ! defined( 'ABSPATH' ) ) {
14 // Block direct web access — only load when WordPress is bootstrapped.
15 exit; // Exit if accessed directly
16 }
17
18 /**
19 * Persist genuine WpEstate variation behind the Stored adapter seam.
20 *
21 * @author mlsimport
22 */
23 class EstateClass {
24
25 /**
26 * No setup required — the adapter is stateless.
27 */
28 public function __construct() {
29 }
30
31
32 /**
33 * return custom post field
34 *
35 * @since 1.0.0
36 * @access protected
37 * @var string $plugin_name
38 */
39 public function get_property_post_type() {
40 // WpEstate's property CPT slug — imported listings are stored here.
41 return 'estate_property';
42 }
43
44 /**
45 * Return the WpEstate post type used for Managed Listing lookup/write.
46 *
47 * @return string WpEstate property post-type slug.
48 */
49 public function property_post_type(): string {
50 return 'estate_property';
51 }
52
53 /**
54 * Keep WpEstate's existing no-gallery-meta behavior.
55 *
56 * @param int $property_id Managed Listing post ID.
57 * @param array<int, int> $attachment_ids Final ordered attachment IDs.
58 * @return bool Always true because this theme stores no gallery meta here.
59 */
60 public function write_gallery( int $property_id, array $attachment_ids ): bool {
61 unset( $property_id, $attachment_ids );
62 return true;
63 }
64
65 /**
66 * Persist WpEstate's plain custom fields and creation-time defaults.
67 *
68 * @param int $property_id Managed Listing post ID.
69 * @param array<string, mixed> $property Raw incoming property.
70 * @param array<string, mixed> $context Prepared fields and creation choices.
71 * @return bool Whether the theme projection completed.
72 */
73 public function write_theme_projection( int $property_id, array $property, array $context ): bool {
74 foreach ( (array) ( $context['fields'] ?? array() ) as $field ) {
75 // GitHub issue #286: the identity field is never projected as theme
76 // meta — its lowercased row is the same case-insensitive meta row as
77 // the listing identity and an edit-screen save could blank it.
78 if ( 'listingkey' === strtolower( (string) $field['field'] ) ) {
79 continue;
80 }
81 update_post_meta( $property_id, strtolower( (string) $field['field'] ), (string) $field['value'] );
82 }
83 $this->write_property_features( $property_id, $property );
84 if ( empty( $context['is_new'] ) ) {
85 return true;
86 }
87
88 update_post_meta( $property_id, 'prop_featured', 0 );
89 update_post_meta( $property_id, 'page_custom_zoom', 16 );
90 update_post_meta( $property_id, 'property_agent', (int) ( $context['assigned_agent_id'] ?? 0 ) );
91 update_post_meta( $property_id, 'property_page_desing_local', '' );
92 foreach ( array( 'header_transparent', 'page_show_adv_search', 'sidebar_agent_option', 'local_pgpr_slider_type', 'local_pgpr_content_type', 'sidebar_select', 'sidebar_option' ) as $key ) {
93 update_post_meta( $property_id, $key, 'global' );
94 }
95 update_post_meta( $property_id, 'header_type', 0 );
96 if ( function_exists( 'wpestate_update_hiddent_address_single' ) ) {
97 wpestate_update_hiddent_address_single( $property_id );
98 }
99 return true;
100 }
101
102
103
104 /**
105 * return custom post field
106 *
107 * @since 1.0.0
108 * @access protected
109 * @var string $plugin_name
110 */
111 public function get_agent_post_type() {
112 // WpEstate's agent CPT slug — imported agents are stored here.
113 return 'estate_agent';
114 }
115
116 /**
117 * Persist WpEstate feature flags and its theme-wide feature registry.
118 *
119 * The RESO feature collection may contain scalar names or one nested list.
120 * Each usable name becomes a sanitized boolean post-meta flag. The theme
121 * registry is normalized once and saved only when a new name is discovered.
122 *
123 * @param int $property_id Managed Listing post ID.
124 * @param array<string, mixed> $property Raw incoming property.
125 * @return void
126 */
127 private function write_property_features( int $property_id, array $property ): void {
128 $raw_features = $property['meta']['property_features'] ?? array();
129 if ( ! is_array( $raw_features ) ) {
130 return;
131 }
132
133 $feature_names = array();
134 foreach ( $raw_features as $raw_feature ) {
135 foreach ( is_array( $raw_feature ) ? $raw_feature : array( $raw_feature ) as $feature_name ) {
136 $feature_name = trim( (string) $feature_name );
137 if ( '' !== $feature_name ) {
138 $feature_names[] = $feature_name;
139 }
140 }
141 }
142
143 $registered = array_values(
144 array_filter(
145 array_map( 'trim', explode( ',', (string) get_option( 'wp_estate_feature_list', '' ) ) )
146 )
147 );
148 $changed = false;
149 foreach ( array_values( array_unique( $feature_names ) ) as $feature_name ) {
150 $meta_key = sanitize_key( sanitize_title( str_replace( ' ', '_', $feature_name ) ) );
151 if ( '' !== $meta_key ) {
152 update_post_meta( $property_id, $meta_key, 1 );
153 }
154 if ( ! in_array( $feature_name, $registered, true ) ) {
155 $registered[] = $feature_name;
156 $changed = true;
157 }
158 }
159 if ( $changed ) {
160 update_option( 'wp_estate_feature_list', implode( ',', $registered ) );
161 }
162 }
163
164 /**
165 * save custom fields per environment
166 *
167 * @since 1.0.0
168 * @access protected
169 * @var string $plugin_name
170 */
171 public function enviroment_custom_fields( $option_name ) {
172
173 // Existing WpEstate custom-field definitions (each a numeric array row).
174 $custom_fields = get_option( 'wp_estate_custom_fields', true );
175
176 // Ensure we always work with an array.
177 if ( ! is_array( $custom_fields ) ) {
178 $custom_fields = array();
179 }
180 // Starting order index for newly added custom fields.
181 $custom_field_no = 100;
182 $options = mlsimport_normalized_field_configuration();
183 $active_fields = array_fill_keys( array_keys( mlsimport_field_configuration_metadata() ), true );
184
185 foreach ( $options['mls-fields'] as $key => $value ) {
186 // Field is enabled AND not flagged as admin-only → it becomes a theme custom field.
187 if ( isset( $active_fields[ $key ] ) && 1 === intval($value) && 0 === intval( $options['mls-fields-admin'][ $key ]) ) {
188 // Not already registered (and non-empty key) → add a new custom-field row.
189 if ( ! in_array( $key, array_column( $custom_fields, 0 ) ) && '' !== $key ) {
190 ++$custom_field_no;
191 $temp_array = array();
192 $temp_array[0] = $key;
193 $label = isset( $options['mls-fields-label'][ $key ] ) && '' !== $options['mls-fields-label'][ $key ] ? $options['mls-fields-label'][ $key ] : $key;
194 $temp_array[1] = $label;
195
196 $temp_array[2] = 'short text';
197 $temp_array[3] = $custom_field_no;
198 $custom_fields[] = $temp_array;
199 } else {
200 // Already registered → just refresh its label (index 1).
201 $to_replace_key = array_search( $key, array_column( $custom_fields, 0 ) );
202 $label = isset( $options['mls-fields-label'][ $key ] ) && '' !== $options['mls-fields-label'][ $key ] ? $options['mls-fields-label'][ $key ] : $key;
203 $custom_fields[ $to_replace_key ]['1'] = $label;
204 }
205 } else {
206 // remove item from custom fields
207 $key_remove = $this->searchForId( $key, $custom_fields );
208
209 // Drop the row when a matching definition exists.
210 if ( null !== $key_remove ) {
211 unset( $custom_fields[ $key_remove ] );
212 }
213 }
214 }
215
216 // Persist the rebuilt custom-field list back to the theme option.
217 update_option( 'wp_estate_custom_fields', $custom_fields );
218 }
219
220
221 /**
222 * Find the array index of a custom-field row whose first element equals $id.
223 *
224 * @param string $id The field key to look for (matched against $val[0]).
225 * @param array $array Rows of custom-field definitions.
226 * @return int|string|null Matching key, or null when not found.
227 */
228 public function searchForId( $id, $array ) {
229 // Linear scan comparing each row's key column (index 0).
230 foreach ( $array as $key => $val ) {
231 if ( $val[0] === $id ) {
232 return $key;
233 }
234 }
235 // No match.
236 return null;
237 }
238
239
240
241 /**
242 * return theme schema
243 *
244 * @since 1.0.0
245 * @access protected
246 * @var string $plugin_name
247 */
248 public function return_theme_schema() {
249
250 // No schema exposed for WpEstate — returns nothing.
251 return;
252 }
253 }
254