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 / help_functions.php

help_functions.php in MLSImport: IDX Plugin & MLS Plugin for Real Estate Listings 7.1.2, at includes/help_functions.php

3,315 lines 83.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Helper functions for the MLSImport plugin.
4 *
5 * Grab-bag of stand-alone utilities used across the admin/import layers:
6 * - Standalone-mode detection (theme_id 990).
7 * - The canonical RESO -> theme field-mapping schema (mlsimport_hardocde_theme_schema),
8 * a large associative array telling the importer where each RESO field lands
9 * (post meta, taxonomy, media, or post content/title).
10 * - Taxonomy discovery for a post type, allowed-HTML whitelists, SaaS "ready to go
11 * MLS" list fetching, recursive array sanitisation, the reconciliation cron entry
12 * point, the Import Tasks admin list-table columns, and a plugin data reset routine.
13 *
14 * Loaded early in the bootstrap so these helpers are available to both admin and
15 * public code paths.
16 */
17 if ( ! defined( 'ABSPATH' ) ) {
18 exit; // Exit if accessed directly
19 }
20
21
22 /**
23 * Whether the site runs in standalone (theme-agnostic) mode — theme_id 990.
24 *
25 * Drives the standalone write path / front-end gating. Reads the configured
26 * theme from mlsimport_admin_options['mlsimport_theme_used'].
27 *
28 * @return bool
29 */
30 function mlsimport_is_standalone_mode() {
31 $options = get_option( 'mlsimport_admin_options' );
32 return is_array( $options )
33 && isset( $options['mlsimport_theme_used'] )
34 && 990 === intval( $options['mlsimport_theme_used'] );
35 }
36
37
38 /**
39 * Hard-coded RESO -> theme field-mapping schema (fallback / reference map).
40 *
41 * Returns a large associative array keyed by RESO Data Dictionary field name
42 * (e.g. 'ListPrice', 'BedroomsTotal', 'City'). Each value is a descriptor array
43 * describing where that RESO field is written on the WordPress side:
44 * - 'type' => one of:
45 * 'meta' - stored as a post meta value ('name' = meta key),
46 * 'taxonomy' - assigned as a term of taxonomy 'name'; an optional
47 * 'insert' gives the fixed term label to add (used for
48 * boolean *YN flags, e.g. 'Has Garage'),
49 * 'media' - handled by the media/gallery importer,
50 * 'content' - written to the post content (PublicRemarks).
51 * - 'name' => the destination meta key / taxonomy slug / field on the theme side.
52 * - 'insert' => (taxonomy only, optional) literal term label to insert when the
53 * RESO boolean is truthy.
54 *
55 * The keys are ordered alphabetically by RESO field name. Section markers below
56 * flag the larger logical clusters (agent/office contact blocks, distance-to-*,
57 * tax, etc.) but most fields are simple 1:1 meta passthroughs.
58 *
59 * @return array Field-name => descriptor map.
60 */
61 function mlsimport_hardocde_theme_schema(){
62 // Build and return the full descriptor map in one literal array.
63 $theme_schema= array(
64 // ---- Above/Below-grade area, access & accessibility (A) ----
65 'AboveGradeFinishedArea' => array(
66 'type' => 'meta',
67 'name' => 'abovegradefinishedarea',
68 ),
69 'AboveGradeFinishedAreaSource' => array(
70 'type' => 'meta',
71 'name' => 'abovegradefinishedareasource',
72 ),
73 'AboveGradeFinishedAreaUnits' => array(
74 'type' => 'meta',
75 'name' => 'abovegradefinishedareaunits',
76 ),
77 'AboveGradeUnfinishedArea' => array(
78 'type' => 'meta',
79 'name' => 'abovegradeunfinishedarea',
80 ),
81 'AboveGradeUnfinishedAreaSource' => array(
82 'type' => 'meta',
83 'name' => 'abovegradeunfinishedareasource',
84 ),
85 'AboveGradeUnfinishedAreaUnits' => array(
86 'type' => 'meta',
87 'name' => 'abovegradeunfinishedareaunits',
88 ),
89 'AccessCode' => array(
90 'type' => 'meta',
91 'name' => 'accesscode',
92 ),
93 'AccessibilityFeatures' => array(
94 'type' => 'meta',
95 'name' => 'accessibilityfeatures',
96 ),
97 'ActivationDate' => array(
98 'type' => 'meta',
99 'name' => 'activationdate',
100 ),
101 'AdditionalParcelsDescription' => array(
102 'type' => 'meta',
103 'name' => 'additionalparcelsdescription',
104 ),
105 'AdditionalParcelsYN' => array(
106 'type' => 'taxonomy',
107 'name' => 'property_features',
108 'insert' => 'Has Additional Parcels',
109 ),
110 'AnchorsCoTenants' => array(
111 'type' => 'meta',
112 'name' => 'anchorscotenants',
113 ),
114 'Appliances' => array(
115 'type' => 'taxonomy',
116 'name' => 'property_features',
117 ),
118 'ArchitecturalStyle' => array(
119 'type' => 'meta',
120 'name' => 'architecturalstyle',
121 ),
122 // ---- HOA / association fees & names ----
123 'AssociationAmenities' => array(
124 'type' => 'meta',
125 'name' => 'associationamenities',
126 ),
127 'AssociationFee' => array(
128 'type' => 'meta',
129 'name' => 'associationfee',
130 ),
131 'AssociationFee2' => array(
132 'type' => 'meta',
133 'name' => 'associationfee2',
134 ),
135 'AssociationFee2Frequency' => array(
136 'type' => 'meta',
137 'name' => 'associationfee2frequency',
138 ),
139 'AssociationFeeFrequency' => array(
140 'type' => 'meta',
141 'name' => 'associationfeefrequency',
142 ),
143 'AssociationFeeIncludes' => array(
144 'type' => 'meta',
145 'name' => 'associationfeeincludes',
146 ),
147 'AssociationName' => array(
148 'type' => 'meta',
149 'name' => 'associationname',
150 ),
151 'AssociationName2' => array(
152 'type' => 'meta',
153 'name' => 'associationname2',
154 ),
155 'AssociationPhone' => array(
156 'type' => 'meta',
157 'name' => 'associationphone',
158 ),
159 'AssociationPhone2' => array(
160 'type' => 'meta',
161 'name' => 'associationphone2',
162 ),
163 'AssociationYN' => array(
164 'type' => 'taxonomy',
165 'name' => 'property_features',
166 'insert' => 'Home Owners Association',
167 ),
168 'AttachedGarageYN' => array(
169 'type' => 'taxonomy',
170 'name' => 'property_features',
171 'insert' => 'Garage Attached',
172 ),
173 'AttributionContact' => array(
174 'type' => 'meta',
175 'name' => 'attributioncontact',
176 ),
177 'AvailabilityDate' => array(
178 'type' => 'meta',
179 'name' => 'availabilitydate',
180 ),
181 'AvailableLeaseType' => array(
182 'type' => 'meta',
183 'name' => 'availableleasetype',
184 ),
185 'BackOnMarketDate' => array(
186 'type' => 'meta',
187 'name' => 'backonmarketdate',
188 ),
189 'Basement' => array(
190 'type' => 'meta',
191 'name' => 'basement',
192 ),
193 'BasementYN' => array(
194 'type' => 'taxonomy',
195 'name' => 'property_features',
196 'insert' => 'Has Basement',
197 ),
198 // ---- Bath / bedroom counts (BathroomsTotalInteger & BedroomsTotal map to theme core fields) ----
199 'BathroomsFull' => array(
200 'type' => 'meta',
201 'name' => 'bathroomsfull',
202 ),
203 'BathroomsHalf' => array(
204 'type' => 'meta',
205 'name' => 'bathroomshalf',
206 ),
207 'BathroomsOneQuarter' => array(
208 'type' => 'meta',
209 'name' => 'bathroomsonequarter',
210 ),
211 'BathroomsPartial' => array(
212 'type' => 'meta',
213 'name' => 'bathroomspartial',
214 ),
215 'BathroomsThreeQuarter' => array(
216 'type' => 'meta',
217 'name' => 'bathroomsthreequarter',
218 ),
219 'BathroomsTotalInteger' => array(
220 'type' => 'meta',
221 'name' => 'property_bathrooms',
222 ),
223 'BedroomsPossible' => array(
224 'type' => 'meta',
225 'name' => 'bedroomspossible',
226 ),
227 'BedroomsTotal' => array(
228 'type' => 'meta',
229 'name' => 'property_bedrooms',
230 ),
231 'BelowGradeFinishedArea' => array(
232 'type' => 'meta',
233 'name' => 'belowgradefinishedarea',
234 ),
235 'BelowGradeFinishedAreaSource' => array(
236 'type' => 'meta',
237 'name' => 'belowgradefinishedareasource',
238 ),
239 'BelowGradeFinishedAreaUnits' => array(
240 'type' => 'meta',
241 'name' => 'belowgradefinishedareaunits',
242 ),
243 'BelowGradeUnfinishedArea' => array(
244 'type' => 'meta',
245 'name' => 'belowgradeunfinishedarea',
246 ),
247 'BelowGradeUnfinishedAreaSource' => array(
248 'type' => 'meta',
249 'name' => 'belowgradeunfinishedareasource',
250 ),
251 'BelowGradeUnfinishedAreaUnits' => array(
252 'type' => 'meta',
253 'name' => 'belowgradeunfinishedareaunits',
254 ),
255 'BodyType' => array(
256 'type' => 'meta',
257 'name' => 'bodytype',
258 ),
259 'BuilderModel' => array(
260 'type' => 'meta',
261 'name' => 'buildermodel',
262 ),
263 'BuilderName' => array(
264 'type' => 'meta',
265 'name' => 'buildername',
266 ),
267 'BuildingAreaSource' => array(
268 'type' => 'meta',
269 'name' => 'buildingareasource',
270 ),
271 'BuildingAreaTotal' => array(
272 'type' => 'meta',
273 'name' => 'buildingareatotal',
274 ),
275 'BuildingAreaUnits' => array(
276 'type' => 'meta',
277 'name' => 'buildingareaunits',
278 ),
279 'BuildingFeatures' => array(
280 'type' => 'meta',
281 'name' => 'buildingfeatures',
282 ),
283 'BuildingName' => array(
284 'type' => 'meta',
285 'name' => 'buildingname',
286 ),
287 'BusinessName' => array(
288 'type' => 'meta',
289 'name' => 'businessname',
290 ),
291 'BusinessType' => array(
292 'type' => 'meta',
293 'name' => 'businesstype',
294 ),
295 // ---- Buyer agent contact block (name/phone/email/license variants) ----
296 'BuyerAgent' => array(
297 'type' => 'meta',
298 'name' => 'buyeragent',
299 ),
300 'BuyerAgentAOR' => array(
301 'type' => 'meta',
302 'name' => 'buyeragentaor',
303 ),
304 'BuyerAgentDesignation' => array(
305 'type' => 'meta',
306 'name' => 'buyeragentdesignation',
307 ),
308 'BuyerAgentDirectPhone' => array(
309 'type' => 'meta',
310 'name' => 'buyeragentdirectphone',
311 ),
312 'BuyerAgentEmail' => array(
313 'type' => 'meta',
314 'name' => 'buyeragentemail',
315 ),
316 'BuyerAgentFax' => array(
317 'type' => 'meta',
318 'name' => 'buyeragentfax',
319 ),
320 'BuyerAgentFirstName' => array(
321 'type' => 'meta',
322 'name' => 'buyeragentfirstname',
323 ),
324 'BuyerAgentFullName' => array(
325 'type' => 'meta',
326 'name' => 'buyeragentfullname',
327 ),
328 'BuyerAgentHomePhone' => array(
329 'type' => 'meta',
330 'name' => 'buyeragenthomephone',
331 ),
332 'BuyerAgentKey' => array(
333 'type' => 'meta',
334 'name' => 'buyeragentkey',
335 ),
336 'BuyerAgentLastName' => array(
337 'type' => 'meta',
338 'name' => 'buyeragentlastname',
339 ),
340 'BuyerAgentMiddleName' => array(
341 'type' => 'meta',
342 'name' => 'buyeragentmiddlename',
343 ),
344 'BuyerAgentMlsId' => array(
345 'type' => 'meta',
346 'name' => 'buyeragentmlsid',
347 ),
348 'BuyerAgentMobilePhone' => array(
349 'type' => 'meta',
350 'name' => 'buyeragentmobilephone',
351 ),
352 'BuyerAgentNamePrefix' => array(
353 'type' => 'meta',
354 'name' => 'buyeragentnameprefix',
355 ),
356 'BuyerAgentNameSuffix' => array(
357 'type' => 'meta',
358 'name' => 'buyeragentnamesuffix',
359 ),
360 'BuyerAgentNationalAssociationId' => array(
361 'type' => 'meta',
362 'name' => 'buyeragentnationalassociationid',
363 ),
364 'BuyerAgentOfficePhone' => array(
365 'type' => 'meta',
366 'name' => 'buyeragentofficephone',
367 ),
368 'BuyerAgentOfficePhoneExt' => array(
369 'type' => 'meta',
370 'name' => 'buyeragentofficephoneext',
371 ),
372 'BuyerAgentPager' => array(
373 'type' => 'meta',
374 'name' => 'buyeragentpager',
375 ),
376 'BuyerAgentPreferredPhone' => array(
377 'type' => 'meta',
378 'name' => 'buyeragentpreferredphone',
379 ),
380 'BuyerAgentPreferredPhoneExt' => array(
381 'type' => 'meta',
382 'name' => 'buyeragentpreferredphoneext',
383 ),
384 'BuyerAgentStateLicense' => array(
385 'type' => 'meta',
386 'name' => 'buyeragentstatelicense',
387 ),
388 'BuyerAgentTollFreePhone' => array(
389 'type' => 'meta',
390 'name' => 'buyeragenttollfreephone',
391 ),
392 'BuyerAgentURL' => array(
393 'type' => 'meta',
394 'name' => 'buyeragenturl',
395 ),
396 'BuyerAgentVoiceMail' => array(
397 'type' => 'meta',
398 'name' => 'buyeragentvoicemail',
399 ),
400 'BuyerAgentVoiceMailExt' => array(
401 'type' => 'meta',
402 'name' => 'buyeragentvoicemailext',
403 ),
404 'BuyerBrokerageCompensation' => array(
405 'type' => 'meta',
406 'name' => 'buyerbrokeragecompensation',
407 ),
408 'BuyerBrokerageCompensationType' => array(
409 'type' => 'meta',
410 'name' => 'buyerbrokeragecompensationtype',
411 ),
412 'BuyerFinancing' => array(
413 'type' => 'meta',
414 'name' => 'buyerfinancing',
415 ),
416 // ---- Buyer office / brokerage block ----
417 'BuyerOffice' => array(
418 'type' => 'meta',
419 'name' => 'buyeroffice',
420 ),
421 'BuyerOfficeAOR' => array(
422 'type' => 'meta',
423 'name' => 'buyerofficeaor',
424 ),
425 'BuyerOfficeEmail' => array(
426 'type' => 'meta',
427 'name' => 'buyerofficeemail',
428 ),
429 'BuyerOfficeFax' => array(
430 'type' => 'meta',
431 'name' => 'buyerofficefax',
432 ),
433 'BuyerOfficeKey' => array(
434 'type' => 'meta',
435 'name' => 'buyerofficekey',
436 ),
437 'BuyerOfficeMlsId' => array(
438 'type' => 'meta',
439 'name' => 'buyerofficemlsid',
440 ),
441 'BuyerOfficeName' => array(
442 'type' => 'meta',
443 'name' => 'buyerofficename',
444 ),
445 'BuyerOfficeNationalAssociationId' => array(
446 'type' => 'meta',
447 'name' => 'buyerofficenationalassociationid',
448 ),
449 'BuyerOfficePhone' => array(
450 'type' => 'meta',
451 'name' => 'buyerofficephone',
452 ),
453 'BuyerOfficePhoneExt' => array(
454 'type' => 'meta',
455 'name' => 'buyerofficephoneext',
456 ),
457 'BuyerOfficeURL' => array(
458 'type' => 'meta',
459 'name' => 'buyerofficeurl',
460 ),
461 'BuyerTeam' => array(
462 'type' => 'meta',
463 'name' => 'buyerteam',
464 ),
465 'BuyerTeamKey' => array(
466 'type' => 'meta',
467 'name' => 'buyerteamkey',
468 ),
469 'BuyerTeamName' => array(
470 'type' => 'meta',
471 'name' => 'buyerteamname',
472 ),
473 'CableTvExpense' => array(
474 'type' => 'meta',
475 'name' => 'cabletvexpense',
476 ),
477 'CancellationDate' => array(
478 'type' => 'meta',
479 'name' => 'cancellationdate',
480 ),
481 'CapRate' => array(
482 'type' => 'meta',
483 'name' => 'caprate',
484 ),
485 'CarportSpaces' => array(
486 'type' => 'meta',
487 'name' => 'carportspaces',
488 ),
489 'CarportYN' => array(
490 'type' => 'taxonomy',
491 'name' => 'property_features',
492 'insert' => 'Has Carport',
493 ),
494 'CarrierRoute' => array(
495 'type' => 'meta',
496 'name' => 'carrierroute',
497 ),
498 // ---- Location taxonomies: City -> property_city, CityRegion -> property_area, etc. ----
499 'City' => array(
500 'type' => 'taxonomy',
501 'name' => 'property_city',
502 ),
503 'CityRegion' => array(
504 'type' => 'taxonomy',
505 'name' => 'property_area',
506 ),
507 'CloseDate' => array(
508 'type' => 'meta',
509 'name' => 'closedate',
510 ),
511 'ClosePrice' => array(
512 'type' => 'meta',
513 'name' => 'closeprice',
514 ),
515 // ---- Co-buyer agent contact block ----
516 'CoBuyerAgent' => array(
517 'type' => 'meta',
518 'name' => 'cobuyeragent',
519 ),
520 'CoBuyerAgentAOR' => array(
521 'type' => 'meta',
522 'name' => 'cobuyeragentaor',
523 ),
524 'CoBuyerAgentDesignation' => array(
525 'type' => 'meta',
526 'name' => 'cobuyeragentdesignation',
527 ),
528 'CoBuyerAgentDirectPhone' => array(
529 'type' => 'meta',
530 'name' => 'cobuyeragentdirectphone',
531 ),
532 'CoBuyerAgentEmail' => array(
533 'type' => 'meta',
534 'name' => 'cobuyeragentemail',
535 ),
536 'CoBuyerAgentFax' => array(
537 'type' => 'meta',
538 'name' => 'cobuyeragentfax',
539 ),
540 'CoBuyerAgentFirstName' => array(
541 'type' => 'meta',
542 'name' => 'cobuyeragentfirstname',
543 ),
544 'CoBuyerAgentFullName' => array(
545 'type' => 'meta',
546 'name' => 'cobuyeragentfullname',
547 ),
548 'CoBuyerAgentHomePhone' => array(
549 'type' => 'meta',
550 'name' => 'cobuyeragenthomephone',
551 ),
552 'CoBuyerAgentKey' => array(
553 'type' => 'meta',
554 'name' => 'cobuyeragentkey',
555 ),
556 'CoBuyerAgentLastName' => array(
557 'type' => 'meta',
558 'name' => 'cobuyeragentlastname',
559 ),
560 'CoBuyerAgentMiddleName' => array(
561 'type' => 'meta',
562 'name' => 'cobuyeragentmiddlename',
563 ),
564 'CoBuyerAgentMlsId' => array(
565 'type' => 'meta',
566 'name' => 'cobuyeragentmlsid',
567 ),
568 'CoBuyerAgentMobilePhone' => array(
569 'type' => 'meta',
570 'name' => 'cobuyeragentmobilephone',
571 ),
572 'CoBuyerAgentNamePrefix' => array(
573 'type' => 'meta',
574 'name' => 'cobuyeragentnameprefix',
575 ),
576 'CoBuyerAgentNameSuffix' => array(
577 'type' => 'meta',
578 'name' => 'cobuyeragentnamesuffix',
579 ),
580 'CoBuyerAgentNationalAssociationId' => array(
581 'type' => 'meta',
582 'name' => 'cobuyeragentnationalassociationid',
583 ),
584 'CoBuyerAgentOfficePhone' => array(
585 'type' => 'meta',
586 'name' => 'cobuyeragentofficephone',
587 ),
588 'CoBuyerAgentOfficePhoneExt' => array(
589 'type' => 'meta',
590 'name' => 'cobuyeragentofficephoneext',
591 ),
592 'CoBuyerAgentPager' => array(
593 'type' => 'meta',
594 'name' => 'cobuyeragentpager',
595 ),
596 'CoBuyerAgentPreferredPhone' => array(
597 'type' => 'meta',
598 'name' => 'cobuyeragentpreferredphone',
599 ),
600 'CoBuyerAgentPreferredPhoneExt' => array(
601 'type' => 'meta',
602 'name' => 'cobuyeragentpreferredphoneext',
603 ),
604 'CoBuyerAgentStateLicense' => array(
605 'type' => 'meta',
606 'name' => 'cobuyeragentstatelicense',
607 ),
608 'CoBuyerAgentTollFreePhone' => array(
609 'type' => 'meta',
610 'name' => 'cobuyeragenttollfreephone',
611 ),
612 'CoBuyerAgentURL' => array(
613 'type' => 'meta',
614 'name' => 'cobuyeragenturl',
615 ),
616 'CoBuyerAgentVoiceMail' => array(
617 'type' => 'meta',
618 'name' => 'cobuyeragentvoicemail',
619 ),
620 'CoBuyerAgentVoiceMailExt' => array(
621 'type' => 'meta',
622 'name' => 'cobuyeragentvoicemailext',
623 ),
624 // ---- Co-buyer office / brokerage block ----
625 'CoBuyerOffice' => array(
626 'type' => 'meta',
627 'name' => 'cobuyeroffice',
628 ),
629 'CoBuyerOfficeAOR' => array(
630 'type' => 'meta',
631 'name' => 'cobuyerofficeaor',
632 ),
633 'CoBuyerOfficeEmail' => array(
634 'type' => 'meta',
635 'name' => 'cobuyerofficeemail',
636 ),
637 'CoBuyerOfficeFax' => array(
638 'type' => 'meta',
639 'name' => 'cobuyerofficefax',
640 ),
641 'CoBuyerOfficeKey' => array(
642 'type' => 'meta',
643 'name' => 'cobuyerofficekey',
644 ),
645 'CoBuyerOfficeMlsId' => array(
646 'type' => 'meta',
647 'name' => 'cobuyerofficemlsid',
648 ),
649 'CoBuyerOfficeName' => array(
650 'type' => 'meta',
651 'name' => 'cobuyerofficename',
652 ),
653 'CoBuyerOfficeNationalAssociationId' => array(
654 'type' => 'meta',
655 'name' => 'cobuyerofficenationalassociationid',
656 ),
657 'CoBuyerOfficePhone' => array(
658 'type' => 'meta',
659 'name' => 'cobuyerofficephone',
660 ),
661 'CoBuyerOfficePhoneExt' => array(
662 'type' => 'meta',
663 'name' => 'cobuyerofficephoneext',
664 ),
665 'CoBuyerOfficeURL' => array(
666 'type' => 'meta',
667 'name' => 'cobuyerofficeurl',
668 ),
669 // ---- Co-listing agent contact block ----
670 'CoListAgent' => array(
671 'type' => 'meta',
672 'name' => 'colistagent',
673 ),
674 'CoListAgentAOR' => array(
675 'type' => 'meta',
676 'name' => 'colistagentaor',
677 ),
678 'CoListAgentDesignation' => array(
679 'type' => 'meta',
680 'name' => 'colistagentdesignation',
681 ),
682 'CoListAgentDirectPhone' => array(
683 'type' => 'meta',
684 'name' => 'colistagentdirectphone',
685 ),
686 'CoListAgentEmail' => array(
687 'type' => 'meta',
688 'name' => 'colistagentemail',
689 ),
690 'CoListAgentFax' => array(
691 'type' => 'meta',
692 'name' => 'colistagentfax',
693 ),
694 'CoListAgentFirstName' => array(
695 'type' => 'meta',
696 'name' => 'colistagentfirstname',
697 ),
698 'CoListAgentFullName' => array(
699 'type' => 'meta',
700 'name' => 'colistagentfullname',
701 ),
702 'CoListAgentHomePhone' => array(
703 'type' => 'meta',
704 'name' => 'colistagenthomephone',
705 ),
706 'CoListAgentKey' => array(
707 'type' => 'meta',
708 'name' => 'colistagentkey',
709 ),
710 'CoListAgentLastName' => array(
711 'type' => 'meta',
712 'name' => 'colistagentlastname',
713 ),
714 'CoListAgentMiddleName' => array(
715 'type' => 'meta',
716 'name' => 'colistagentmiddlename',
717 ),
718 'CoListAgentMlsId' => array(
719 'type' => 'meta',
720 'name' => 'colistagentmlsid',
721 ),
722 'CoListAgentMobilePhone' => array(
723 'type' => 'meta',
724 'name' => 'colistagentmobilephone',
725 ),
726 'CoListAgentNamePrefix' => array(
727 'type' => 'meta',
728 'name' => 'colistagentnameprefix',
729 ),
730 'CoListAgentNameSuffix' => array(
731 'type' => 'meta',
732 'name' => 'colistagentnamesuffix',
733 ),
734 'CoListAgentNationalAssociationId' => array(
735 'type' => 'meta',
736 'name' => 'colistagentnationalassociationid',
737 ),
738 'CoListAgentOfficePhone' => array(
739 'type' => 'meta',
740 'name' => 'colistagentofficephone',
741 ),
742 'CoListAgentOfficePhoneExt' => array(
743 'type' => 'meta',
744 'name' => 'colistagentofficephoneext',
745 ),
746 'CoListAgentPager' => array(
747 'type' => 'meta',
748 'name' => 'colistagentpager',
749 ),
750 'CoListAgentPreferredPhone' => array(
751 'type' => 'meta',
752 'name' => 'colistagentpreferredphone',
753 ),
754 'CoListAgentPreferredPhoneExt' => array(
755 'type' => 'meta',
756 'name' => 'colistagentpreferredphoneext',
757 ),
758 'CoListAgentStateLicense' => array(
759 'type' => 'meta',
760 'name' => 'colistagentstatelicense',
761 ),
762 'CoListAgentTollFreePhone' => array(
763 'type' => 'meta',
764 'name' => 'colistagenttollfreephone',
765 ),
766 'CoListAgentURL' => array(
767 'type' => 'meta',
768 'name' => 'colistagenturl',
769 ),
770 'CoListAgentVoiceMail' => array(
771 'type' => 'meta',
772 'name' => 'colistagentvoicemail',
773 ),
774 'CoListAgentVoiceMailExt' => array(
775 'type' => 'meta',
776 'name' => 'colistagentvoicemailext',
777 ),
778 // ---- Co-listing office / brokerage block ----
779 'CoListOffice' => array(
780 'type' => 'meta',
781 'name' => 'colistoffice',
782 ),
783 'CoListOfficeAOR' => array(
784 'type' => 'meta',
785 'name' => 'colistofficeaor',
786 ),
787 'CoListOfficeEmail' => array(
788 'type' => 'meta',
789 'name' => 'colistofficeemail',
790 ),
791 'CoListOfficeFax' => array(
792 'type' => 'meta',
793 'name' => 'colistofficefax',
794 ),
795 'CoListOfficeKey' => array(
796 'type' => 'meta',
797 'name' => 'colistofficekey',
798 ),
799 'CoListOfficeMlsId' => array(
800 'type' => 'meta',
801 'name' => 'colistofficemlsid',
802 ),
803 'CoListOfficeName' => array(
804 'type' => 'meta',
805 'name' => 'colistofficename',
806 ),
807 'CoListOfficeNationalAssociationId' => array(
808 'type' => 'meta',
809 'name' => 'colistofficenationalassociationid',
810 ),
811 'CoListOfficePhone' => array(
812 'type' => 'meta',
813 'name' => 'colistofficephone',
814 ),
815 'CoListOfficePhoneExt' => array(
816 'type' => 'meta',
817 'name' => 'colistofficephoneext',
818 ),
819 'CoListOfficeURL' => array(
820 'type' => 'meta',
821 'name' => 'colistofficeurl',
822 ),
823 'CommonInterest' => array(
824 'type' => 'meta',
825 'name' => 'commoninterest',
826 ),
827 'CommonWalls' => array(
828 'type' => 'meta',
829 'name' => 'commonwalls',
830 ),
831 'CommunityFeatures' => array(
832 'type' => 'meta',
833 'name' => 'communityfeatures',
834 ),
835 'CompensationComments' => array(
836 'type' => 'meta',
837 'name' => 'compensationcomments',
838 ),
839 'CompSaleYN' => array(
840 'type' => 'taxonomy',
841 'name' => 'property_features',
842 'insert' => 'Comparative Purposes',
843 ),
844 'Concessions' => array(
845 'type' => 'meta',
846 'name' => 'concessions',
847 ),
848 'ConcessionsAmount' => array(
849 'type' => 'meta',
850 'name' => 'concessionsamount',
851 ),
852 'ConcessionsComments' => array(
853 'type' => 'meta',
854 'name' => 'concessionscomments',
855 ),
856 'ConstructionMaterials' => array(
857 'type' => 'meta',
858 'name' => 'constructionmaterials',
859 ),
860 'ContinentRegion' => array(
861 'type' => 'meta',
862 'name' => 'continentregion',
863 ),
864 'Contingency' => array(
865 'type' => 'meta',
866 'name' => 'contingency',
867 ),
868 'ContingentDate' => array(
869 'type' => 'meta',
870 'name' => 'contingentdate',
871 ),
872 'ContractStatusChangeDate' => array(
873 'type' => 'meta',
874 'name' => 'contractstatuschangedate',
875 ),
876 'Cooling' => array(
877 'type' => 'meta',
878 'name' => 'cooling',
879 ),
880 'CoolingYN' => array(
881 'type' => 'taxonomy',
882 'name' => 'property_features',
883 'insert' => 'Has Cooling System',
884 ),
885 'CopyrightNotice' => array(
886 'type' => 'meta',
887 'name' => 'copyrightnotice',
888 ),
889 'Country' => array(
890 'type' => 'meta',
891 'name' => 'property_country',
892 ),
893 'CountryRegion' => array(
894 'type' => 'meta',
895 'name' => 'countryregion',
896 ),
897 'CountyOrParish' => array(
898 'type' => 'taxonomy',
899 'name' => 'property_county_state',
900 ),
901 'CoveredSpaces' => array(
902 'type' => 'meta',
903 'name' => 'coveredspaces',
904 ),
905 'CropsIncludedYN' => array(
906 'type' => 'taxonomy',
907 'name' => 'property_features',
908 'insert' => 'Crops Included',
909 ),
910 'CrossStreet' => array(
911 'type' => 'meta',
912 'name' => 'crossstreet',
913 ),
914 'CultivatedArea' => array(
915 'type' => 'meta',
916 'name' => 'cultivatedarea',
917 ),
918 'CumulativeDaysOnMarket' => array(
919 'type' => 'meta',
920 'name' => 'cumulativedaysonmarket',
921 ),
922 'CurrentFinancing' => array(
923 'type' => 'meta',
924 'name' => 'currentfinancing',
925 ),
926 'CurrentUse' => array(
927 'type' => 'meta',
928 'name' => 'currentuse',
929 ),
930 'DaysInMls' => array(
931 'type' => 'meta',
932 'name' => 'daysinmls',
933 ),
934 'DaysOnMarket' => array(
935 'type' => 'meta',
936 'name' => 'daysonmarket',
937 ),
938 'DaysOnSite' => array(
939 'type' => 'meta',
940 'name' => 'daysonsite',
941 ),
942 'DevelopmentStatus' => array(
943 'type' => 'meta',
944 'name' => 'developmentstatus',
945 ),
946 'DirectionFaces' => array(
947 'type' => 'meta',
948 'name' => 'directionfaces',
949 ),
950 'Directions' => array(
951 'type' => 'meta',
952 'name' => 'directions',
953 ),
954 'Disclaimer' => array(
955 'type' => 'meta',
956 'name' => 'disclaimer',
957 ),
958 'Disclosures' => array(
959 'type' => 'meta',
960 'name' => 'disclosures',
961 ),
962 // ---- DistanceTo* family: comments/numeric/units triplets for each amenity ----
963 'DistanceToBusComments' => array(
964 'type' => 'meta',
965 'name' => 'distancetobuscomments',
966 ),
967 'DistanceToBusNumeric' => array(
968 'type' => 'meta',
969 'name' => 'distancetobusnumeric',
970 ),
971 'DistanceToBusUnits' => array(
972 'type' => 'meta',
973 'name' => 'distancetobusunits',
974 ),
975 'DistanceToElectricComments' => array(
976 'type' => 'meta',
977 'name' => 'distancetoelectriccomments',
978 ),
979 'DistanceToElectricNumeric' => array(
980 'type' => 'meta',
981 'name' => 'distancetoelectricnumeric',
982 ),
983 'DistanceToElectricUnits' => array(
984 'type' => 'meta',
985 'name' => 'distancetoelectricunits',
986 ),
987 'DistanceToFreewayComments' => array(
988 'type' => 'meta',
989 'name' => 'distancetofreewaycomments',
990 ),
991 'DistanceToFreewayNumeric' => array(
992 'type' => 'meta',
993 'name' => 'distancetofreewaynumeric',
994 ),
995 'DistanceToFreewayUnits' => array(
996 'type' => 'meta',
997 'name' => 'distancetofreewayunits',
998 ),
999 'DistanceToGasComments' => array(
1000 'type' => 'meta',
1001 'name' => 'distancetogascomments',
1002 ),
1003 'DistanceToGasNumeric' => array(
1004 'type' => 'meta',
1005 'name' => 'distancetogasnumeric',
1006 ),
1007 'DistanceToGasUnits' => array(
1008 'type' => 'meta',
1009 'name' => 'distancetogasunits',
1010 ),
1011 'DistanceToPhoneServiceComments' => array(
1012 'type' => 'meta',
1013 'name' => 'distancetophoneservicecomments',
1014 ),
1015 'DistanceToPhoneServiceNumeric' => array(
1016 'type' => 'meta',
1017 'name' => 'distancetophoneservicenumeric',
1018 ),
1019 'DistanceToPhoneServiceUnits' => array(
1020 'type' => 'meta',
1021 'name' => 'distancetophoneserviceunits',
1022 ),
1023 'DistanceToPlaceofWorshipComments' => array(
1024 'type' => 'meta',
1025 'name' => 'distancetoplaceofworshipcomments',
1026 ),
1027 'DistanceToPlaceofWorshipNumeric' => array(
1028 'type' => 'meta',
1029 'name' => 'distancetoplaceofworshipnumeric',
1030 ),
1031 'DistanceToPlaceofWorshipUnits' => array(
1032 'type' => 'meta',
1033 'name' => 'distancetoplaceofworshipunits',
1034 ),
1035 'DistanceToSchoolBusComments' => array(
1036 'type' => 'meta',
1037 'name' => 'distancetoschoolbuscomments',
1038 ),
1039 'DistanceToSchoolBusNumeric' => array(
1040 'type' => 'meta',
1041 'name' => 'distancetoschoolbusnumeric',
1042 ),
1043 'DistanceToSchoolBusUnits' => array(
1044 'type' => 'meta',
1045 'name' => 'distancetoschoolbusunits',
1046 ),
1047 'DistanceToSchoolsComments' => array(
1048 'type' => 'meta',
1049 'name' => 'distancetoschoolscomments',
1050 ),
1051 'DistanceToSchoolsNumeric' => array(
1052 'type' => 'meta',
1053 'name' => 'distancetoschoolsnumeric',
1054 ),
1055 'DistanceToSchoolsUnits' => array(
1056 'type' => 'meta',
1057 'name' => 'distancetoschoolsunits',
1058 ),
1059 'DistanceToSewerComments' => array(
1060 'type' => 'meta',
1061 'name' => 'distancetosewercomments',
1062 ),
1063 'DistanceToSewerNumeric' => array(
1064 'type' => 'meta',
1065 'name' => 'distancetosewernumeric',
1066 ),
1067 'DistanceToSewerUnits' => array(
1068 'type' => 'meta',
1069 'name' => 'distancetosewerunits',
1070 ),
1071 'DistanceToShoppingComments' => array(
1072 'type' => 'meta',
1073 'name' => 'distancetoshoppingcomments',
1074 ),
1075 'DistanceToShoppingNumeric' => array(
1076 'type' => 'meta',
1077 'name' => 'distancetoshoppingnumeric',
1078 ),
1079 'DistanceToShoppingUnits' => array(
1080 'type' => 'meta',
1081 'name' => 'distancetoshoppingunits',
1082 ),
1083 'DistanceToStreetComments' => array(
1084 'type' => 'meta',
1085 'name' => 'distancetostreetcomments',
1086 ),
1087 'DistanceToStreetNumeric' => array(
1088 'type' => 'meta',
1089 'name' => 'distancetostreetnumeric',
1090 ),
1091 'DistanceToStreetUnits' => array(
1092 'type' => 'meta',
1093 'name' => 'distancetostreetunits',
1094 ),
1095 'DistanceToWaterComments' => array(
1096 'type' => 'meta',
1097 'name' => 'distancetowatercomments',
1098 ),
1099 'DistanceToWaterNumeric' => array(
1100 'type' => 'meta',
1101 'name' => 'distancetowaternumeric',
1102 ),
1103 'DistanceToWaterUnits' => array(
1104 'type' => 'meta',
1105 'name' => 'distancetowaterunits',
1106 ),
1107 'DocumentsAvailable' => array(
1108 'type' => 'meta',
1109 'name' => 'documentsavailable',
1110 ),
1111 'DocumentsChangeTimestamp' => array(
1112 'type' => 'meta',
1113 'name' => 'documentschangetimestamp',
1114 ),
1115 'DocumentsCount' => array(
1116 'type' => 'meta',
1117 'name' => 'documentscount',
1118 ),
1119 'DocumentStatus' => array(
1120 'type' => 'meta',
1121 'name' => 'documentstatus',
1122 ),
1123 'DOH1' => array(
1124 'type' => 'meta',
1125 'name' => 'doh1',
1126 ),
1127 'DOH2' => array(
1128 'type' => 'meta',
1129 'name' => 'doh2',
1130 ),
1131 'DOH3' => array(
1132 'type' => 'meta',
1133 'name' => 'doh3',
1134 ),
1135 'DoorFeatures' => array(
1136 'type' => 'meta',
1137 'name' => 'doorfeatures',
1138 ),
1139 'DualOrVariableRateCommissionYN' => array(
1140 'type' => 'meta',
1141 'name' => 'dualorvariableratecommissionyn',
1142 ),
1143 'Electric' => array(
1144 'type' => 'meta',
1145 'name' => 'electric',
1146 ),
1147 'ElectricExpense' => array(
1148 'type' => 'meta',
1149 'name' => 'electricexpense',
1150 ),
1151 'ElectricOnPropertyYN' => array(
1152 'type' => 'taxonomy',
1153 'name' => 'property_features',
1154 'insert' => 'Electrical Utility Available',
1155 ),
1156 'ElementarySchool' => array(
1157 'type' => 'meta',
1158 'name' => 'elementaryschool',
1159 ),
1160 'ElementarySchoolDistrict' => array(
1161 'type' => 'meta',
1162 'name' => 'elementaryschooldistrict',
1163 ),
1164 'Elevation' => array(
1165 'type' => 'meta',
1166 'name' => 'elevation',
1167 ),
1168 'ElevationUnits' => array(
1169 'type' => 'meta',
1170 'name' => 'elevationunits',
1171 ),
1172 'EntryLevel' => array(
1173 'type' => 'meta',
1174 'name' => 'entrylevel',
1175 ),
1176 'EntryLocation' => array(
1177 'type' => 'meta',
1178 'name' => 'entrylocation',
1179 ),
1180 'Exclusions' => array(
1181 'type' => 'meta',
1182 'name' => 'exclusions',
1183 ),
1184 'ExistingLeaseType' => array(
1185 'type' => 'meta',
1186 'name' => 'existingleasetype',
1187 ),
1188 'ExpirationDate' => array(
1189 'type' => 'meta',
1190 'name' => 'expirationdate',
1191 ),
1192 'ExteriorFeatures' => array(
1193 'type' => 'taxonomy',
1194 'name' => 'property_features',
1195 ),
1196 'FarmCreditServiceInclYN' => array(
1197 'type' => 'taxonomy',
1198 'name' => 'property_features',
1199 'insert' => 'Farm Credit Service shares are included',
1200 ),
1201 'FarmLandAreaSource' => array(
1202 'type' => 'meta',
1203 'name' => 'farmlandareasource',
1204 ),
1205 'FarmLandAreaUnits' => array(
1206 'type' => 'meta',
1207 'name' => 'farmlandareaunits',
1208 ),
1209 'Fencing' => array(
1210 'type' => 'meta',
1211 'name' => 'fencing',
1212 ),
1213 'FhaEligibility' => array(
1214 'type' => 'meta',
1215 'name' => 'fhaeligibility',
1216 ),
1217 'FinancialDataSource' => array(
1218 'type' => 'meta',
1219 'name' => 'financialdatasource',
1220 ),
1221 'FireplaceFeatures' => array(
1222 'type' => 'meta',
1223 'name' => 'fireplacefeatures',
1224 ),
1225 'FireplacesTotal' => array(
1226 'type' => 'meta',
1227 'name' => 'fireplacestotal',
1228 ),
1229 'FireplaceYN' => array(
1230 'type' => 'taxonomy',
1231 'name' => 'property_features',
1232 'insert' => 'Has Fireplace',
1233 ),
1234 'Flooring' => array(
1235 'type' => 'meta',
1236 'name' => 'flooring',
1237 ),
1238 'FoundationArea' => array(
1239 'type' => 'meta',
1240 'name' => 'foundationarea',
1241 ),
1242 'FoundationDetails' => array(
1243 'type' => 'meta',
1244 'name' => 'foundationdetails',
1245 ),
1246 'FrontageLength' => array(
1247 'type' => 'meta',
1248 'name' => 'frontagelength',
1249 ),
1250 'FrontageType' => array(
1251 'type' => 'meta',
1252 'name' => 'frontagetype',
1253 ),
1254 'FuelExpense' => array(
1255 'type' => 'meta',
1256 'name' => 'fuelexpense',
1257 ),
1258 'Furnished' => array(
1259 'type' => 'meta',
1260 'name' => 'furnished',
1261 ),
1262 'FurnitureReplacementExpense' => array(
1263 'type' => 'meta',
1264 'name' => 'furniturereplacementexpense',
1265 ),
1266 'GarageSpaces' => array(
1267 'type' => 'meta',
1268 'name' => 'garagespaces',
1269 ),
1270 'GarageYN' => array(
1271 'type' => 'taxonomy',
1272 'name' => 'property_features',
1273 'insert' => 'Has Garage',
1274 ),
1275 'GardenerExpense' => array(
1276 'type' => 'meta',
1277 'name' => 'gardenerexpense',
1278 ),
1279 'GrazingPermitsBlmYN' => array(
1280 'type' => 'taxonomy',
1281 'name' => 'property_features',
1282 'insert' => 'Has Grazing Permits - Bureau of Land Management',
1283 ),
1284 'GrazingPermitsForestServiceYN' => array(
1285 'type' => 'taxonomy',
1286 'name' => 'property_features',
1287 'insert' => 'Has Grazing Permits - Forestry Service',
1288 ),
1289 'GrazingPermitsPrivateYN' => array(
1290 'type' => 'taxonomy',
1291 'name' => 'property_features',
1292 'insert'=>'Private Grazing Permits'
1293 ),
1294 'GreenBuildingVerification' => array(
1295 'type' => 'meta',
1296 'name' => 'greenbuildingverification',
1297 ),
1298 'GreenBuildingVerificationType' => array(
1299 'type' => 'meta',
1300 'name' => 'greenbuildingverificationtype',
1301 ),
1302 'GreenEnergyEfficient' => array(
1303 'type' => 'meta',
1304 'name' => 'greenenergyefficient',
1305 ),
1306 'GreenEnergyGeneration' => array(
1307 'type' => 'meta',
1308 'name' => 'greenenergygeneration',
1309 ),
1310 'GreenIndoorAirQuality' => array(
1311 'type' => 'meta',
1312 'name' => 'greenindoorairquality',
1313 ),
1314 'GreenLocation' => array(
1315 'type' => 'meta',
1316 'name' => 'greenlocation',
1317 ),
1318 'GreenSustainability' => array(
1319 'type' => 'meta',
1320 'name' => 'greensustainability',
1321 ),
1322 'GreenVerificationYN' => array(
1323 'type' => 'taxonomy',
1324 'name' => 'property_features',
1325 'insert'=>'Green Verification'
1326 ),
1327 'GreenWaterConservation' => array(
1328 'type' => 'meta',
1329 'name' => 'greenwaterconservation',
1330 ),
1331 'GrossIncome' => array(
1332 'type' => 'meta',
1333 'name' => 'grossincome',
1334 ),
1335 'GrossLivingAreaAnsi' => array(
1336 'type' => 'meta',
1337 'name' => 'grosslivingareaansi',
1338 ),
1339 'GrossScheduledIncome' => array(
1340 'type' => 'meta',
1341 'name' => 'grossscheduledincome',
1342 ),
1343 'HabitableResidenceYN' => array(
1344 'type' => 'taxonomy',
1345 'name' => 'property_features',
1346 'insert'=>'Habitable Residence'
1347 ),
1348 'Heating' => array(
1349 'type' => 'meta',
1350 'name' => 'heating',
1351 ),
1352 'HeatingYN' => array(
1353 'type' => 'taxonomy',
1354 'name' => 'property_features',
1355 'insert' => 'Heating System',
1356 ),
1357 'HighSchool' => array(
1358 'type' => 'meta',
1359 'name' => 'highschool',
1360 ),
1361 'HighSchoolDistrict' => array(
1362 'type' => 'meta',
1363 'name' => 'highschooldistrict',
1364 ),
1365 'HistoryTransactional' => array(
1366 'type' => 'meta',
1367 'name' => 'historytransactional',
1368 ),
1369 'HomeWarrantyYN' => array(
1370 'type' => 'taxonomy',
1371 'name' => 'property_features',
1372 'insert'=>'Home Warranty'
1373 ),
1374 'HorseAmenities' => array(
1375 'type' => 'meta',
1376 'name' => 'horseamenities',
1377 ),
1378 'HorseYN' => array(
1379 'type' => 'taxonomy',
1380 'name' => 'property_features',
1381 'insert' => 'Can Raise Horses',
1382 ),
1383 'HoursDaysOfOperation' => array(
1384 'type' => 'meta',
1385 'name' => 'hoursdaysofoperation',
1386 ),
1387 'HoursDaysOfOperationDescription' => array(
1388 'type' => 'meta',
1389 'name' => 'hoursdaysofoperationdescription',
1390 ),
1391 'Inclusions' => array(
1392 'type' => 'meta',
1393 'name' => 'inclusions',
1394 ),
1395 'IncomeIncludes' => array(
1396 'type' => 'meta',
1397 'name' => 'incomeincludes',
1398 ),
1399 'InsuranceExpense' => array(
1400 'type' => 'meta',
1401 'name' => 'insuranceexpense',
1402 ),
1403 'InteriorFeatures' => array(
1404 'type' => 'taxonomy',
1405 'name' => 'property_features',
1406 ),
1407 'InternetAddressDisplayYN' => array(
1408 'type' => 'meta',
1409 'name' => 'internetaddressdisplayyn',
1410
1411 ),
1412 'InternetAutomatedValuationDisplayYN' => array(
1413 'type' => 'meta',
1414 'name' => 'internetautomatedvaluationdisplayyn',
1415 ),
1416 'InternetConsumerCommentYN' => array(
1417 'type' => 'meta',
1418 'name' => 'internetconsumercommentyn',
1419 ),
1420 'InternetEntireListingDisplayYN' => array(
1421 'type' => 'meta',
1422 'name' => 'internetentirelistingdisplayyn',
1423 ),
1424 'IrrigationSource' => array(
1425 'type' => 'meta',
1426 'name' => 'irrigationsource',
1427 ),
1428 'IrrigationWaterRightsAcres' => array(
1429 'type' => 'meta',
1430 'name' => 'irrigationwaterrightsacres',
1431 ),
1432 'IrrigationWaterRightsYN' => array(
1433 'type' => 'taxonomy',
1434 'name' => 'property_features',
1435 'insert'=>'Irrigation Water Rights'
1436 ),
1437 'LaborInformation' => array(
1438 'type' => 'meta',
1439 'name' => 'laborinformation',
1440 ),
1441 'LandLeaseAmount' => array(
1442 'type' => 'meta',
1443 'name' => 'landleaseamount',
1444 ),
1445 'LandLeaseAmountFrequency' => array(
1446 'type' => 'meta',
1447 'name' => 'landleaseamountfrequency',
1448 ),
1449 'LandLeaseExpirationDate' => array(
1450 'type' => 'meta',
1451 'name' => 'landleaseexpirationdate',
1452 ),
1453 'LandLeaseYN' => array(
1454 'type' => 'taxonomy',
1455 'name' => 'property_features',
1456 'insert'=> 'Land Lease'
1457 ),
1458 'Latitude' => array(
1459 'type' => 'meta',
1460 'name' => 'property_latitude',
1461 ),
1462 'LaundryFeatures' => array(
1463 'type' => 'meta',
1464 'name' => 'laundryfeatures',
1465 ),
1466 'LeasableArea' => array(
1467 'type' => 'meta',
1468 'name' => 'leasablearea',
1469 ),
1470 'LeasableAreaUnits' => array(
1471 'type' => 'meta',
1472 'name' => 'leasableareaunits',
1473 ),
1474 'LeaseAmount' => array(
1475 'type' => 'meta',
1476 'name' => 'leaseamount',
1477 ),
1478 'LeaseAmountFrequency' => array(
1479 'type' => 'meta',
1480 'name' => 'leaseamountfrequency',
1481 ),
1482 'LeaseAssignableYN' => array(
1483 'type' => 'taxonomy',
1484 'name' => 'property_features',
1485 'insert'=> 'Lease Assignable'
1486 ),
1487 'LeaseConsideredYN' => array(
1488 'type' => 'taxonomy',
1489 'name' => 'property_features',
1490 'insert'=> 'Will Consider Lease'
1491 ),
1492 'LeaseExpiration' => array(
1493 'type' => 'meta',
1494 'name' => 'leaseexpiration',
1495 ),
1496 'LeaseRenewalCompensation' => array(
1497 'type' => 'meta',
1498 'name' => 'leaserenewalcompensation',
1499 ),
1500 'LeaseRenewalOptionYN' => array(
1501 'type' => 'taxonomy',
1502 'name' => 'property_features',
1503 'insert'=> 'Lease Renewal Option'
1504 ),
1505 'LeaseTerm' => array(
1506 'type' => 'meta',
1507 'name' => 'leaseterm',
1508 ),
1509 'Levels' => array(
1510 'type' => 'meta',
1511 'name' => 'levels',
1512 ),
1513 'License1' => array(
1514 'type' => 'meta',
1515 'name' => 'license1',
1516 ),
1517 'License2' => array(
1518 'type' => 'meta',
1519 'name' => 'license2',
1520 ),
1521 'License3' => array(
1522 'type' => 'meta',
1523 'name' => 'license3',
1524 ),
1525 'LicensesExpense' => array(
1526 'type' => 'meta',
1527 'name' => 'licensesexpense',
1528 ),
1529 // ---- Listing agent contact block ----
1530 'ListAgent' => array(
1531 'type' => 'meta',
1532 'name' => 'listagent',
1533 ),
1534 'ListAgentAOR' => array(
1535 'type' => 'meta',
1536 'name' => 'listagentaor',
1537 ),
1538 'ListAgentDesignation' => array(
1539 'type' => 'meta',
1540 'name' => 'listagentdesignation',
1541 ),
1542 'ListAgentDirectPhone' => array(
1543 'type' => 'meta',
1544 'name' => 'listagentdirectphone',
1545 ),
1546 'ListAgentEmail' => array(
1547 'type' => 'meta',
1548 'name' => 'listagentemail',
1549 ),
1550 'ListAgentFax' => array(
1551 'type' => 'meta',
1552 'name' => 'listagentfax',
1553 ),
1554 'ListAgentFirstName' => array(
1555 'type' => 'meta',
1556 'name' => 'listagentfirstname',
1557 ),
1558 'ListAgentFullName' => array(
1559 'type' => 'meta',
1560 'name' => 'listagentfullname',
1561 ),
1562 'ListAgentHomePhone' => array(
1563 'type' => 'meta',
1564 'name' => 'listagenthomephone',
1565 ),
1566 'ListAgentKey' => array(
1567 'type' => 'meta',
1568 'name' => 'listagentkey',
1569 ),
1570 'ListAgentLastName' => array(
1571 'type' => 'meta',
1572 'name' => 'listagentlastname',
1573 ),
1574 'ListAgentMiddleName' => array(
1575 'type' => 'meta',
1576 'name' => 'listagentmiddlename',
1577 ),
1578 'ListAgentMlsId' => array(
1579 'type' => 'meta',
1580 'name' => 'listagentmlsid',
1581 ),
1582 'ListAgentMobilePhone' => array(
1583 'type' => 'meta',
1584 'name' => 'listagentmobilephone',
1585 ),
1586 'ListAgentNamePrefix' => array(
1587 'type' => 'meta',
1588 'name' => 'listagentnameprefix',
1589 ),
1590 'ListAgentNameSuffix' => array(
1591 'type' => 'meta',
1592 'name' => 'listagentnamesuffix',
1593 ),
1594 'ListAgentNationalAssociationId' => array(
1595 'type' => 'meta',
1596 'name' => 'listagentnationalassociationid',
1597 ),
1598 'ListAgentOfficePhone' => array(
1599 'type' => 'meta',
1600 'name' => 'listagentofficephone',
1601 ),
1602 'ListAgentOfficePhoneExt' => array(
1603 'type' => 'meta',
1604 'name' => 'listagentofficephoneext',
1605 ),
1606 'ListAgentPager' => array(
1607 'type' => 'meta',
1608 'name' => 'listagentpager',
1609 ),
1610 'ListAgentPreferredPhone' => array(
1611 'type' => 'meta',
1612 'name' => 'listagentpreferredphone',
1613 ),
1614 'ListAgentPreferredPhoneExt' => array(
1615 'type' => 'meta',
1616 'name' => 'listagentpreferredphoneext',
1617 ),
1618 'ListAgentStateLicense' => array(
1619 'type' => 'meta',
1620 'name' => 'listagentstatelicense',
1621 ),
1622 'ListAgentTollFreePhone' => array(
1623 'type' => 'meta',
1624 'name' => 'listagenttollfreephone',
1625 ),
1626 'ListAgentURL' => array(
1627 'type' => 'meta',
1628 'name' => 'listagenturl',
1629 ),
1630 'ListAgentVoiceMail' => array(
1631 'type' => 'meta',
1632 'name' => 'listagentvoicemail',
1633 ),
1634 'ListAgentVoiceMailExt' => array(
1635 'type' => 'meta',
1636 'name' => 'listagentvoicemailext',
1637 ),
1638 'ListAOR' => array(
1639 'type' => 'meta',
1640 'name' => 'listaor',
1641 ),
1642 'ListingAgreement' => array(
1643 'type' => 'meta',
1644 'name' => 'listingagreement',
1645 ),
1646 'ListingContractDate' => array(
1647 'type' => 'meta',
1648 'name' => 'listingcontractdate',
1649 ),
1650 'ListingId' => array(
1651 'type' => 'meta',
1652 'name' => 'listingid',
1653 ),
1654 'ListingKey' => array(
1655 'type' => 'meta',
1656 'name' => 'listingkey',
1657 ),
1658 'ListingService' => array(
1659 'type' => 'meta',
1660 'name' => 'listingservice',
1661 ),
1662 'ListingTerms' => array(
1663 'type' => 'meta',
1664 'name' => 'listingterms',
1665 ),
1666 'ListingURL' => array(
1667 'type' => 'meta',
1668 'name' => 'listingurl',
1669 ),
1670 'ListingURLDescription' => array(
1671 'type' => 'meta',
1672 'name' => 'listingurldescription',
1673 ),
1674 // ---- Listing office / brokerage block ----
1675 'ListOffice' => array(
1676 'type' => 'meta',
1677 'name' => 'listoffice',
1678 ),
1679 'ListOfficeAOR' => array(
1680 'type' => 'meta',
1681 'name' => 'listofficeaor',
1682 ),
1683 'ListOfficeEmail' => array(
1684 'type' => 'meta',
1685 'name' => 'listofficeemail',
1686 ),
1687 'ListOfficeFax' => array(
1688 'type' => 'meta',
1689 'name' => 'listofficefax',
1690 ),
1691 'ListOfficeKey' => array(
1692 'type' => 'meta',
1693 'name' => 'listofficekey',
1694 ),
1695 'ListOfficeMlsId' => array(
1696 'type' => 'meta',
1697 'name' => 'listofficemlsid',
1698 ),
1699 'ListOfficeName' => array(
1700 'type' => 'meta',
1701 'name' => 'listofficename',
1702 ),
1703 'ListOfficeNationalAssociationId' => array(
1704 'type' => 'meta',
1705 'name' => 'listofficenationalassociationid',
1706 ),
1707 'ListOfficePhone' => array(
1708 'type' => 'meta',
1709 'name' => 'listofficephone',
1710 ),
1711 'ListOfficePhoneExt' => array(
1712 'type' => 'meta',
1713 'name' => 'listofficephoneext',
1714 ),
1715 'ListOfficeURL' => array(
1716 'type' => 'meta',
1717 'name' => 'listofficeurl',
1718 ),
1719 // ---- Core theme fields: ListPrice/LivingArea/LotSize/Lat-Long map to theme meta keys ----
1720 'ListPrice' => array(
1721 'type' => 'meta',
1722 'name' => 'property_price',
1723 ),
1724 'ListPriceLow' => array(
1725 'type' => 'meta',
1726 'name' => 'listpricelow',
1727 ),
1728 'ListTeam' => array(
1729 'type' => 'meta',
1730 'name' => 'listteam',
1731 ),
1732 'ListTeamKey' => array(
1733 'type' => 'meta',
1734 'name' => 'listteamkey',
1735 ),
1736 'ListTeamName' => array(
1737 'type' => 'meta',
1738 'name' => 'listteamname',
1739 ),
1740 'LivingArea' => array(
1741 'type' => 'meta',
1742 'name' => 'property_size',
1743 ),
1744 'LivingAreaSource' => array(
1745 'type' => 'meta',
1746 'name' => 'livingareasource',
1747 ),
1748 'LivingAreaUnits' => array(
1749 'type' => 'meta',
1750 'name' => 'livingareaunits',
1751 ),
1752 'LockBoxLocation' => array(
1753 'type' => 'meta',
1754 'name' => 'lockboxlocation',
1755 ),
1756 'LockBoxSerialNumber' => array(
1757 'type' => 'meta',
1758 'name' => 'lockboxserialnumber',
1759 ),
1760 'LockBoxType' => array(
1761 'type' => 'meta',
1762 'name' => 'lockboxtype',
1763 ),
1764 'Longitude' => array(
1765 'type' => 'meta',
1766 'name' => 'property_longitude',
1767 ),
1768 'LotDimensionsSource' => array(
1769 'type' => 'meta',
1770 'name' => 'lotdimensionssource',
1771 ),
1772 'LotFeatures' => array(
1773 'type' => 'meta',
1774 'name' => 'lotfeatures',
1775 ),
1776 'LotSizeAcres' => array(
1777 'type' => 'meta',
1778 'name' => 'property_lot_size',
1779 ),
1780 'LotSizeArea' => array(
1781 'type' => 'meta',
1782 'name' => 'lotsizearea',
1783 ),
1784 'LotSizeDimensions' => array(
1785 'type' => 'meta',
1786 'name' => 'lotsizedimensions',
1787 ),
1788 'LotSizeSource' => array(
1789 'type' => 'meta',
1790 'name' => 'lotsizesource',
1791 ),
1792 'LotSizeSquareFeet' => array(
1793 'type' => 'meta',
1794 'name' => 'lotsizesquarefeet',
1795 ),
1796 'LotSizeUnits' => array(
1797 'type' => 'meta',
1798 'name' => 'lotsizeunits',
1799 ),
1800 'MainLevelBathrooms' => array(
1801 'type' => 'meta',
1802 'name' => 'mainlevelbathrooms',
1803 ),
1804 'MainLevelBedrooms' => array(
1805 'type' => 'meta',
1806 'name' => 'mainlevelbedrooms',
1807 ),
1808 'MaintenanceExpense' => array(
1809 'type' => 'meta',
1810 'name' => 'maintenanceexpense',
1811 ),
1812 'MajorChangeTimestamp' => array(
1813 'type' => 'meta',
1814 'name' => 'majorchangetimestamp',
1815 ),
1816 'MajorChangeType' => array(
1817 'type' => 'meta',
1818 'name' => 'majorchangetype',
1819 ),
1820 'Make' => array(
1821 'type' => 'meta',
1822 'name' => 'make',
1823 ),
1824 'ManagerExpense' => array(
1825 'type' => 'meta',
1826 'name' => 'managerexpense',
1827 ),
1828 'MapCoordinate' => array(
1829 'type' => 'meta',
1830 'name' => 'mapcoordinate',
1831 ),
1832 'MapCoordinateSource' => array(
1833 'type' => 'meta',
1834 'name' => 'mapcoordinatesource',
1835 ),
1836 'MapURL' => array(
1837 'type' => 'meta',
1838 'name' => 'mapurl',
1839 ),
1840 // ---- Media: routed to the gallery/attachment importer rather than a meta key ----
1841 'Media' => array(
1842 'type' => 'media',
1843 'name' => 'media',
1844 ),
1845 'MiddleOrJuniorSchool' => array(
1846 'type' => 'meta',
1847 'name' => 'middleorjuniorschool',
1848 ),
1849 'MiddleOrJuniorSchoolDistrict' => array(
1850 'type' => 'meta',
1851 'name' => 'middleorjuniorschooldistrict',
1852 ),
1853 'MLSAreaMajor' => array(
1854 'type' => 'meta',
1855 'name' => 'mlsareamajor',
1856 ),
1857 'MLSAreaMinor' => array(
1858 'type' => 'meta',
1859 'name' => 'mlsareaminor',
1860 ),
1861 'MlsStatus' => array(
1862 'type' => 'meta',
1863 'name' => 'mlsstatus',
1864 ),
1865 'MobileDimUnits' => array(
1866 'type' => 'meta',
1867 'name' => 'mobiledimunits',
1868 ),
1869 'MobileHomeRemainsYN' => array(
1870 'type' => 'taxonomy',
1871 'name' => 'property_features',
1872 'insert'=> 'Mobile Home Remains'
1873 ),
1874 'MobileLength' => array(
1875 'type' => 'meta',
1876 'name' => 'mobilelength',
1877 ),
1878 'MobileWidth' => array(
1879 'type' => 'meta',
1880 'name' => 'mobilewidth',
1881 ),
1882 'Model' => array(
1883 'type' => 'meta',
1884 'name' => 'model',
1885 ),
1886 'ModificationTimestamp' => array(
1887 'type' => 'meta',
1888 'name' => 'modificationtimestamp',
1889 ),
1890 'NetOperatingIncome' => array(
1891 'type' => 'meta',
1892 'name' => 'netoperatingincome',
1893 ),
1894 'NewConstructionYN' => array(
1895 'type' => 'taxonomy',
1896 'name' => 'property_features',
1897 'insert' => 'New Construction',
1898 ),
1899 'NewTaxesExpense' => array(
1900 'type' => 'meta',
1901 'name' => 'newtaxesexpense',
1902 ),
1903 'NumberOfBuildings' => array(
1904 'type' => 'meta',
1905 'name' => 'numberofbuildings',
1906 ),
1907 'NumberOfFullTimeEmployees' => array(
1908 'type' => 'meta',
1909 'name' => 'numberoffulltimeemployees',
1910 ),
1911 'NumberOfLots' => array(
1912 'type' => 'meta',
1913 'name' => 'numberoflots',
1914 ),
1915 'NumberOfPads' => array(
1916 'type' => 'meta',
1917 'name' => 'numberofpads',
1918 ),
1919 'NumberOfPartTimeEmployees' => array(
1920 'type' => 'meta',
1921 'name' => 'numberofparttimeemployees',
1922 ),
1923 'NumberOfSeparateElectricMeters' => array(
1924 'type' => 'meta',
1925 'name' => 'numberofseparateelectricmeters',
1926 ),
1927 'NumberOfSeparateGasMeters' => array(
1928 'type' => 'meta',
1929 'name' => 'numberofseparategasmeters',
1930 ),
1931 'NumberOfSeparateWaterMeters' => array(
1932 'type' => 'meta',
1933 'name' => 'numberofseparatewatermeters',
1934 ),
1935 'NumberOfUnitsInCommunity' => array(
1936 'type' => 'meta',
1937 'name' => 'numberofunitsincommunity',
1938 ),
1939 'NumberOfUnitsLeased' => array(
1940 'type' => 'meta',
1941 'name' => 'numberofunitsleased',
1942 ),
1943 'NumberOfUnitsMoMo' => array(
1944 'type' => 'meta',
1945 'name' => 'numberofunitsmomo',
1946 ),
1947 'NumberOfUnitsTotal' => array(
1948 'type' => 'meta',
1949 'name' => 'numberofunitstotal',
1950 ),
1951 'NumberOfUnitsVacant' => array(
1952 'type' => 'meta',
1953 'name' => 'numberofunitsvacant',
1954 ),
1955 'OccupantName' => array(
1956 'type' => 'meta',
1957 'name' => 'occupantname',
1958 ),
1959 'OccupantPhone' => array(
1960 'type' => 'meta',
1961 'name' => 'occupantphone',
1962 ),
1963 'OccupantType' => array(
1964 'type' => 'meta',
1965 'name' => 'occupanttype',
1966 ),
1967 'OffMarketDate' => array(
1968 'type' => 'meta',
1969 'name' => 'offmarketdate',
1970 ),
1971 'OffMarketTimestamp' => array(
1972 'type' => 'meta',
1973 'name' => 'offmarkettimestamp',
1974 ),
1975 'OnMarketDate' => array(
1976 'type' => 'meta',
1977 'name' => 'onmarketdate',
1978 ),
1979 'OnMarketTimestamp' => array(
1980 'type' => 'meta',
1981 'name' => 'onmarkettimestamp',
1982 ),
1983 'OpenHouse' => array(
1984 'type' => 'meta',
1985 'name' => 'openhouse',
1986 ),
1987 'OpenHouseModificationTimestamp' => array(
1988 'type' => 'meta',
1989 'name' => 'openhousemodificationtimestamp',
1990 ),
1991 'OpenParkingSpaces' => array(
1992 'type' => 'meta',
1993 'name' => 'openparkingspaces',
1994 ),
1995 'OpenParkingYN' => array(
1996 'type' => 'taxonomy',
1997 'name' => 'property_features',
1998 'insert' => 'Open Parking',
1999 ),
2000 'OperatingExpense' => array(
2001 'type' => 'meta',
2002 'name' => 'operatingexpense',
2003 ),
2004 'OperatingExpenseIncludes' => array(
2005 'type' => 'meta',
2006 'name' => 'operatingexpenseincludes',
2007 ),
2008 'OriginalEntryTimestamp' => array(
2009 'type' => 'meta',
2010 'name' => 'originalentrytimestamp',
2011 ),
2012 'OriginalListPrice' => array(
2013 'type' => 'meta',
2014 'name' => 'originallistprice',
2015 ),
2016 'OriginatingSystem' => array(
2017 'type' => 'meta',
2018 'name' => 'originatingsystem',
2019 ),
2020 'OriginatingSystemID' => array(
2021 'type' => 'meta',
2022 'name' => 'originatingsystemid',
2023 ),
2024 'OriginatingSystemKey' => array(
2025 'type' => 'meta',
2026 'name' => 'originatingsystemkey',
2027 ),
2028 'OriginatingSystemName' => array(
2029 'type' => 'meta',
2030 'name' => 'originatingsystemname',
2031 ),
2032 'OtherEquipment' => array(
2033 'type' => 'meta',
2034 'name' => 'otherequipment',
2035 ),
2036 'OtherExpense' => array(
2037 'type' => 'meta',
2038 'name' => 'otherexpense',
2039 ),
2040 'OtherParking' => array(
2041 'type' => 'meta',
2042 'name' => 'otherparking',
2043 ),
2044 'OtherStructures' => array(
2045 'type' => 'meta',
2046 'name' => 'otherstructures',
2047 ),
2048 'OwnerName' => array(
2049 'type' => 'meta',
2050 'name' => 'ownername',
2051 ),
2052 'OwnerPays' => array(
2053 'type' => 'meta',
2054 'name' => 'ownerpays',
2055 ),
2056 'OwnerPhone' => array(
2057 'type' => 'meta',
2058 'name' => 'ownerphone',
2059 ),
2060 'Ownership' => array(
2061 'type' => 'meta',
2062 'name' => 'ownership',
2063 ),
2064 'OwnershipType' => array(
2065 'type' => 'meta',
2066 'name' => 'ownershiptype',
2067 ),
2068 'ParcelNumber' => array(
2069 'type' => 'meta',
2070 'name' => 'parcelnumber',
2071 ),
2072 'ParkingFeatures' => array(
2073 'type' => 'meta',
2074 'name' => 'parkingfeatures',
2075 ),
2076 'ParkingTotal' => array(
2077 'type' => 'meta',
2078 'name' => 'parkingtotal',
2079 ),
2080 'ParkManagerName' => array(
2081 'type' => 'meta',
2082 'name' => 'parkmanagername',
2083 ),
2084 'ParkManagerPhone' => array(
2085 'type' => 'meta',
2086 'name' => 'parkmanagerphone',
2087 ),
2088 'ParkName' => array(
2089 'type' => 'meta',
2090 'name' => 'parkname',
2091 ),
2092 'PastureArea' => array(
2093 'type' => 'meta',
2094 'name' => 'pasturearea',
2095 ),
2096 'PatioAndPorchFeatures' => array(
2097 'type' => 'meta',
2098 'name' => 'patioandporchfeatures',
2099 ),
2100 'PendingTimestamp' => array(
2101 'type' => 'meta',
2102 'name' => 'pendingtimestamp',
2103 ),
2104 'PestControlExpense' => array(
2105 'type' => 'meta',
2106 'name' => 'pestcontrolexpense',
2107 ),
2108 'PetsAllowed' => array(
2109 'type' => 'meta',
2110 'name' => 'petsallowed',
2111 ),
2112 'PhotosChangeTimestamp' => array(
2113 'type' => 'meta',
2114 'name' => 'photoschangetimestamp',
2115 ),
2116 'PhotosCount' => array(
2117 'type' => 'meta',
2118 'name' => 'photoscount',
2119 ),
2120 'PoolExpense' => array(
2121 'type' => 'meta',
2122 'name' => 'poolexpense',
2123 ),
2124 'PoolFeatures' => array(
2125 'type' => 'meta',
2126 'name' => 'poolfeatures',
2127 ),
2128 'PoolPrivateYN' => array(
2129 'type' => 'taxonomy',
2130 'name' => 'property_features',
2131 'insert' => 'Private Pool',
2132 ),
2133 'Possession' => array(
2134 'type' => 'meta',
2135 'name' => 'possession',
2136 ),
2137 'PossibleUse' => array(
2138 'type' => 'meta',
2139 'name' => 'possibleuse',
2140 ),
2141 'PostalCity' => array(
2142 'type' => 'meta',
2143 'name' => 'postalcity',
2144 ),
2145 'PostalCode' => array(
2146 'type' => 'meta',
2147 'name' => 'property_zip',
2148 ),
2149 'PostalCodePlus4' => array(
2150 'type' => 'meta',
2151 'name' => 'postalcodeplus4',
2152 ),
2153 'PowerProduction' => array(
2154 'type' => 'meta',
2155 'name' => 'powerproduction',
2156 ),
2157 'PowerProductionType' => array(
2158 'type' => 'meta',
2159 'name' => 'powerproductiontype',
2160 ),
2161 'PowerProductionYN' => array(
2162 'type' => 'taxonomy',
2163 'name' => 'property_features',
2164 'insert'=> 'Power Production System'
2165 ),
2166 'PreviousListPrice' => array(
2167 'type' => 'meta',
2168 'name' => 'previouslistprice',
2169 ),
2170 'PriceChangeTimestamp' => array(
2171 'type' => 'meta',
2172 'name' => 'pricechangetimestamp',
2173 ),
2174 'PrivateOfficeRemarks' => array(
2175 'type' => 'meta',
2176 'name' => 'privateofficeremarks',
2177 ),
2178 'PrivateRemarks' => array(
2179 'type' => 'meta',
2180 'name' => 'owner_notes',
2181 ),
2182 'ProfessionalManagementExpense' => array(
2183 'type' => 'meta',
2184 'name' => 'professionalmanagementexpense',
2185 ),
2186 'PropertyAttachedYN' => array(
2187 'type' => 'taxonomy',
2188 'name' => 'property_features',
2189 'insert' => 'Property Attached',
2190 ),
2191 'PropertyCondition' => array(
2192 'type' => 'meta',
2193 'name' => 'propertycondition',
2194 ),
2195 'PropertySubType' => array(
2196 'type' => 'taxonomy',
2197 'name' => 'property_category',
2198 ),
2199 'PropertyTimeZoneName' => array(
2200 'type' => 'meta',
2201 'name' => 'propertytimezonename',
2202 ),
2203 'PropertyTimeZoneObservesDstYN' => array(
2204 'type' => 'taxonomy',
2205 'name' => 'property_features',
2206 'insert'=> 'Property Time Zone Observes DST'
2207 ),
2208 'PropertyTimeZoneStandardOffset' => array(
2209 'type' => 'meta',
2210 'name' => 'propertytimezonestandardoffset',
2211 ),
2212 'PropertyType' => array(
2213 'type' => 'taxonomy',
2214 'name' => 'property_action_category',
2215 ),
2216 // ---- PublicRemarks -> the post content body (the public listing description) ----
2217 'PublicRemarks' => array(
2218 'type' => 'content',
2219 'name' => 'content',
2220 ),
2221 'PublicSurveyRange' => array(
2222 'type' => 'meta',
2223 'name' => 'publicsurveyrange',
2224 ),
2225 'PublicSurveySection' => array(
2226 'type' => 'meta',
2227 'name' => 'publicsurveysection',
2228 ),
2229 'PublicSurveyTownship' => array(
2230 'type' => 'meta',
2231 'name' => 'publicsurveytownship',
2232 ),
2233 'PurchaseContractDate' => array(
2234 'type' => 'meta',
2235 'name' => 'purchasecontractdate',
2236 ),
2237 'RangeArea' => array(
2238 'type' => 'meta',
2239 'name' => 'rangearea',
2240 ),
2241 'RentControlYN' => array(
2242 'type' => 'taxonomy',
2243 'name' => 'property_features',
2244 'insert'=> 'Rent Control Area'
2245 ),
2246 'RentIncludes' => array(
2247 'type' => 'meta',
2248 'name' => 'rentincludes',
2249 ),
2250 'RoadFrontageType' => array(
2251 'type' => 'meta',
2252 'name' => 'roadfrontagetype',
2253 ),
2254 'RoadResponsibility' => array(
2255 'type' => 'meta',
2256 'name' => 'roadresponsibility',
2257 ),
2258 'RoadSurfaceType' => array(
2259 'type' => 'meta',
2260 'name' => 'roadsurfacetype',
2261 ),
2262 'Roof' => array(
2263 'type' => 'meta',
2264 'name' => 'roof',
2265 ),
2266 'Rooms' => array(
2267 'type' => 'meta',
2268 'name' => 'rooms',
2269 ),
2270 'RoomsTotal' => array(
2271 'type' => 'meta',
2272 'name' => 'property_rooms',
2273 ),
2274 'RoomType' => array(
2275 'type' => 'meta',
2276 'name' => 'roomtype',
2277 ),
2278 'RVParkingDimensions' => array(
2279 'type' => 'meta',
2280 'name' => 'rvparkingdimensions',
2281 ),
2282 'SeatingCapacity' => array(
2283 'type' => 'meta',
2284 'name' => 'seatingcapacity',
2285 ),
2286 'SecurityFeatures' => array(
2287 'type' => 'meta',
2288 'name' => 'securityfeatures',
2289 ),
2290 'SeniorCommunityYN' => array(
2291 'type' => 'taxonomy',
2292 'name' => 'property_features',
2293 'insert' => 'Senior Community',
2294 ),
2295 'SerialU' => array(
2296 'type' => 'meta',
2297 'name' => 'serialu',
2298 ),
2299 'SerialX' => array(
2300 'type' => 'meta',
2301 'name' => 'serialx',
2302 ),
2303 'SerialXX' => array(
2304 'type' => 'meta',
2305 'name' => 'serialxx',
2306 ),
2307 'Sewer' => array(
2308 'type' => 'meta',
2309 'name' => 'sewer',
2310 ),
2311 'ShowingAdvanceNotice' => array(
2312 'type' => 'meta',
2313 'name' => 'showingadvancenotice',
2314 ),
2315 'ShowingAttendedYN' => array(
2316 'type' => 'taxonomy',
2317 'name' => 'property_features',
2318 'insert'=> 'Requires An Attended Showing'
2319 ),
2320 'ShowingConsiderations' => array(
2321 'type' => 'meta',
2322 'name' => 'showingconsiderations',
2323 ),
2324 'ShowingContactName' => array(
2325 'type' => 'meta',
2326 'name' => 'showingcontactname',
2327 ),
2328 'ShowingContactPhone' => array(
2329 'type' => 'meta',
2330 'name' => 'showingcontactphone',
2331 ),
2332 'ShowingContactPhoneExt' => array(
2333 'type' => 'meta',
2334 'name' => 'showingcontactphoneext',
2335 ),
2336 'ShowingContactType' => array(
2337 'type' => 'meta',
2338 'name' => 'showingcontacttype',
2339 ),
2340 'ShowingDays' => array(
2341 'type' => 'meta',
2342 'name' => 'showingdays',
2343 ),
2344 'ShowingEndTime' => array(
2345 'type' => 'meta',
2346 'name' => 'showingendtime',
2347 ),
2348 'ShowingInstructions' => array(
2349 'type' => 'meta',
2350 'name' => 'showinginstructions',
2351 ),
2352 'ShowingRequirements' => array(
2353 'type' => 'meta',
2354 'name' => 'showingrequirements',
2355 ),
2356 'ShowingServiceName' => array(
2357 'type' => 'meta',
2358 'name' => 'showingservicename',
2359 ),
2360 'ShowingStartTime' => array(
2361 'type' => 'meta',
2362 'name' => 'showingstarttime',
2363 ),
2364 'SignOnPropertyYN' => array(
2365 'type' => 'taxonomy',
2366 'name' => 'property_features',
2367 'insert'=> 'Sign On Property'
2368 ),
2369 'SimpleDaysOnMarket' => array(
2370 'type' => 'meta',
2371 'name' => 'simpledaysonmarket',
2372 ),
2373 'Skirt' => array(
2374 'type' => 'meta',
2375 'name' => 'skirt',
2376 ),
2377 'SocialMedia' => array(
2378 'type' => 'meta',
2379 'name' => 'socialmedia',
2380 ),
2381 'SourceSystem' => array(
2382 'type' => 'meta',
2383 'name' => 'sourcesystem',
2384 ),
2385 'SourceSystemID' => array(
2386 'type' => 'meta',
2387 'name' => 'sourcesystemid',
2388 ),
2389 'SourceSystemKey' => array(
2390 'type' => 'meta',
2391 'name' => 'sourcesystemkey',
2392 ),
2393 'SourceSystemName' => array(
2394 'type' => 'meta',
2395 'name' => 'sourcesystemname',
2396 ),
2397 'SpaFeatures' => array(
2398 'type' => 'meta',
2399 'name' => 'spafeatures',
2400 ),
2401 'SpaYN' => array(
2402 'type' => 'taxonomy',
2403 'name' => 'property_features',
2404 'insert' => 'Spa',
2405 ),
2406 'SpecialLicenses' => array(
2407 'type' => 'meta',
2408 'name' => 'speciallicenses',
2409 ),
2410 'SpecialListingConditions' => array(
2411 'type' => 'meta',
2412 'name' => 'speciallistingconditions',
2413 ),
2414 'StandardStatus' => array(
2415 'type' => 'taxonomy',
2416 'name' => 'property_status',
2417 ),
2418 'StartShowingDate' => array(
2419 'type' => 'meta',
2420 'name' => 'startshowingdate',
2421 ),
2422 'StateOrProvince' => array(
2423 'type' => 'meta',
2424 'name' => 'stateorprovince',
2425 ),
2426 'StateRegion' => array(
2427 'type' => 'meta',
2428 'name' => 'stateregion',
2429 ),
2430 'StatusChangeTimestamp' => array(
2431 'type' => 'meta',
2432 'name' => 'statuschangetimestamp',
2433 ),
2434 'Stories' => array(
2435 'type' => 'meta',
2436 'name' => 'stories',
2437 ),
2438 'StoriesTotal' => array(
2439 'type' => 'meta',
2440 'name' => 'storiestotal',
2441 ),
2442 'StreetAdditionalInfo' => array(
2443 'type' => 'meta',
2444 'name' => 'streetadditionalinfo',
2445 ),
2446 'StreetDirPrefix' => array(
2447 'type' => 'meta',
2448 'name' => 'streetdirprefix',
2449 ),
2450 'StreetDirSuffix' => array(
2451 'type' => 'meta',
2452 'name' => 'streetdirsuffix',
2453 ),
2454 'StreetName' => array(
2455 'type' => 'meta',
2456 'name' => 'streetname',
2457 ),
2458 'StreetNumber' => array(
2459 'type' => 'meta',
2460 'name' => 'streetnumber',
2461 ),
2462 'StreetNumberNumeric' => array(
2463 'type' => 'meta',
2464 'name' => 'streetnumbernumeric',
2465 ),
2466 'StreetSuffix' => array(
2467 'type' => 'meta',
2468 'name' => 'streetsuffix',
2469 ),
2470 'StreetSuffixModifier' => array(
2471 'type' => 'meta',
2472 'name' => 'streetsuffixmodifier',
2473 ),
2474 'StructureType' => array(
2475 'type' => 'meta',
2476 'name' => 'structuretype',
2477 ),
2478 'SubAgencyCompensation' => array(
2479 'type' => 'meta',
2480 'name' => 'subagencycompensation',
2481 ),
2482 'SubAgencyCompensationType' => array(
2483 'type' => 'meta',
2484 'name' => 'subagencycompensationtype',
2485 ),
2486 'SubdivisionName' => array(
2487 'type' => 'taxonomy',
2488 'name' => 'property_area',
2489 ),
2490 'SuppliesExpense' => array(
2491 'type' => 'meta',
2492 'name' => 'suppliesexpense',
2493 ),
2494 'SyndicateTo' => array(
2495 'type' => 'meta',
2496 'name' => 'syndicateto',
2497 ),
2498 'SyndicationRemarks' => array(
2499 'type' => 'meta',
2500 'name' => 'syndicationremarks',
2501 ),
2502 // ---- Tax / assessment block ----
2503 'TaxAnnualAmount' => array(
2504 'type' => 'meta',
2505 'name' => 'taxannualamount',
2506 ),
2507 'TaxAnnualAmountPerLivingAreaUnit' => array(
2508 'type' => 'meta',
2509 'name' => 'taxannualamountperlivingareaunit',
2510 ),
2511 'TaxAnnualAmountPerSquareFoot' => array(
2512 'type' => 'meta',
2513 'name' => 'taxannualamountpersquarefoot',
2514 ),
2515 'TaxAssessedValue' => array(
2516 'type' => 'meta',
2517 'name' => 'taxassessedvalue',
2518 ),
2519 'TaxBlock' => array(
2520 'type' => 'meta',
2521 'name' => 'taxblock',
2522 ),
2523 'TaxBookNumber' => array(
2524 'type' => 'meta',
2525 'name' => 'taxbooknumber',
2526 ),
2527 'TaxLegalDescription' => array(
2528 'type' => 'meta',
2529 'name' => 'taxlegaldescription',
2530 ),
2531 'TaxLot' => array(
2532 'type' => 'meta',
2533 'name' => 'taxlot',
2534 ),
2535 'TaxMapNumber' => array(
2536 'type' => 'meta',
2537 'name' => 'taxmapnumber',
2538 ),
2539 'TaxOtherAnnualAssessmentAmount' => array(
2540 'type' => 'meta',
2541 'name' => 'taxotherannualassessmentamount',
2542 ),
2543 'TaxParcelLetter' => array(
2544 'type' => 'meta',
2545 'name' => 'taxparcelletter',
2546 ),
2547 'TaxStatusCurrent' => array(
2548 'type' => 'meta',
2549 'name' => 'taxstatuscurrent',
2550 ),
2551 'TaxTract' => array(
2552 'type' => 'meta',
2553 'name' => 'taxtract',
2554 ),
2555 'TaxYear' => array(
2556 'type' => 'meta',
2557 'name' => 'taxyear',
2558 ),
2559 'TenantPays' => array(
2560 'type' => 'meta',
2561 'name' => 'tenantpays',
2562 ),
2563 'Topography' => array(
2564 'type' => 'meta',
2565 'name' => 'topography',
2566 ),
2567 'TotalActualRent' => array(
2568 'type' => 'meta',
2569 'name' => 'totalactualrent',
2570 ),
2571 'Township' => array(
2572 'type' => 'meta',
2573 'name' => 'township',
2574 ),
2575 'TransactionBrokerCompensation' => array(
2576 'type' => 'meta',
2577 'name' => 'transactionbrokercompensation',
2578 ),
2579 'TransactionBrokerCompensationType' => array(
2580 'type' => 'meta',
2581 'name' => 'transactionbrokercompensationtype',
2582 ),
2583 'TrashExpense' => array(
2584 'type' => 'meta',
2585 'name' => 'trashexpense',
2586 ),
2587 'UnitNumber' => array(
2588 'type' => 'meta',
2589 'name' => 'unitnumber',
2590 ),
2591 'UnitsFurnished' => array(
2592 'type' => 'meta',
2593 'name' => 'unitsfurnished',
2594 ),
2595 'UnitTypes' => array(
2596 'type' => 'meta',
2597 'name' => 'unittypes',
2598 ),
2599 'UnitTypeType' => array(
2600 'type' => 'meta',
2601 'name' => 'unittypetype',
2602 ),
2603 'UniversalPropertyId' => array(
2604 'type' => 'meta',
2605 'name' => 'universalpropertyid',
2606 ),
2607 'UniversalPropertySubId' => array(
2608 'type' => 'meta',
2609 'name' => 'universalpropertysubid',
2610 ),
2611 'UnparsedAddress' => array(
2612 'type' => 'meta',
2613 'name' => 'property_address',
2614 ),
2615 'Utilities' => array(
2616 'type' => 'meta',
2617 'name' => 'utilities',
2618 ),
2619 'VacancyAllowance' => array(
2620 'type' => 'meta',
2621 'name' => 'vacancyallowance',
2622 ),
2623 'VacancyAllowanceRate' => array(
2624 'type' => 'meta',
2625 'name' => 'vacancyallowancerate',
2626 ),
2627 'Vegetation' => array(
2628 'type' => 'meta',
2629 'name' => 'vegetation',
2630 ),
2631 'VideosChangeTimestamp' => array(
2632 'type' => 'meta',
2633 'name' => 'videoschangetimestamp',
2634 ),
2635 'VideosCount' => array(
2636 'type' => 'meta',
2637 'name' => 'videoscount',
2638 ),
2639 'View' => array(
2640 'type' => 'meta',
2641 'name' => 'view',
2642 ),
2643 'ViewYN' => array(
2644 'type' => 'taxonomy',
2645 'name' => 'property_features',
2646 'insert' => 'Has a View',
2647 ),
2648 'VirtualTourURLBranded' => array(
2649 'type' => 'meta',
2650 'name' => 'virtualtoururlbranded',
2651 ),
2652 'VirtualTourURLUnbranded' => array(
2653 'type' => 'meta',
2654 'name' => 'embed_virtual_tour',
2655 ),
2656 'WalkScore' => array(
2657 'type' => 'meta',
2658 'name' => 'walkscore',
2659 ),
2660 'WaterBodyName' => array(
2661 'type' => 'meta',
2662 'name' => 'waterbodyname',
2663 ),
2664 'WaterfrontFeatures' => array(
2665 'type' => 'meta',
2666 'name' => 'waterfrontfeatures',
2667 ),
2668 'WaterfrontYN' => array(
2669 'type' => 'taxonomy',
2670 'name' => 'property_features',
2671 'insert' => 'Has Waterfront',
2672 ),
2673 'WaterSewerExpense' => array(
2674 'type' => 'meta',
2675 'name' => 'watersewerexpense',
2676 ),
2677 'WaterSource' => array(
2678 'type' => 'meta',
2679 'name' => 'watersource',
2680 ),
2681 'WindowFeatures' => array(
2682 'type' => 'meta',
2683 'name' => 'windowfeatures',
2684 ),
2685 'WithdrawnDate' => array(
2686 'type' => 'meta',
2687 'name' => 'withdrawndate',
2688 ),
2689 'WoodedArea' => array(
2690 'type' => 'meta',
2691 'name' => 'woodedarea',
2692 ),
2693 'WorkmansCompensationExpense' => array(
2694 'type' => 'meta',
2695 'name' => 'workmanscompensationexpense',
2696 ),
2697 // ---- Year built / establishment & zoning (tail of the map) ----
2698 'YearBuilt' => array(
2699 'type' => 'meta',
2700 'name' => 'yearbuilt',
2701 ),
2702 'YearBuiltDetails' => array(
2703 'type' => 'meta',
2704 'name' => 'yearbuiltdetails',
2705 ),
2706 'YearBuiltEffective' => array(
2707 'type' => 'meta',
2708 'name' => 'yearbuilteffective',
2709 ),
2710 'YearBuiltSource' => array(
2711 'type' => 'meta',
2712 'name' => 'yearbuiltsource',
2713 ),
2714 'YearEstablished' => array(
2715 'type' => 'meta',
2716 'name' => 'yearestablished',
2717 ),
2718 'YearsCurrentOwner' => array(
2719 'type' => 'meta',
2720 'name' => 'yearscurrentowner',
2721 ),
2722 'Zoning' => array(
2723 'type' => 'meta',
2724 'name' => 'zoning',
2725 ),
2726 'ZoningDescription' => array(
2727 'type' => 'meta',
2728 'name' => 'zoningdescription',
2729 ),
2730 );
2731 // Hand the completed map back to the caller.
2732 return $theme_schema;
2733 }
2734
2735
2736 /**
2737 * Build a slug => label map of the taxonomies registered for a post type.
2738 *
2739 * @param string $post_type Post type name to inspect.
2740 * @return array Associative array of taxonomy slug => human-readable label.
2741 */
2742 function mlsimport_get_custom_post_type_taxonomies($post_type) {
2743 // Get the taxonomies associated with the custom post type
2744 $taxonomies = get_object_taxonomies($post_type , 'objects');
2745
2746 // Initialize an array to hold the slug => label pairs
2747 $taxonomy_array = array();
2748
2749 // Loop through the taxonomies and fill the array
2750 foreach ($taxonomies as $taxonomy_slug => $taxonomy) {
2751 // Key by slug, store the taxonomy's display label.
2752 $taxonomy_array[$taxonomy_slug] = $taxonomy->label;
2753 }
2754
2755 return $taxonomy_array;
2756 }
2757
2758
2759 /*
2760 *
2761 * Request list of ready to go MLS
2762 *
2763 *
2764 */
2765
2766 /**
2767 * Whitelist of HTML tags/attributes allowed in MLSImport-rendered content.
2768 *
2769 * Intended for use with wp_kses() when echoing plugin-generated markup: keeps a
2770 * small set of formatting tags plus the form controls (select/option/input/
2771 * fieldset/label) the admin UI emits. (The preceding block comment is a stale
2772 * copy/paste and does not describe this function.)
2773 *
2774 * @return array Tag => allowed-attributes map in wp_kses() format.
2775 */
2776 function mlsimport_allowed_html_tags_content() {
2777 // Define the allowable HTML tags and their attributes
2778 $allowed_tags = array(
2779 'a' => array(
2780 'href' => array(),
2781 'title' => array(),
2782 'rel' => array(),
2783 'target' => array(),
2784 ),
2785 'b' => array(),
2786 'i' => array(),
2787 'p' => array(),
2788 'br' => array(),
2789 'ul' => array(),
2790 'ol' => array(),
2791 'li' => array(),
2792 'strong' => array(),
2793 'em' => array(),
2794 'blockquote' => array(),
2795 'code' => array(),
2796 'pre' => array(),
2797 'select' => array( // Allow <select> and its attributes
2798 'name' => array(),
2799 'id' => array(),
2800 'class' => array(),
2801 'multiple' => array(),
2802 'required' => array(),
2803 ),
2804 'option' => array( // Allow <option> and its attributes
2805 'value' => array(),
2806 'selected' => array(),
2807 ),
2808 'div' => array( // Allow <div> and its attributes
2809 'id' => array(),
2810 'class' => array(),
2811 'style' => array(), // Use with caution, considering inline CSS security implications
2812 ),
2813 'h4' => array(
2814 'id' => array(),
2815 'class' => array(),
2816
2817 ),
2818 'label' => array(
2819 'id' => array(),
2820 'class' => array(),
2821
2822 ),
2823 'fieldset' => array(
2824 'id' => array(),
2825 'class' => array(),
2826
2827 ),
2828 'input' => array(
2829 'id' => array(),
2830 'class' => array(),
2831 'type' => array(),
2832 'name' => array(),
2833 'value' => array(),
2834 'checked'=>array()
2835
2836
2837 ),
2838 );
2839
2840
2841 return $allowed_tags;
2842 }
2843
2844
2845 /*
2846 *
2847 * Request list of ready to go MLS
2848 *
2849 *
2850 */
2851 /**
2852 * Fetch the SaaS list of "ready to go" MLS systems, formatted for an autocomplete.
2853 *
2854 * Result is cached in a 24h transient. On a fresh fetch the raw MLS list is turned
2855 * into an array of {label, value} pairs (with a "My MLS is not on this list" entry
2856 * prepended) and JSON-encoded; on API failure a single-element error array is returned.
2857 *
2858 * @return string|array JSON string of autofill pairs on success, or an array
2859 * carrying an error message under key '0' on failure.
2860 */
2861 function mlsimport_saas_request_list() {
2862
2863 // Serve from the cached transient when present.
2864 $mls_data = get_transient( 'mlsimport_ready_to_go_mlsimport_data' );
2865
2866 // Cache miss: hit the SaaS API for the current MLS list.
2867 if ( false === $mls_data ) {
2868 $theme_Start = new ThemeImport();
2869 $values = array();
2870
2871 // GET the MLS catalogue from the SaaS endpoint.
2872 $answer = $theme_Start::globalApiRequestSaas( 'mls', $values, 'GET' );
2873
2874 // Success: reshape the list into autocomplete {label,value} pairs.
2875 if ( isset( $answer['success'] ) && true === $answer['success'] ) {
2876 $mls_data = $answer['mls_list'];
2877 // Prepend the "not listed" opt-out choice.
2878 $mls_data['0'] = esc_html__( 'My MLS is not on this list', 'mlsimport' );
2879
2880 $autofill_array = array();
2881 // Convert each key => label into a label/value pair.
2882 foreach ( $mls_data as $key => $value ) {
2883 $temp_array = array(
2884 'label' => $value,
2885 'value' => $key,
2886 );
2887 $autofill_array[] = $temp_array;
2888 }
2889
2890 // Encode the pairs and cache for 24 hours.
2891 $mls_data = wp_json_encode( $autofill_array );
2892
2893 set_transient( 'mlsimport_ready_to_go_mlsimport_data', $mls_data, 60 * 60 * 24 );
2894 } else {
2895 // Failure: return a single-entry array carrying the error message.
2896 $mls_data = array();
2897 $error_message = isset( $answer['error_message'] ) && ! empty( $answer['error_message'] )
2898 ? $answer['error_message']
2899 : esc_html__( 'We could not connect to MLSimport Api', 'mlsimport' );
2900 $mls_data['0'] = esc_html( $error_message );
2901 }
2902 }
2903
2904 return $mls_data;
2905 }
2906
2907
2908 /*
2909 * sanitize multidimensional array
2910 *
2911 *
2912 * */
2913 /**
2914 * Recursively sanitise a value (scalar or nested array) for safe storage.
2915 *
2916 * Walks arrays depth-first, applying sanitize_text_field( wp_unslash() ) to every
2917 * leaf; a scalar input is sanitised directly.
2918 *
2919 * @param mixed $data Array or scalar to sanitise.
2920 * @return mixed Sanitised value of the same shape as the input.
2921 */
2922 function mlsimport_sanitize_multi_dimensional_array($data){
2923 // Arrays: recurse into each element.
2924 if ( is_array( $data ) ) {
2925 foreach ( $data as $key => $value ) {
2926 // Nested array -> recurse; otherwise sanitise the leaf value.
2927 if ( is_array( $value ) ) {
2928 $data[ $key ] = mlsimport_sanitize_multi_dimensional_array( $value );
2929 } else {
2930
2931 $data[ $key ] = sanitize_text_field( wp_unslash( $value ));
2932 }
2933 }
2934 } else {
2935 // Scalar input: sanitise directly.
2936 $data = sanitize_text_field( wp_unslash( $data) );
2937 }
2938
2939 return $data;
2940 }
2941
2942
2943 /*
2944 * Lopp troght the listings and get Listing key
2945 *
2946 *
2947 *
2948 *
2949 *
2950 * */
2951
2952 /**
2953 * Cron entry point for the daily SaaS reconciliation pass.
2954 *
2955 * Bails out early unless at least one non-trashed import task has a title, then
2956 * calls the one deep reconciliation interface when an MLS name is configured.
2957 *
2958 * The same function handles the deduplicated one-hour retry hook. Trigger code
2959 * intentionally owns no snapshot, status, batching, or deletion decisions.
2960 *
2961 * @return array<string, int|string>|null Reconciliation Outcome, or null when ineligible.
2962 */
2963 function mlsimport_saas_reconciliation_event_function() {
2964
2965 // Pull the API token (side effect: ensures a fresh token) and plugin options.
2966 global $mlsimport, $wpdb;
2967 $token = $mlsimport->admin->mlsimport_saas_get_mls_api_token_from_transient();
2968 $options = get_option( 'mlsimport_admin_options' );
2969
2970 // Only run reconciliation if at least one import task has a title.
2971 $has_titled_task = $wpdb->get_var(
2972 "SELECT ID FROM {$wpdb->posts}
2973 WHERE post_type = 'mlsimport_item'
2974 AND post_status != 'trash'
2975 AND post_title != ''
2976 LIMIT 1"
2977 );
2978 // No titled task -> nothing to reconcile, abort.
2979 if ( ! $has_titled_task ) {
2980 return null;
2981 }
2982
2983 // Only reconcile when an MLS name is configured.
2984 if ( isset( $options['mlsimport_mls_name'] ) && '' !== $options['mlsimport_mls_name'] ) {
2985 $environment = new Mlsimport_Reconciliation_WordPress_Environment(
2986 static function () use ( $mlsimport ): array {
2987 return $mlsimport->admin->mlsimport_saas_get_mls_reconciliation_data();
2988 }
2989 );
2990
2991 $outcome = ( new Mlsimport_Reconciliation( $environment ) )->reconcile_current_listings();
2992 error_log( 'MLSImport reconciliation outcome: ' . wp_json_encode( $outcome ) );
2993 return $outcome;
2994 }
2995
2996 return null;
2997 }
2998
2999 /*
3000 * Admin extra columns for MlsImport Items
3001 *
3002 *
3003 *
3004 *
3005 *
3006 * */
3007
3008 // Register the custom admin list-table columns for the Import Tasks post type.
3009 add_filter( 'manage_edit-mlsimport_item_columns', 'mlsimport_items_columns_admin' );
3010
3011 // Guard against redeclaration when the filter/file is loaded more than once.
3012 if ( ! function_exists( 'mlsimport_items_columns_admin' ) ) :
3013
3014 /**
3015 * Add MLSImport-specific columns to the Import Tasks admin list table.
3016 *
3017 * Drops the default comments column and appends Import Parameters, Last action
3018 * and Auto Update Enabled columns.
3019 *
3020 * @param array $columns Existing column id => label map.
3021 * @return array Modified column map.
3022 */
3023 function mlsimport_items_columns_admin( $columns ) {
3024 // Keep a copy of two columns starting at offset 2 (to re-append later).
3025 $slice = array_slice( $columns, 2, 2 );
3026 // Remove the comments column from both the full set and the slice.
3027 unset( $columns['comments'] );
3028 unset( $slice['comments'] );
3029 // Trim the original column set down to the first two entries.
3030 $splice = array_splice( $columns, 2 );
3031
3032 // Append the plugin's own columns.
3033 $columns['mlsimport_items_params'] = esc_html__( 'Import Parameters', 'mlsimport' );
3034 $columns['mlsimport_task_health'] = esc_html__( 'Status', 'mlsimport' );
3035 $columns['mlsimport_last_action'] = esc_html__( 'Last action', 'mlsimport' );
3036 $columns['mlsimport_autoupdates'] = esc_html__( 'Auto Update Enabled', 'mlsimport' );
3037
3038 // Return the plugin columns followed by the preserved slice (reversed).
3039 return array_merge( $columns, array_reverse( $slice ) );
3040 }
3041
3042 endif; // end wpestate_my_columns
3043
3044
3045
3046
3047 /*
3048 * Admin extra columns for MlsImport Items - Populate with data display value
3049 *
3050 *
3051 *
3052 *
3053 *
3054 * */
3055 /**
3056 * Flatten an import-parameter value into a comma-separated display string.
3057 *
3058 * Arrays are joined with commas (trailing comma trimmed); scalars pass through.
3059 *
3060 * @param mixed $value Array of values or a single scalar.
3061 * @return string Comma-separated (or scalar) display string.
3062 */
3063 function mlsimport_populate_columns_params_display_value( $value ) {
3064 $display_value = '';
3065 // Array: concatenate each element with a comma separator.
3066 if ( is_array( $value ) ) {
3067 foreach ( $value as $key_item => $item_name ) :
3068 $display_value .= $item_name . ',';
3069 endforeach;
3070 // Drop the trailing comma left by the loop.
3071 $display_value = rtrim( $display_value, ',' );
3072 } else {
3073 // Scalar: use as-is.
3074 $display_value = $value;
3075 }
3076
3077 return $display_value;
3078 }
3079 /*
3080 * Admin extra columns for MlsImport Items - Populate with data
3081 *
3082 *
3083 *
3084 *
3085 *
3086 * */
3087
3088 /**
3089 * Echo the configured import parameters for one Import Task into the admin column.
3090 *
3091 * Iterates the MLS field definitions and, for each non-hidden field, prints the
3092 * task's stored value. Fields NOT in the $select_all_none list show "ALL" when
3093 * their per-field checkbox meta is set; the rest always show the raw stored value.
3094 *
3095 * @param int $postID Import Task post ID.
3096 * @return void Output is echoed directly.
3097 */
3098 function mlsimport_populate_columns_params_display( $postID ) {
3099 // Field definitions come from the admin class.
3100 global $mlsimport;
3101 $field_import = $mlsimport->admin->mlsimport_saas_return_mls_fields();
3102
3103 // Fields whose stored value is always shown verbatim (never collapsed to "ALL").
3104 $select_all_none = array(
3105 'InternetAddressDisplayYN',
3106 'InternetEntireListingDisplayYN',
3107 'PostalCode',
3108 'ListAgentKey',
3109 'ListAgentMlsId',
3110 'BuyerAgentMlsId',
3111 'ListOfficeKey',
3112 'ListOfficeMlsId',
3113 'ListingID',
3114 'StandardStatus',
3115 'extraCity',
3116 'extraCounty',
3117 'Exclude_ListOfficeKey',
3118 'Exclude_ListOfficeMlsId',
3119 'Exclude_ListAgentKey',
3120 'Exclude_ListAgentMlsId',
3121 'CustomParameters',
3122 'MLSAreaMajor',
3123 'SubdivisionName',
3124
3125 );
3126 // Walk every defined MLS field for this task.
3127 foreach ( $field_import as $key => $field ) :
3128 // Skip fields flagged hidden.
3129 if ( ! empty( $field['hidden'] ) ) {
3130 continue;
3131 }
3132 $display_value = '';
3133 // Derive the per-field meta keys (value + its "check" companion).
3134 $name_check = strtolower( 'mlsimport_item_' . $key . '_check' );
3135 $name = strtolower( 'mlsimport_item_' . $key );
3136
3137 // Read the stored value and its checkbox flag.
3138 $value = get_post_meta( $postID, $name, true );
3139 $value_check = get_post_meta( $postID, $name_check, true );
3140
3141 // Normalise the checkbox flag to 0/1.
3142 $is_checkbox_admin = 0;
3143 if ( 1 === intval($value_check) ) {
3144 $is_checkbox_admin = 1;
3145 }
3146
3147 // For collapsible fields a set checkbox means "ALL"; otherwise show the value.
3148 if ( ! in_array( $key, $select_all_none ) ) {
3149 if ( 1 === intval($is_checkbox_admin) ) {
3150 $display_value = esc_html__( 'ALL', 'mlsimport' );
3151 } else {
3152 $display_value = mlsimport_populate_columns_params_display_value( $value );
3153 }
3154 } else {
3155 // Always-verbatim fields: print the stored value.
3156 $display_value = mlsimport_populate_columns_params_display_value( $value );
3157 }
3158
3159 // Render "<Label> : <value>" only when there is something to show.
3160 if ( '' !== $display_value ) { ?>
3161 <strong>
3162 <?php
3163 // Field label with the leading "Select " prefix stripped.
3164 print esc_html( ucfirst( str_replace( 'Select ', '', $field['label'] ) ) );
3165 ?>
3166 :</strong>
3167 <?php
3168 print esc_html($display_value).'</br>';
3169
3170 }
3171 endforeach;
3172 }
3173
3174
3175
3176 // Render cell contents for the custom Import Tasks columns.
3177 add_action( 'manage_posts_custom_column', 'mlsimport_populate_columns' );
3178 // Guard against redeclaration.
3179 if ( ! function_exists( 'mlsimport_populate_columns' ) ) :
3180
3181 /**
3182 * Output the value for each custom Import Tasks admin column.
3183 *
3184 * Handles the three plugin columns: import parameters (price range + field
3185 * params), last action date, and whether auto-update (cron) is enabled.
3186 *
3187 * @param string $column Column id being rendered.
3188 * @return void Output is echoed directly.
3189 */
3190 function mlsimport_populate_columns( $column ) {
3191
3192 // Current row's post is available via the global.
3193 global $post;
3194
3195 // Import Parameters column: price range then the field parameter list.
3196 if ( 'mlsimport_items_params' === $column ) {
3197 // Read the configured min/max price filters as floats.
3198 $mlsimport_item_min_price = floatval( get_post_meta( $post->ID, 'mlsimport_item_min_price', true ) );
3199 $mlsimport_item_max_price = floatval( get_post_meta( $post->ID, 'mlsimport_item_max_price', true ) );
3200 ?>
3201
3202
3203 <!-- Strong tag for emphasizing the label -->
3204 <strong>
3205 <?php esc_html_e('Minimum price:', 'mlsimport'); ?>
3206 </strong>
3207
3208 <?php echo esc_html($mlsimport_item_min_price); ?><br>
3209
3210 <strong>
3211 <?php esc_html_e('Maximum price:', 'mlsimport'); ?>
3212 </strong>
3213
3214 <?php echo esc_html($mlsimport_item_max_price); ?><br>
3215 <?php
3216
3217 // Then the per-field import parameters.
3218 mlsimport_populate_columns_params_display( $post->ID );
3219 } elseif ( 'mlsimport_task_health' === $column ) {
3220 // Status column (GitHub issue #200): surface stuck, failed, and
3221 // sync-overdue tasks directly in the list. All inputs are already
3222 // recorded — the run status meta (state, progress, heartbeat, error),
3223 // the sync watermark, and the auto-sync flag. The badge decision
3224 // itself lives in the pure, unit-tested mlsimport_task_health().
3225 $health_status = get_post_meta( $post->ID, 'mlsimport_import_run_status', true );
3226 $health = mlsimport_task_health(
3227 is_array( $health_status ) ? $health_status : array(),
3228 (string) get_post_meta( $post->ID, 'mlsimport_last_date', true ),
3229 1 === (int) get_post_meta( $post->ID, 'mlsimport_item_stat_cron', true ),
3230 time(),
3231 // Watermarks are stored with wp_date() in site-local time, so
3232 // the overdue cutoff must be built the same way to compare.
3233 wp_date( 'Y-m-d\TH:i', time() - MLSIMPORT_TASK_HEALTH_OVERDUE_AFTER )
3234 );
3235 ?>
3236 <span class="mlsimport-task-health mlsimport-task-health--<?php echo esc_attr( $health['level'] ); ?>">
3237 <?php echo esc_html( $health['label'] ); ?>
3238 </span>
3239 <p class="mlsimport-task-health__message"><?php echo esc_html( $health['message'] ); ?></p>
3240 <?php
3241 } elseif ( 'mlsimport_last_action' === $column ) {
3242 // Last action column: date of the most recent import activity.
3243 $last_date = get_post_meta( $post->ID, 'mlsimport_last_date', true );
3244 if ( '' !== $last_date ) {
3245 // Have a date: show it with an explanatory note.
3246 print esc_html($last_date) . ' </br>';
3247 esc_html_e( 'On this date we found new or edited listings.', 'mlsimport' );
3248 } else {
3249 // No date recorded (sync likely disabled).
3250 esc_html_e( 'Not available - sync option may be off.', 'mlsimport' );
3251 }
3252 } elseif ( 'mlsimport_autoupdates' === $column ) {
3253 // Auto Update column: reflects the cron-enabled meta flag.
3254 $mlsimport_item_stat_cron = esc_html( get_post_meta( $post->ID, 'mlsimport_item_stat_cron', true ) );
3255
3256 // Positive flag -> "yes", otherwise "no".
3257 if ( intval( $mlsimport_item_stat_cron ) > 0 ) {
3258 ?>
3259 yes
3260 <?php
3261 } else {
3262 ?>
3263 no
3264 <?php
3265 }
3266 }
3267 }
3268 endif;
3269
3270
3271
3272 /**
3273 * Wipe all MLSImport-created options and transients from the database.
3274 *
3275 * Deletes every option whose name begins with "mlsimport_" (both single-site and
3276 * network variants) and every matching transient (site and normal). Does NOT touch
3277 * imported posts/terms — options and transients only.
3278 *
3279 * @return bool Always true.
3280 */
3281 function mlsimport_reset_plugin_data() {
3282
3283
3284 global $wpdb;
3285
3286 // Remove all options stored by MLSImport
3287 // Collect every option name prefixed with "mlsimport_".
3288 $option_names = $wpdb->get_col( $wpdb->prepare( "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE %s", $wpdb->esc_like( 'mlsimport_' ) . '%' ) );
3289 // Delete each as both a normal and a network option.
3290 foreach ( $option_names as $option_name ) {
3291 delete_option( $option_name );
3292 delete_site_option( $option_name );
3293 }
3294
3295 // Remove transients created by MLSImport
3296 // Match both normal and site transient row-name prefixes.
3297 $transient_patterns = array( '_transient_mlsimport_%', '_site_transient_mlsimport_%' );
3298 foreach ( $transient_patterns as $pattern ) {
3299 // Find the raw option rows backing these transients.
3300 $names = $wpdb->get_col( $wpdb->prepare( "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE %s", $pattern ) );
3301 foreach ( $names as $name ) {
3302 // Strip the storage prefix and delete via the matching transient API.
3303 if ( strpos( $name, '_site_transient_' ) === 0 ) {
3304 $transient = substr( $name, strlen( '_site_transient_' ) );
3305 delete_site_transient( $transient );
3306 } else {
3307 $transient = substr( $name, strlen( '_transient_' ) );
3308 delete_transient( $transient );
3309 }
3310 }
3311 }
3312
3313 return true;
3314 }
3315