Changeset 3447995
- Timestamp:
- 01/27/2026 03:14:40 PM (2 months ago)
- Location:
- property-drive/trunk
- Files:
-
- 7 deleted
- 21 edited
-
assets/css/ui.css (modified) (3 diffs)
-
assets/images/4property-logo.png (deleted)
-
assets/images/foursquare-logotype.png (deleted)
-
assets/images/foursquare.png (deleted)
-
assets/images/fullscreen@2x.png (deleted)
-
assets/images/heart-on.png (deleted)
-
assets/images/heart.png (deleted)
-
assets/js/init.js (modified) (10 diffs)
-
includes/admin/build_admin_page.php (modified) (24 diffs)
-
includes/helpers.php (modified) (41 diffs)
-
includes/inline_styling.php (modified) (2 diffs)
-
includes/meta.php (modified) (5 diffs)
-
includes/property_search.php (modified) (2 diffs)
-
includes/setup-plugin-options.php (modified) (2 diffs)
-
modules/cpt-favourites.php (deleted)
-
modules/init.php (modified) (1 diff)
-
modules/slider/slider.php (modified) (12 diffs)
-
modules/user_dashboard.php (modified) (9 diffs)
-
modules/user_sign_up.php (modified) (3 diffs)
-
property-drive.php (modified) (5 diffs)
-
readme.txt (modified) (2 diffs)
-
shortcodes/property-grid.php (modified) (5 diffs)
-
shortcodes/property-map.php (modified) (5 diffs)
-
shortcodes/search-form-results.php (modified) (17 diffs)
-
shortcodes/search-form.php (modified) (15 diffs)
-
templates/part-sidebar-classic.php (modified) (2 diffs)
-
templates/single-property.php (modified) (21 diffs)
-
templates/template-parts.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
property-drive/trunk/assets/css/ui.css
r3059897 r3447995 961 961 position: relative; 962 962 } 963 .property-card--image-count, 964 .pd-box-favourite { 963 .property-card--image-count { 965 964 position: absolute; 966 965 z-index: 0; … … 971 970 font-size: 18px; 972 971 color: #ffffff; 973 }974 .pd-box-favourite {975 right: 16px;976 width: 24px;977 height: 24px;978 background: url('../images/heart.png') no-repeat center center;979 cursor: pointer;980 }981 .pd-box-favourite.favourite,982 .pd-box-favourite:hover {983 background: url('../images/heart-on.png') no-repeat center center;984 972 } 985 973 … … 1676 1664 @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { 1677 1665 .leaflet-control-fullscreen a { 1678 background-image:url(../images/fullscreen @2x.png);1666 background-image:url(../images/fullscreen-2x.png); 1679 1667 } 1680 1668 } -
property-drive/trunk/assets/js/init.js
r3059897 r3447995 4 4 * Licensed GPLv3 5 5 */ 6 function roar(e, r,t){"use strict";if("object"!=typeof t&&(t={}),window.roarAlert)window.roarAlert.cancel&&(window.roarAlert.cancelElement.style=""),window.roarAlert.confirm&&(window.roarAlert.confirmElement.style=""),document.body.classList.add("roar-open"),window.roarAlert.element.style.display="block",a=window.roarAlert;else{var a={element:null,cancelElement:null,confirmElement:null};a.element=document.querySelector(".roar-alert")}if(a.cancel=void 0!==t.cancel?t.cancel:!1,a.cancelText=void 0!==t.cancelText?t.cancelText:"Cancel",a.cancelCallBack=function(e){return document.body.classList.remove("roar-open"),window.roarAlert.element.style.display="none","function"==typeof t.cancelCallBack&&t.cancelCallBack(e),!0},document.querySelector(".roar-alert-mask")&&document.querySelector(".roar-alert-mask").addEventListener("click",function(e){return document.body.classList.remove("roar-open"),window.roarAlert.element.style.display="none","function"==typeof t.cancelCallBack&&t.cancelCallBack(e),!0}),a.message=r,a.title=e,a.confirm=void 0!==t.confirm?t.confirm:!0,a.confirmText=void 0!==t.confirmText?t.confirmText:"Confirm",a.confirmCallBack=function(e){return document.body.classList.remove("roar-open"),window.roarAlert.element.style.display="none","function"==typeof t.confirmCallBack&&t.confirmCallBack(e),!0},!a.element){a.html='<div class="roar-alert" id="roar-alert" role="alertdialog"><div class="roar-alert-mask"></div><div class="roar-alert-message-body" role="alert" aria-relevant="all"><div class="roar-alert-message-tbf roar-alert-message-title">'+a.title+'</div><div class="roar-alert-message-tbf roar-alert-message-content">'+a.message+'</div><div class="roar-alert-message-tbf roar-alert-message-button">',a.cancel,a.html+='<a href="javascript:;" class="roar-alert-message-tbf roar-alert-message-button-cancel">'+a.cancelText+"</a>",a.confirm,a.html+='<a href="javascript:;" class="roar-alert-message-tbf roar-alert-message-button-confirm">'+a.confirmText+"</a>",a.html+="</div></div></div>";var l=document.createElement("div");l.id="roar-alert-wrap",l.innerHTML=a.html,document.body.appendChild(l),a.element=document.querySelector(".roar-alert"),a.cancelElement=document.querySelector(".roar-alert-message-button-cancel"),a.cancel?document.querySelector(".roar-alert-message-button-cancel").style.display="block":document.querySelector(".roar-alert-message-button-cancel").style.display="none",a.confirmElement=document.querySelector(".roar-alert-message-button-confirm"),a.confirm?document.querySelector(".roar-alert-message-button-confirm").style.display="block":document.querySelector(".roar-alert-message-button-confirm").style.display="none",a.cancelElement.onclick=a.cancelCallBack,a.confirmElement.onclick=a.confirmCallBack,window.roarAlert=a}document.querySelector(".roar-alert-message-title").innerHTML="",document.querySelector(".roar-alert-message-content").innerHTML="",document.querySelector(".roar-alert-message-button-cancel").innerHTML=a.cancelText,document.querySelector(".roar-alert-message-button-confirm").innerHTML=a.confirmText,a.cancelElement=document.querySelector(".roar-alert-message-button-cancel"),a.cancel?document.querySelector(".roar-alert-message-button-cancel").style.display="block":document.querySelector(".roar-alert-message-button-cancel").style.display="none",a.confirmElement=document.querySelector(".roar-alert-message-button-confirm"),a.confirm?document.querySelector(".roar-alert-message-button-confirm").style.display="block":document.querySelector(".roar-alert-message-button-confirm").style.display="none",a.cancelElement.onclick=a.cancelCallBack,a.confirmElement.onclick=a.confirmCallBack,a.title=a.title||"",a.message=a.message||"",document.querySelector(".roar-alert-message-title").innerHTML=a.title,document.querySelector(".roar-alert-message-content").innerHTML=a.message,window.roarAlert=a}6 function roar(e, r, t) { "use strict"; if ("object" != typeof t && (t = {}), window.roarAlert) window.roarAlert.cancel && (window.roarAlert.cancelElement.style = ""), window.roarAlert.confirm && (window.roarAlert.confirmElement.style = ""), document.body.classList.add("roar-open"), window.roarAlert.element.style.display = "block", a = window.roarAlert; else { var a = { element: null, cancelElement: null, confirmElement: null }; a.element = document.querySelector(".roar-alert") } if (a.cancel = void 0 !== t.cancel ? t.cancel : !1, a.cancelText = void 0 !== t.cancelText ? t.cancelText : "Cancel", a.cancelCallBack = function (e) { return document.body.classList.remove("roar-open"), window.roarAlert.element.style.display = "none", "function" == typeof t.cancelCallBack && t.cancelCallBack(e), !0 }, document.querySelector(".roar-alert-mask") && document.querySelector(".roar-alert-mask").addEventListener("click", function (e) { return document.body.classList.remove("roar-open"), window.roarAlert.element.style.display = "none", "function" == typeof t.cancelCallBack && t.cancelCallBack(e), !0 }), a.message = r, a.title = e, a.confirm = void 0 !== t.confirm ? t.confirm : !0, a.confirmText = void 0 !== t.confirmText ? t.confirmText : "Confirm", a.confirmCallBack = function (e) { return document.body.classList.remove("roar-open"), window.roarAlert.element.style.display = "none", "function" == typeof t.confirmCallBack && t.confirmCallBack(e), !0 }, !a.element) { a.html = '<div class="roar-alert" id="roar-alert" role="alertdialog"><div class="roar-alert-mask"></div><div class="roar-alert-message-body" role="alert" aria-relevant="all"><div class="roar-alert-message-tbf roar-alert-message-title">' + a.title + '</div><div class="roar-alert-message-tbf roar-alert-message-content">' + a.message + '</div><div class="roar-alert-message-tbf roar-alert-message-button">', a.cancel, a.html += '<a href="javascript:;" class="roar-alert-message-tbf roar-alert-message-button-cancel">' + a.cancelText + "</a>", a.confirm, a.html += '<a href="javascript:;" class="roar-alert-message-tbf roar-alert-message-button-confirm">' + a.confirmText + "</a>", a.html += "</div></div></div>"; var l = document.createElement("div"); l.id = "roar-alert-wrap", l.innerHTML = a.html, document.body.appendChild(l), a.element = document.querySelector(".roar-alert"), a.cancelElement = document.querySelector(".roar-alert-message-button-cancel"), a.cancel ? document.querySelector(".roar-alert-message-button-cancel").style.display = "block" : document.querySelector(".roar-alert-message-button-cancel").style.display = "none", a.confirmElement = document.querySelector(".roar-alert-message-button-confirm"), a.confirm ? document.querySelector(".roar-alert-message-button-confirm").style.display = "block" : document.querySelector(".roar-alert-message-button-confirm").style.display = "none", a.cancelElement.onclick = a.cancelCallBack, a.confirmElement.onclick = a.confirmCallBack, window.roarAlert = a } document.querySelector(".roar-alert-message-title").innerHTML = "", document.querySelector(".roar-alert-message-content").innerHTML = "", document.querySelector(".roar-alert-message-button-cancel").innerHTML = a.cancelText, document.querySelector(".roar-alert-message-button-confirm").innerHTML = a.confirmText, a.cancelElement = document.querySelector(".roar-alert-message-button-cancel"), a.cancel ? document.querySelector(".roar-alert-message-button-cancel").style.display = "block" : document.querySelector(".roar-alert-message-button-cancel").style.display = "none", a.confirmElement = document.querySelector(".roar-alert-message-button-confirm"), a.confirm ? document.querySelector(".roar-alert-message-button-confirm").style.display = "block" : document.querySelector(".roar-alert-message-button-confirm").style.display = "none", a.cancelElement.onclick = a.cancelCallBack, a.confirmElement.onclick = a.confirmCallBack, a.title = a.title || "", a.message = a.message || "", document.querySelector(".roar-alert-message-title").innerHTML = a.title, document.querySelector(".roar-alert-message-content").innerHTML = a.message, window.roarAlert = a } 7 7 8 8 … … 39 39 40 40 location.search = query.join("&"); 41 }42 43 44 45 function get_favourites() {46 // Get favorites from local storage or empty array47 var favourites = JSON.parse(localStorage.getItem('favourites')) || [];48 49 // Add class 'fav' to each favorite50 favourites.forEach(function (favourite) {51 if (document.querySelector('.pd-box-favourite[data-property-id="' + favourite + '"]')) {52 document.querySelector('.pd-box-favourite[data-property-id="' + favourite + '"]').classList.add('favourite');53 }54 });55 56 // Register click event listener57 document.querySelector('body').addEventListener('click', function (e) {58 var id = parseInt(e.target.dataset.propertyId, 10),59 index = favourites.indexOf(id);60 61 if (index == -1) {62 if (!isNaN(id)) {63 favourites.push(id);64 document.querySelector('h1.single-property-title .pd-box-favourite[data-property-id="' + id + '"]').classList.add('favourite');65 }66 } else {67 favourites.splice(index, 1);68 document.querySelector('h1.single-property-title .pd-box-favourite[data-property-id="' + id + '"]').classList.remove('favourite');69 }70 localStorage.setItem('favourites', JSON.stringify(favourites));71 72 // Save to database if user is logged in73 var request = new XMLHttpRequest();74 75 request.open('POST', wp4pmAjaxVar.ajaxurl, true);76 request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');77 request.onload = function () {78 if (this.status >= 200 && this.status < 400) {79 // Response success80 }81 };82 request.send('action=save_user_favourite&property_id=' + id);83 });84 41 } 85 42 … … 109 66 } 110 67 }; 111 request.onerror = function () {68 request.onerror = function () { 112 69 // Connection error 113 70 }; … … 201 158 // a = addressPoints[i]; 202 159 // title = a[2]; 203 //marker = L.marker(new L.LatLng(a[0], a[1]), {204 // title: title,205 // icon: icon206 //});207 //marker.bindPopup(getDetailsById(title));208 //marker.addTo(osmMap); // Regular marker209 //markers.addLayer(marker); // Marker clusterer210 211 /**212 circleMarker = L.circleMarker(new L.LatLng(a[0], a[1]), {213 color: '#000000',214 fillColor: '#3388ff',215 weight: 1,216 radius: 10,217 fillOpacity: 0.5,218 title: title219 });220 circleMarker.bindPopup(getDetailsById(title));221 circleMarker.addTo(osmMap);222 /**/160 //marker = L.marker(new L.LatLng(a[0], a[1]), { 161 // title: title, 162 // icon: icon 163 //}); 164 //marker.bindPopup(getDetailsById(title)); 165 //marker.addTo(osmMap); // Regular marker 166 //markers.addLayer(marker); // Marker clusterer 167 168 /** 169 circleMarker = L.circleMarker(new L.LatLng(a[0], a[1]), { 170 color: '#000000', 171 fillColor: '#3388ff', 172 weight: 1, 173 radius: 10, 174 fillOpacity: 0.5, 175 title: title 176 }); 177 circleMarker.bindPopup(getDetailsById(title)); 178 circleMarker.addTo(osmMap); 179 /**/ 223 180 //} 224 181 //osmMap.addLayer(markers); // Marker clusterer … … 296 253 } 297 254 }; 298 request.onerror = function () {255 request.onerror = function () { 299 256 // Connection error 300 257 }; … … 545 502 546 503 547 /**548 * Basic favourites engine549 *550 * Local storage stores strings so we use JSON to stringify for storage and parse to get out of storage551 */552 if (document.querySelector('.pd-box-favourite')) {553 get_favourites();554 }555 556 557 558 if (document.getElementById('pd-favourites')) {559 var favouritesFetch = JSON.parse(localStorage.getItem('favourites')) || [],560 favouritesArray = [];561 562 document.getElementById('pd-favourites').innerHTML = 'Loading your favourite properties...';563 favouritesFetch.forEach(function (favouriteFetch) {564 favouritesArray.push(favouriteFetch);565 });566 567 // Fetch favourites568 var request = new XMLHttpRequest(),569 favourites = favouritesArray;570 571 request.open('POST', wp4pmAjaxVar.ajaxurl, true);572 request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');573 request.onload = function () {574 if (this.status >= 200 && this.status < 400) {575 document.getElementById('pd-favourites').innerHTML = this.response;576 577 get_favourites();578 }579 };580 request.send('action=pd_favourites_fetch_public&favourites=' + favourites);581 }582 583 584 if (document.querySelector('.remove-user-favourite')) {585 [].forEach.call(document.querySelectorAll('.remove-user-favourite'), function (favourite) {586 favourite.addEventListener('click', function (event) {587 event.preventDefault();588 589 var request = new XMLHttpRequest(),590 favouriteId = favourite.dataset.favouriteId;591 592 request.open('POST', wp4pmAjaxVar.ajaxurl, true);593 request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');594 request.onload = function () {595 if (this.status >= 200 && this.status < 400) {596 document.getElementById('favourite-row-' + favouriteId).remove();597 }598 };599 request.send('action=remove_user_favourite&favourite_id=' + favouriteId);600 });601 });602 }603 604 605 606 504 document.querySelector('body').addEventListener('click', function (e) { 607 505 /** … … 618 516 '<input type="text" id="contact-phone" placeholder="Phone"><br>' + 619 517 '<textarea id="contact-message" rows="3"></textarea>' + 620 '</p>';518 '</p>'; 621 519 622 520 var options = { … … 646 544 request.onload = function () { 647 545 if (this.status >= 200 && this.status < 400) { 648 roar('Quick Contact', 'Thank you for your request! We will contact you shortly.', { confirmText: 'Close'});546 roar('Quick Contact', 'Thank you for your request! We will contact you shortly.', { confirmText: 'Close' }); 649 547 } 650 548 }; … … 670 568 request.onload = function () { 671 569 if (this.status >= 200 && this.status < 400) { 672 roar('Quick Contact', 'Thank you for your request! We will contact you shortly.', { confirmText: 'Close'});570 roar('Quick Contact', 'Thank you for your request! We will contact you shortly.', { confirmText: 'Close' }); 673 571 674 572 // Reset fields on success … … 701 599 }); 702 600 703 window.addEventListener('click', function (event) {601 window.addEventListener('click', function (event) { 704 602 if (event.target == modal) { 705 603 modal.style.display = 'none'; -
property-drive/trunk/includes/admin/build_admin_page.php
r3059897 r3447995 1 1 <?php 2 function pm_menu_links() { 2 if ( ! defined( 'ABSPATH' ) ) { 3 exit; // Exit if accessed directly 4 } 5 6 function wppd_menu_links() { 3 7 add_menu_page('Property Drive Settings', 'Property Drive', 'manage_options', 'property_drive', 'wppd_build_admin_page', 'dashicons-admin-home', 4); 4 8 } 5 9 6 add_action('admin_menu', ' pm_menu_links');10 add_action('admin_menu', 'wppd_menu_links'); 7 11 8 12 function wppd_dashboard_help() { … … 18 22 $propertyArgs = [ 19 23 'post_type' => 'property', 20 'meta_query' => [ 21 [ 22 'key' => 'property_view_count' 23 ] 24 ] 24 'meta_key' => 'property_view_count', 25 25 ]; 26 26 … … 61 61 $nonce = wp_create_nonce('wppd_property_admin'); 62 62 63 $jtg_plugin_logo = plugin_dir_url(dirname(__DIR__)) . 'assets/images/4property-logo.png';64 65 63 $plugin_version_dir = plugin_dir_path(dirname(__DIR__)).'property-drive.php'; 66 64 $plugin_version = get_plugin_data($plugin_version_dir, 'Version'); … … 73 71 74 72 <h2 class="nav-tab-wrapper"> 75 <a href="<?php echo $section; ?>dashboard" class="nav-tab <?php echo $tab === 'dashboard' ? 'nav-tab-active' : ''; ?>">Dashboard</a>76 <a href="<?php echo $section; ?>agency" class="nav-tab <?php echo $tab === 'agency' ? 'nav-tab-active' : ''; ?>">Agency Details</a>77 <a href="<?php echo $section; ?>general" class="nav-tab <?php echo $tab === 'general' ? 'nav-tab-active' : ''; ?>">Settings</a>78 <a href="<?php echo $section; ?>design" class="nav-tab <?php echo $tab === 'design' ? 'nav-tab-active' : ''; ?>">Design</a>79 <a href="<?php echo $section; ?>search" class="nav-tab <?php echo $tab === 'search' ? 'nav-tab-active' : ''; ?>">Search</a>80 <a href="<?php echo $section; ?>users" class="nav-tab <?php echo $tab === 'users' ? 'nav-tab-active' : ''; ?>">Users</a>81 <a href="<?php echo $section; ?>pro" class="nav-tab nav-tab--pro <?php echo $tab === 'pro' ? 'nav-tab-active' : ''; ?>">Pro</a>73 <a href="<?php echo esc_url( $section ); ?>dashboard" class="nav-tab <?php echo esc_attr( $tab === 'dashboard' ? 'nav-tab-active' : '' ); ?>">Dashboard</a> 74 <a href="<?php echo esc_url( $section ); ?>agency" class="nav-tab <?php echo esc_attr( $tab === 'agency' ? 'nav-tab-active' : '' ); ?>">Agency Details</a> 75 <a href="<?php echo esc_url( $section ); ?>general" class="nav-tab <?php echo esc_attr( $tab === 'general' ? 'nav-tab-active' : '' ); ?>">Settings</a> 76 <a href="<?php echo esc_url( $section ); ?>design" class="nav-tab <?php echo esc_attr( $tab === 'design' ? 'nav-tab-active' : '' ); ?>">Design</a> 77 <a href="<?php echo esc_url( $section ); ?>search" class="nav-tab <?php echo esc_attr( $tab === 'search' ? 'nav-tab-active' : '' ); ?>">Search</a> 78 <a href="<?php echo esc_url( $section ); ?>users" class="nav-tab <?php echo esc_attr( $tab === 'users' ? 'nav-tab-active' : '' ); ?>">Users</a> 79 <a href="<?php echo esc_url( $section ); ?>pro" class="nav-tab nav-tab--pro <?php echo esc_attr( $tab === 'pro' ? 'nav-tab-active' : '' ); ?>">Pro</a> 82 80 </h2> 83 81 84 82 <?php if ($tab === 'dashboard') { ?> 85 <h3 class="identityblock">WP Property<br>Drive <code class="codeblock"><?php echo $plugin_version['Version']; ?></code></h3>83 <h3 class="identityblock">WP Property<br>Drive <code class="codeblock"><?php echo esc_html( $plugin_version['Version'] ); ?></code></h3> 86 84 87 85 <h2 class="titleblock">Welcome to WP Property Drive! Get the most out of your properties.</h2> 88 86 89 87 <?php wppd_dashboard_help(); ?> 90 91 <p>92 <a href="https://www.4property.com/"><img src="<?php echo $jtg_plugin_logo; ?>" width="100" alt="4Property"></a>93 </p>94 88 <?php } else if ($tab === 'agency') { ?> 95 <h2><?php _e('Agency Details', 'property-drive'); ?></h2>89 <h2><?php esc_html_e('Agency Details', 'property-drive'); ?></h2> 96 90 97 91 <?php 98 92 if (isset($_POST['save_agency_settings'])) { 99 update_option('agency_name', sanitize_text_field(trim($_POST['agency_name']))); 100 update_option('agency_email', sanitize_email($_POST['agency_email'])); 101 update_option('agency_phone', sanitize_text_field($_POST['agency_phone'])); 102 103 update_option('force_agency_name', (int) $_POST['force_agency_name']); 104 update_option('force_agency_email', (int) $_POST['force_agency_email']); 105 update_option('force_agency_phone', (int) $_POST['force_agency_phone']); 106 update_option('mask_agency_email', (int) $_POST['mask_agency_email']); 107 update_option('mask_agency_phone', (int) $_POST['mask_agency_phone']); 108 109 update_option('agency_logo', $_POST['agency_logo']); 93 if ( ! isset( $_POST['wppd_property_admin_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['wppd_property_admin_nonce'] ) ), 'wppd_property_admin' ) ) { 94 wp_die( esc_html__( 'Security check failed.', 'property-drive' ) ); 95 } 96 $agency_name = isset( $_POST['agency_name'] ) ? sanitize_text_field( wp_unslash( $_POST['agency_name'] ) ) : ''; 97 update_option('agency_name', $agency_name); 98 update_option('agency_email', isset( $_POST['agency_email'] ) ? sanitize_email( wp_unslash( $_POST['agency_email'] ) ) : ''); 99 update_option('agency_phone', isset( $_POST['agency_phone'] ) ? sanitize_text_field( wp_unslash( $_POST['agency_phone'] ) ) : ''); 100 101 update_option('force_agency_name', isset( $_POST['force_agency_name'] ) ? absint( $_POST['force_agency_name'] ) : 0); 102 update_option('force_agency_email', isset( $_POST['force_agency_email'] ) ? absint( $_POST['force_agency_email'] ) : 0); 103 update_option('force_agency_phone', isset( $_POST['force_agency_phone'] ) ? absint( $_POST['force_agency_phone'] ) : 0); 104 update_option('mask_agency_email', isset( $_POST['mask_agency_email'] ) ? absint( $_POST['mask_agency_email'] ) : 0); 105 update_option('mask_agency_phone', isset( $_POST['mask_agency_phone'] ) ? absint( $_POST['mask_agency_phone'] ) : 0); 106 107 update_option('agency_logo', isset( $_POST['agency_logo'] ) ? esc_url_raw( wp_unslash( $_POST['agency_logo'] ) ) : ''); 110 108 111 109 echo '<div class="updated notice is-dismissible"><p>Settings updated successfully!</p></div>'; … … 117 115 118 116 <form method="post"> 117 <?php wp_nonce_field( 'wppd_property_admin', 'wppd_property_admin_nonce' ); ?> 119 118 <table class="form-table"> 120 119 <tbody> … … 122 121 <th scope="row"><label>Estate Agency Name</label></th> 123 122 <td> 124 <input type="text" name="agency_name" value="<?php echo stripslashes(get_option('agency_name')); ?>" class="regular-text">123 <input type="text" name="agency_name" value="<?php echo esc_attr( get_option('agency_name') ); ?>" class="regular-text"> 125 124 <input type="checkbox" name="force_agency_name" value="1" <?php checked(1, (int) get_option('force_agency_name')); ?>> Force this information, regardless of feed data 126 125 </td> … … 129 128 <th scope="row"><label>Estate Agency Email Address</label></th> 130 129 <td> 131 <input type="email" name="agency_email" value="<?php echo get_option('agency_email'); ?>" class="regular-text">130 <input type="email" name="agency_email" value="<?php echo esc_attr( get_option('agency_email') ); ?>" class="regular-text"> 132 131 <input type="checkbox" name="force_agency_email" value="1" <?php checked(1, (int) get_option('force_agency_email')); ?>> Force this information, regardless of feed data 133 132 <input type="checkbox" name="mask_agency_email" value="1" <?php checked(1, (int) get_option('mask_agency_email')); ?>> Mask this information … … 137 136 <th scope="row"><label>Estate Agency Phone Number</label></th> 138 137 <td> 139 <input type="text" name="agency_phone" value="<?php echo get_option('agency_phone'); ?>" class="regular-text">138 <input type="text" name="agency_phone" value="<?php echo esc_attr( get_option('agency_phone') ); ?>" class="regular-text"> 140 139 <input type="checkbox" name="force_agency_phone" value="1" <?php checked(1, (int) get_option('force_agency_phone')); ?>> Force this information, regardless of feed data 141 140 <input type="checkbox" name="mask_agency_phone" value="1" <?php checked(1, (int) get_option('mask_agency_phone')); ?>> Mask this information … … 151 150 if (get_option('agency_logo')) { 152 151 $image_url = get_option('agency_logo'); 153 echo '<p><img src="' . $image_url. '" style="max-width: 400px;" alt=""></p>';152 echo '<p><img src="' . esc_url( $image_url ) . '" style="max-width: 400px;" alt=""></p>'; 154 153 } else { 155 154 echo '<p>No image selected.</p>'; … … 157 156 158 157 if (!empty($_POST['image'])) { 159 $image_url = esc_url ($_POST['image']);158 $image_url = esc_url_raw( wp_unslash( $_POST['image'] ) ); 160 159 } 161 160 162 161 wp_enqueue_media(); 163 162 ?> 164 <input id="pm-image-url" type="hidden" name="agency_logo" value="<?php echo get_option('agency_logo'); ?>">163 <input id="pm-image-url" type="hidden" name="agency_logo" value="<?php echo esc_attr( get_option('agency_logo') ); ?>"> 165 164 <input id="pm-upload-image-btn" type="button" class="jtg-logo-upload-btn button button-secondary" value="Upload Logo"> 166 165 </div> … … 208 207 </script> 209 208 <?php } else if ($tab === 'general') { ?> 210 <h2><?php _e('General Settings', 'property-drive'); ?></h2>209 <h2><?php esc_html_e('General Settings', 'property-drive'); ?></h2> 211 210 212 211 <?php 213 212 if (isset($_POST['save_general_settings'])) { 214 update_option('default_property_order', sanitize_text_field($_POST['default_property_order'])); 215 update_option('jtg_currency', sanitize_text_field($_POST['jtg_currency'])); 216 217 update_option('map_provider', sanitize_text_field($_POST['map_provider'])); 218 update_option('osm_scrollzoom', (int) $_POST['osm_scrollzoom']); 219 220 update_option('allow_favourites', (int) $_POST['allow_favourites']); 221 222 update_option('allow_quick_contact', (int) $_POST['allow_quick_contact']); 223 224 update_option('show_related_properties', (int) $_POST['show_related_properties']); 225 226 update_option('inactive_not_clickable', (int) $_POST['inactive_not_clickable']); 227 228 update_option('use_single_sidebar', (int) $_POST['use_single_sidebar']); 229 update_option('reusable_sidebar_id', (int) $_POST['reusable_sidebar_id']); 230 update_option('use_single_content_accordion', (int) $_POST['use_single_content_accordion']); 231 232 // Delete old options 233 delete_option('use_single_sidebar_widgets'); 213 if ( ! isset( $_POST['wppd_property_admin_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['wppd_property_admin_nonce'] ) ), 'wppd_property_admin' ) ) { 214 wp_die( esc_html__( 'Security check failed.', 'property-drive' ) ); 215 } 216 update_option('default_property_order', isset( $_POST['default_property_order'] ) ? sanitize_text_field( wp_unslash( $_POST['default_property_order'] ) ) : ''); 217 update_option('jtg_currency', isset( $_POST['jtg_currency'] ) ? sanitize_text_field( wp_unslash( $_POST['jtg_currency'] ) ) : ''); 218 219 update_option('map_provider', isset( $_POST['map_provider'] ) ? sanitize_text_field( wp_unslash( $_POST['map_provider'] ) ) : ''); 220 update_option('osm_scrollzoom', isset( $_POST['osm_scrollzoom'] ) ? absint( $_POST['osm_scrollzoom'] ) : 0); 221 222 update_option('allow_quick_contact', isset( $_POST['allow_quick_contact'] ) ? absint( $_POST['allow_quick_contact'] ) : 0); 223 224 update_option('show_related_properties', isset( $_POST['show_related_properties'] ) ? absint( $_POST['show_related_properties'] ) : 0); 225 226 update_option('inactive_not_clickable', isset( $_POST['inactive_not_clickable'] ) ? absint( $_POST['inactive_not_clickable'] ) : 0); 227 228 update_option('use_single_sidebar', isset( $_POST['use_single_sidebar'] ) ? absint( $_POST['use_single_sidebar'] ) : 0); 229 update_option('reusable_sidebar_id', isset( $_POST['reusable_sidebar_id'] ) ? absint( $_POST['reusable_sidebar_id'] ) : 0); 230 update_option('use_single_content_accordion', isset( $_POST['use_single_content_accordion'] ) ? absint( $_POST['use_single_content_accordion'] ) : 0); 234 231 235 232 echo '<div class="updated notice is-dismissible"><p>Settings updated successfully!</p></div>'; … … 256 253 <input type="checkbox" id="allow_quick_contact" name="allow_quick_contact" value="1" <?php echo ((int) get_option('allow_quick_contact') === 1) ? 'checked' : ''; ?>> 257 254 <label for="allow_quick_contact">Allow quick contact (property enquiry)</label> 258 </p>259 <p>260 <input type="checkbox" id="allow_favourites" name="allow_favourites" value="1" <?php echo ((int) get_option('allow_favourites') === 1) ? 'checked' : ''; ?>>261 <label for="allow_favourites">Allow favourite properties</label>262 255 </p> 263 256 </td> … … 329 322 <br><small>Select your reusable sidebar or <a href="' . admin_url('edit.php?post_type=wp_block') . '">create one now</a>.</small>'; 330 323 331 echo $out;324 echo wp_kses_post( $out ); 332 325 ?> 333 326 </td> … … 375 368 <?php 376 369 if (isset($_POST['save_design_settings'])) { 377 update_option('status_overlay_style', sanitize_text_field($_POST['status_overlay_style'])); 378 379 update_option('show_status_badge', (int) $_POST['show_status_badge']); 380 update_option('show_property_card_description', (int) $_POST['show_property_card_description']); 381 382 update_option('ribbon_colour_sale', sanitize_text_field($_POST['ribbon_colour_sale'])); 383 update_option('ribbon_colour_sale_agreed', sanitize_text_field($_POST['ribbon_colour_sale_agreed'])); 384 update_option('ribbon_colour_sold', sanitize_text_field($_POST['ribbon_colour_sold'])); 385 386 update_option('property_map_id', (int) $_POST['property_map_id']); 387 update_option('property_map_ajax', (int) $_POST['property_map_ajax']); 370 if ( ! isset( $_POST['wppd_property_admin_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['wppd_property_admin_nonce'] ) ), 'wppd_property_admin' ) ) { 371 wp_die( esc_html__( 'Security check failed.', 'property-drive' ) ); 372 } 373 update_option('status_overlay_style', isset( $_POST['status_overlay_style'] ) ? sanitize_text_field( wp_unslash( $_POST['status_overlay_style'] ) ) : ''); 374 375 update_option('show_status_badge', isset( $_POST['show_status_badge'] ) ? absint( $_POST['show_status_badge'] ) : 0); 376 update_option('show_property_card_description', isset( $_POST['show_property_card_description'] ) ? absint( $_POST['show_property_card_description'] ) : 0); 377 378 update_option('ribbon_colour_sale', isset( $_POST['ribbon_colour_sale'] ) ? sanitize_text_field( wp_unslash( $_POST['ribbon_colour_sale'] ) ) : ''); 379 update_option('ribbon_colour_sale_agreed', isset( $_POST['ribbon_colour_sale_agreed'] ) ? sanitize_text_field( wp_unslash( $_POST['ribbon_colour_sale_agreed'] ) ) : ''); 380 update_option('ribbon_colour_sold', isset( $_POST['ribbon_colour_sold'] ) ? sanitize_text_field( wp_unslash( $_POST['ribbon_colour_sold'] ) ) : ''); 381 382 update_option('property_map_id', isset( $_POST['property_map_id'] ) ? absint( $_POST['property_map_id'] ) : 0); 383 update_option('property_map_ajax', isset( $_POST['property_map_ajax'] ) ? absint( $_POST['property_map_ajax'] ) : 0); 388 384 389 385 // Property brochure 390 update_option('cinematic_overlay', (int) $_POST['cinematic_overlay']);386 update_option('cinematic_overlay', isset( $_POST['cinematic_overlay'] ) ? absint( $_POST['cinematic_overlay'] ) : 0); 391 387 392 388 // Flickity options 393 update_option('flickity_wrapAround', (int) $_POST['flickity_wrapAround']);394 update_option('flickity_groupCells', (int) $_POST['flickity_groupCells']);395 update_option('flickity_groupCellsValue', (int) $_POST['flickity_groupCellsValue']);396 update_option('flickity_autoPlay', (int) $_POST['flickity_autoPlay']);389 update_option('flickity_wrapAround', isset( $_POST['flickity_wrapAround'] ) ? absint( $_POST['flickity_wrapAround'] ) : 0); 390 update_option('flickity_groupCells', isset( $_POST['flickity_groupCells'] ) ? absint( $_POST['flickity_groupCells'] ) : 0); 391 update_option('flickity_groupCellsValue', isset( $_POST['flickity_groupCellsValue'] ) ? absint( $_POST['flickity_groupCellsValue'] ) : 0); 392 update_option('flickity_autoPlay', isset( $_POST['flickity_autoPlay'] ) ? absint( $_POST['flickity_autoPlay'] ) : 0); 397 393 // 398 394 399 if ( (int) $_POST['force_cinematic_overlay']=== 1) {395 if (isset( $_POST['force_cinematic_overlay'] ) && absint( $_POST['force_cinematic_overlay'] ) === 1) { 400 396 $tempArgs = [ 401 397 'fields' => 'ids', … … 415 411 416 412 // General design 417 update_option('flex_grid_size', (int) $_POST['flex_grid_size']);413 update_option('flex_grid_size', isset( $_POST['flex_grid_size'] ) ? absint( $_POST['flex_grid_size'] ) : 0); 418 414 419 415 echo '<div class="updated notice is-dismissible"><p>Settings updated successfully!</p></div>'; … … 422 418 423 419 <form method="post"> 420 <?php wp_nonce_field( 'wppd_property_admin', 'wppd_property_admin_nonce' ); ?> 424 421 <div class="flex-container"> 425 422 <div class="flex-item flex-item-half flex-item-box"> … … 474 471 <p> 475 472 <label>Ribbon colour (<b>For Sale</b> and <b>To Let</b>)</label> 476 <input class="color-picker" data-default-color="#1abc9c" name="ribbon_colour_sale" type="text" value="<?php echo get_option('ribbon_colour_sale'); ?>">473 <input class="color-picker" data-default-color="#1abc9c" name="ribbon_colour_sale" type="text" value="<?php echo esc_attr( get_option('ribbon_colour_sale') ); ?>"> 477 474 </p> 478 475 <p> 479 476 <label>Ribbon colour (<b>Sale Agreed</b> and <b>Let Agreed</b>)</label> 480 <input class="color-picker" data-default-color="#e67e22" name="ribbon_colour_sale_agreed" type="text" value="<?php echo get_option('ribbon_colour_sale_agreed'); ?>">477 <input class="color-picker" data-default-color="#e67e22" name="ribbon_colour_sale_agreed" type="text" value="<?php echo esc_attr( get_option('ribbon_colour_sale_agreed') ); ?>"> 481 478 </p> 482 479 <p> 483 480 <label>Ribbon colour (<b>Sold</b>, <b>Let</b> and <b>Has Been Let</b>)</label> 484 <input class="color-picker" data-default-color="#e74c3c" name="ribbon_colour_sold" type="text" value="<?php echo get_option('ribbon_colour_sold'); ?>">481 <input class="color-picker" data-default-color="#e74c3c" name="ribbon_colour_sold" type="text" value="<?php echo esc_attr( get_option('ribbon_colour_sold') ); ?>"> 485 482 </p> 486 483 </td> … … 496 493 wp_dropdown_pages([ 497 494 'name' => 'property_map_id', 498 'selected' => get_option('property_map_id')495 'selected' => (int) get_option('property_map_id') 499 496 ]); 500 497 ?> … … 571 568 <?php 572 569 if (isset($_POST['save_search_settings'])) { 573 update_option('search_field_array', sanitize_text_field($_POST['search_field_array'])); 574 575 update_option('search_field_group', (int) $_POST['search_field_group']); 576 update_option('search_field_type', (int) $_POST['search_field_type']); 577 update_option('search_field_status', (int) $_POST['search_field_status']); 578 update_option('search_field_status_group', (int) $_POST['search_field_status_group']); 579 update_option('search_field_price', (int) $_POST['search_field_price']); 580 update_option('search_field_beds', (int) $_POST['search_field_beds']); 581 update_option('search_field_baths', (int) $_POST['search_field_baths']); 582 update_option('search_field_keyword', (int) $_POST['search_field_keyword']); 583 584 update_option('search_field_location', (int) $_POST['search_field_location']); 585 update_option('search_field_multitype', (int) $_POST['search_field_multitype']); 586 587 update_option('search_field_features', (int) $_POST['search_field_features']); 588 589 update_option('search_results_page', (int) $_POST['search_results_page']); 570 if ( ! isset( $_POST['wppd_property_admin_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['wppd_property_admin_nonce'] ) ), 'wppd_property_admin' ) ) { 571 wp_die( esc_html__( 'Security check failed.', 'property-drive' ) ); 572 } 573 update_option('search_field_array', isset( $_POST['search_field_array'] ) ? sanitize_text_field( wp_unslash( $_POST['search_field_array'] ) ) : ''); 574 575 update_option('search_field_group', isset( $_POST['search_field_group'] ) ? absint( $_POST['search_field_group'] ) : 0); 576 update_option('search_field_type', isset( $_POST['search_field_type'] ) ? absint( $_POST['search_field_type'] ) : 0); 577 update_option('search_field_status', isset( $_POST['search_field_status'] ) ? absint( $_POST['search_field_status'] ) : 0); 578 update_option('search_field_status_group', isset( $_POST['search_field_status_group'] ) ? absint( $_POST['search_field_status_group'] ) : 0); 579 update_option('search_field_price', isset( $_POST['search_field_price'] ) ? absint( $_POST['search_field_price'] ) : 0); 580 update_option('search_field_beds', isset( $_POST['search_field_beds'] ) ? absint( $_POST['search_field_beds'] ) : 0); 581 update_option('search_field_baths', isset( $_POST['search_field_baths'] ) ? absint( $_POST['search_field_baths'] ) : 0); 582 update_option('search_field_keyword', isset( $_POST['search_field_keyword'] ) ? absint( $_POST['search_field_keyword'] ) : 0); 583 584 update_option('search_field_location', isset( $_POST['search_field_location'] ) ? absint( $_POST['search_field_location'] ) : 0); 585 update_option('search_field_multitype', isset( $_POST['search_field_multitype'] ) ? absint( $_POST['search_field_multitype'] ) : 0); 586 587 update_option('search_field_features', isset( $_POST['search_field_features'] ) ? absint( $_POST['search_field_features'] ) : 0); 588 589 update_option('search_results_page', isset( $_POST['search_results_page'] ) ? absint( $_POST['search_results_page'] ) : 0); 590 590 591 591 echo '<div class="updated notice is-dismissible"><p>Settings updated successfully!</p></div>'; … … 594 594 595 595 <form method="post"> 596 <input type="hidden" class="regular-text" name="search_field_array" id="form-items-order" value="<?php echo get_option('search_field_array'); ?>"> 596 <?php wp_nonce_field( 'wppd_property_admin', 'wppd_property_admin_nonce' ); ?> 597 <input type="hidden" class="regular-text" name="search_field_array" id="form-items-order" value="<?php echo esc_attr( get_option('search_field_array') ); ?>"> 597 598 <table class="form-table"> 598 599 <tbody> … … 645 646 } 646 647 647 echo '<li data-id="' . $searchFieldItem. '">648 <svg class="svg-inline--fa fa-bars fa-w-14 fa-fw" aria-hidden="true" focusable="false" data-prefix="fa" data-icon="bars" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" data-fa-i2svg="" height="16"><path fill="currentColor" d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"></path></svg> <input type="checkbox" id="search_field_' . $searchFieldItem . '" name="search_field_' . $searchFieldItem . '" value="1" ' . (((int) get_option('search_field_' . $searchFieldItem) === 1) ? 'checked' : '') . '>649 <label for="search_field_' . $searchFieldItem . '">' . $fieldType. '</label>648 echo '<li data-id="' . esc_attr( $searchFieldItem ) . '"> 649 <svg class="svg-inline--fa fa-bars fa-w-14 fa-fw" aria-hidden="true" focusable="false" data-prefix="fa" data-icon="bars" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" data-fa-i2svg="" height="16"><path fill="currentColor" d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"></path></svg> <input type="checkbox" id="search_field_' . esc_attr( $searchFieldItem ) . '" name="search_field_' . esc_attr( $searchFieldItem ) . '" value="1" ' . checked( 1, (int) get_option('search_field_' . $searchFieldItem), false ) . '> 650 <label for="search_field_' . esc_attr( $searchFieldItem ) . '">' . esc_html( $fieldType ) . '</label> 650 651 </li>'; 651 652 } … … 676 677 <?php } else if ($tab === 'users') { 677 678 if (isset($_POST['save_users_settings'])) { 678 update_option('supernova_account_page_id', (int) $_POST['supernova_account_page_id']); 679 if ( ! isset( $_POST['wppd_property_admin_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['wppd_property_admin_nonce'] ) ), 'wppd_property_admin' ) ) { 680 wp_die( esc_html__( 'Security check failed.', 'property-drive' ) ); 681 } 682 update_option('supernova_account_page_id', isset( $_POST['supernova_account_page_id'] ) ? absint( $_POST['supernova_account_page_id'] ) : 0); 679 683 680 684 echo '<div class="updated notice is-dismissible"><p>Settings updated successfully!</p></div>'; … … 684 688 685 689 <form method="post" action=""> 690 <?php wp_nonce_field( 'wppd_property_admin', 'wppd_property_admin_nonce' ); ?> 686 691 <table class="form-table"> 687 692 <tbody> … … 705 710 <p> 706 711 <input type="checkbox" checked disabled> Profile Editor<br> 707 <input type="checkbox" checked disabled> Favourite Properties<br>708 712 </p> 709 713 </td> -
property-drive/trunk/includes/helpers.php
r3209948 r3447995 1 1 <?php 2 if ( ! defined( 'ABSPATH' ) ) { 3 exit; // Exit if accessed directly 4 } 5 2 6 function wppd_show_property_images( $property_id ) { 3 7 $image_array = get_post_meta( $property_id, 'detail_images_array', true ); … … 121 125 122 126 if ( isset( $linkedProperties ) && (string) $linkedProperties !== '' ) { 123 $out .= get_combined_property_ber( $linkedProperties );127 $out .= wppd_get_combined_property_ber( $linkedProperties ); 124 128 } elseif ( in_array( $berRating, [ 'A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3', 'D1', 'D2', 'E1', 'E2', 'F', 'G' ] ) ) { 125 129 $out = '<div class="bercrumb ber-' . $berRatingClass . '"> … … 151 155 * @return string $out 152 156 */ 153 function get_combined_property_ber( $linkedProperties ) {157 function wppd_get_combined_property_ber( $linkedProperties ) { 154 158 if ( (string) $linkedProperties !== '' ) { 155 159 $linkedPropertiesArray = explode( ',', $linkedProperties ); … … 160 164 'post_type' => 'property', 161 165 'posts_per_page' => 1, 162 'meta_query' => [ 163 [ 164 'key' => 'importer_id', 165 'value' => $linkedProperty, 166 'compare' => '=', 167 ], 168 ], 166 'meta_key' => 'importer_id', 167 'meta_value' => $linkedProperty, 169 168 ]; 170 169 $linkedPropertyObject = new WP_Query( $linkedPropertyArgs ); … … 237 236 } 238 237 239 if ( isset( $propertyMarket ) && $propertyMarket === 'New Developments' && (string) getLinkedPropertiesBedroomRange( $linkedProperties ) !== '' ) {240 return $iconString . getLinkedPropertiesBedroomRange( $linkedProperties );238 if ( isset( $propertyMarket ) && $propertyMarket === 'New Developments' && (string) wppd_get_linked_properties_bedroom_range( $linkedProperties ) !== '' ) { 239 return $iconString . wppd_get_linked_properties_bedroom_range( $linkedProperties ); 241 240 } elseif ( $bedrooms > 0 ) { 242 241 return $iconString . $bedrooms; … … 280 279 function wp4pm_get_property_price( $property_id ) { 281 280 $price = (int) get_post_meta( $property_id, 'price', true ); 282 $priceFrom = (string) getLinkedPropertiesPriceRange( $property_id );281 $priceFrom = (string) wppd_get_linked_properties_price_range( $property_id ); 283 282 284 283 $currency = get_option( 'jtg_currency' ); 285 $currency_info = jtg_currency_symbol( $currency );284 $currency_info = wppd_currency_symbol( $currency ); 286 285 $currency_symbol = $currency_info['symbol']; 287 286 … … 577 576 578 577 /** 579 * Get favourite icon.580 *581 * @since 2.1.6582 *583 * @param int $property_id Property ID.584 * @return string585 */586 function wp4pm_get_favourite_icon( $property_id ) {587 if ( (int) get_option( 'allow_favourites' ) === 1 ) {588 return '<span class="property-card--favourite pd-box-favourite" data-property-id="' . $property_id . '" tooltip="Save property" flow="left"></span>';589 }590 }591 592 593 594 /**595 578 * Get property image count. 596 579 * … … 617 600 618 601 619 function jtg_currency_symbol( $currency ) {602 function wppd_currency_symbol( $currency ) { 620 603 $currency_symbol = [ 621 604 'symbol' => '€', … … 646 629 } 647 630 648 function pd_property_view_count( $post_id, $update = false ) {631 function wppd_property_view_count( $post_id, $update = false ) { 649 632 $viewsCount = get_post_meta( $post_id, 'property_view_count', true ) ?? 0; 650 633 … … 666 649 * @return null 667 650 */ 668 function pd_property_view_increment() { 669 $property_id = $_POST['propertyId']; 651 function wppd_property_view_increment() { 652 // Verify nonce if provided 653 if ( isset( $_POST['nonce'] ) && ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'wp4pm_ajax_nonce' ) ) { 654 wp_send_json_error( 'Invalid nonce' ); 655 return; 656 } 657 658 $property_id = isset( $_POST['propertyId'] ) ? absint( $_POST['propertyId'] ) : 0; 659 660 if ( $property_id <= 0 ) { 661 wp_send_json_error( 'Invalid property ID' ); 662 return; 663 } 670 664 671 665 $viewsCount = get_post_meta( $property_id, 'property_view_count', true ); … … 674 668 update_post_meta( $property_id, 'property_view_count', $viewsCount ); 675 669 676 wp_die(); 677 } 678 add_action( 'wp_ajax_pd_property_view_increment', 'pd_property_view_increment' ); 679 add_action( 'wp_ajax_nopriv_pd_property_view_increment', 'pd_property_view_increment' ); 680 681 682 683 function get_subtypes( $typeSlug, $typeName ) { 684 $subtypes = ''; 685 686 $livingTypes = [ 687 'Not applicable', 688 'With planning', 689 'With Fore Court', 690 'With residence', 691 'Full license', 692 'Residential only', 693 'Commercial only', 694 'Residential & Commercial', 695 'Residential & Commercial', 696 'Residential units only', 697 'Residential & Commercial units', 698 'Residential & Commercial units', 699 'With Offices', 700 'Block', 701 'Residential & Commercial', 702 'Residential & Commercial', 703 'not-applicable', 704 ]; 705 706 $linkedPropertyArgs = [ 707 'post_type' => 'property', 708 'posts_per_page' => -1, 709 'tax_query' => [ 710 [ 711 'taxonomy' => 'property_type', 712 'field' => 'slug', 713 'terms' => [ $typeSlug ], 714 ], 715 ], 716 ]; 717 $linkedPropertyObject = new WP_Query( $linkedPropertyArgs ); 718 if ( $linkedPropertyObject->have_posts() ) { 719 while ( $linkedPropertyObject->have_posts() ) { 720 $linkedPropertyObject->the_post(); 721 722 $livingType = get_post_meta( $linkedPropertyObject->post->ID, 'living_type', true ); 723 724 if ( empty( $livingType ) || in_array( $livingType, $livingTypes ) ) { 725 $subtypes .= ''; 726 } else { 727 $subtypes .= '<option value="' . sanitize_title( $typeName ) . '|' . $livingType . '" data-description="">' . $typeName . ' (' . $livingType . ')</option>'; 728 } 729 } 730 } 731 732 return $subtypes; 733 } 734 735 736 737 function pd_favourites_fetch_public() { 738 $posts = $_POST['favourites']; 739 740 if ( ! empty( $posts ) ) { 741 echo do_shortcode( '[property-grid in="' . $posts . '" more="no" columns="3" pagination="no"]' ); 742 } 743 744 die(); 745 } 746 add_action( 'wp_ajax_pd_favourites_fetch_public', 'pd_favourites_fetch_public' ); 747 add_action( 'wp_ajax_nopriv_pd_favourites_fetch_public', 'pd_favourites_fetch_public' ); 748 749 750 751 function pd_favourites_fetch() { 752 $out = '<div id="pd-favourites"></div>'; 753 754 return $out; 755 } 756 add_shortcode( 'favourites', 'pd_favourites_fetch' ); 757 758 759 function save_user_favourite() { 760 if ( is_user_logged_in() ) { 761 $userId = get_current_user_id(); 762 $property_id = (int) $_POST['property_id']; 763 764 // Check if favourite exists 765 $existingFavouriteArgs = [ 766 'author' => $userId, 767 'post_type' => 'favourite', 768 'posts_per_page' => 1, 769 'meta_query' => [ 770 [ 771 'key' => '_property_id', 772 'value' => $property_id, 773 'compare' => '=', 774 ], 775 ], 776 ]; 777 $existingFavouriteObject = new WP_Query( $existingFavouriteArgs ); 778 779 if ( (int) $existingFavouriteObject->found_posts <= 0 ) { 780 // Save favourite 781 if ( $property_id > 0 ) { 782 $favouriteId = wp_insert_post( 783 [ 784 'post_title' => 'Favourite #' . $property_id . ' - ' . uniqid() . ' - ' . date( 'Y-m-d, H:i' ), 785 'post_type' => 'favourite', 786 'post_status' => 'private', 787 'post_author' => $userId, 788 ] 789 ); 790 if ( $favouriteId ) { 791 add_post_meta( $favouriteId, '_property_id', $property_id ); 792 } 793 } 794 } 795 } 796 797 wp_die(); 798 } 799 add_action( 'wp_ajax_save_user_favourite', 'save_user_favourite' ); 800 add_action( 'wp_ajax_nopriv_save_user_favourite', 'save_user_favourite' ); 801 802 function remove_user_favourite() { 803 if ( is_user_logged_in() ) { 804 $userId = get_current_user_id(); 805 $favouriteId = (int) $_POST['favourite_id']; 806 807 wp_delete_post( $favouriteId, true ); 808 } 809 810 wp_die(); 811 } 812 add_action( 'wp_ajax_remove_user_favourite', 'remove_user_favourite' ); 813 add_action( 'wp_ajax_nopriv_remove_user_favourite', 'remove_user_favourite' ); 814 815 816 817 function pd_request_contact() { 818 $pid = (int) $_POST['id']; 819 820 $to = sanitize_email( $_POST['to'] ); 821 $name = sanitize_text_field( $_POST['name'] ); 822 $email = sanitize_email( $_POST['email'] ); 823 $phone = sanitize_text_field( $_POST['phone'] ); 824 $message = wpautop( $_POST['message'] ); 670 wp_send_json_success(); 671 } 672 add_action( 'wp_ajax_pd_property_view_increment', 'wppd_property_view_increment' ); 673 add_action( 'wp_ajax_nopriv_pd_property_view_increment', 'wppd_property_view_increment' ); 674 675 676 677 function wppd_request_contact() { 678 // Verify nonce if provided 679 if ( isset( $_POST['nonce'] ) && ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'wp4pm_ajax_nonce' ) ) { 680 wp_send_json_error( 'Invalid nonce' ); 681 return; 682 } 683 684 $pid = isset( $_POST['id'] ) ? absint( $_POST['id'] ) : 0; 685 686 $to = isset( $_POST['to'] ) ? sanitize_email( wp_unslash( $_POST['to'] ) ) : ''; 687 $name = isset( $_POST['name'] ) ? sanitize_text_field( wp_unslash( $_POST['name'] ) ) : ''; 688 $email = isset( $_POST['email'] ) ? sanitize_email( wp_unslash( $_POST['email'] ) ) : ''; 689 $phone = isset( $_POST['phone'] ) ? sanitize_text_field( wp_unslash( $_POST['phone'] ) ) : ''; 690 $message = isset( $_POST['message'] ) ? wp_kses_post( wp_unslash( $_POST['message'] ) ) : ''; 691 $message = wpautop( $message ); 825 692 826 693 $subjectLine = 'Contact Request (ACQ)'; … … 829 696 <p>Contact details:</p> 830 697 <ul> 831 <li><b>Name:</b> ' . $name. '</li>832 <li><b>Email:</b> ' . $email. '</li>833 <li><b>Phone:</b> ' . $phone. '</li>834 <li><b>Sent from:</b> <a href="' . get_permalink( $pid ) . '">' . get_the_title( $pid) . '</a></li>835 <li><b>Message:</b> ' . $message. '</li>698 <li><b>Name:</b> ' . esc_html( $name ) . '</li> 699 <li><b>Email:</b> ' . esc_html( $email ) . '</li> 700 <li><b>Phone:</b> ' . esc_html( $phone ) . '</li> 701 <li><b>Sent from:</b> <a href="' . esc_url( get_permalink( $pid ) ) . '">' . esc_html( get_the_title( $pid ) ) . '</a></li> 702 <li><b>Message:</b> ' . wp_kses_post( $message ) . '</li> 836 703 </ul>'; 837 704 838 705 $headers[] = 'Content-Type: text/html;'; 839 706 $headers[] = 'X-Mailer: WordPress/PropertyDrive;'; 840 $headers[] = "Reply-To: $name <$email>;";707 $headers[] = 'Reply-To: ' . sanitize_email( $name ) . ' <' . sanitize_email( $email ) . '>'; 841 708 842 709 wp_mail( $to, $subjectLine, $body, $headers ); 843 710 } 844 add_action( 'wp_ajax_pd_request_contact', 'pd_request_contact' ); 845 add_action( 'wp_ajax_nopriv_pd_request_contact', 'pd_request_contact' ); 846 847 848 849 function get_properties_by_id() { 850 $ids = (string) $_POST['ids']; 711 add_action( 'wp_ajax_pd_request_contact', 'wppd_request_contact' ); 712 add_action( 'wp_ajax_nopriv_pd_request_contact', 'wppd_request_contact' ); 713 714 715 716 function wppd_get_properties_by_id() { 717 // Verify nonce if provided 718 if ( isset( $_POST['nonce'] ) && ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'wp4pm_ajax_nonce' ) ) { 719 wp_send_json_error( 'Invalid nonce' ); 720 return; 721 } 722 723 $ids = isset( $_POST['ids'] ) ? sanitize_text_field( wp_unslash( $_POST['ids'] ) ) : ''; 851 724 852 725 if ( ! empty( $ids ) ) { 853 echo do_shortcode( '[property-grid property-type="residential" count="-1" pagination="no" views="no" in="' . $ids . '"]');726 echo wp_kses_post( do_shortcode( '[property-grid property-type="residential" count="-1" pagination="no" views="no" in="' . esc_attr( $ids ) . '"]' ) ); 854 727 } 855 728 856 729 wp_die(); 857 730 } 858 add_action( 'wp_ajax_get_properties_by_id', ' get_properties_by_id' );859 add_action( 'wp_ajax_nopriv_get_properties_by_id', ' get_properties_by_id' );731 add_action( 'wp_ajax_get_properties_by_id', 'wppd_get_properties_by_id' ); 732 add_action( 'wp_ajax_nopriv_get_properties_by_id', 'wppd_get_properties_by_id' ); 860 733 861 734 … … 871 744 * @param int $parentId WordPress property (CPT) ID. 872 745 */ 873 function getLinkedPropertiesPriceRange( $parentId ) {746 function wppd_get_linked_properties_price_range( $parentId ) { 874 747 if ( get_post_meta( $parentId, 'property_market', true ) == 'New Developments' ) { 875 748 $currency = get_option( 'jtg_currency' ); 876 $currency_info = jtg_currency_symbol( $currency );749 $currency_info = wppd_currency_symbol( $currency ); 877 750 $currency_symbol = $currency_info['symbol']; 878 751 … … 887 760 'post_type' => 'property', 888 761 'posts_per_page' => 1, 889 'meta_query' => [ 890 [ 891 'key' => 'importer_id', 892 'value' => $linkedProperty, 893 'compare' => '=', 894 ], 895 ], 762 'meta_key' => 'importer_id', 763 'meta_value' => $linkedProperty, 896 764 ]; 897 765 $linkedPropertyObject = new WP_Query( $linkedPropertyArgs ); … … 924 792 * @param string $propertyList A list of importer_ids. 925 793 */ 926 function getLinkedPropertiesBedroomRange( $propertyList ) {794 function wppd_get_linked_properties_bedroom_range( $propertyList ) { 927 795 if ( (string) $propertyList !== '' ) { 928 796 $linkedPropertiesArray = explode( ',', $propertyList ); … … 933 801 'post_type' => 'property', 934 802 'posts_per_page' => 1, 935 'meta_query' => [ 936 [ 937 'key' => 'importer_id', 938 'value' => $linkedProperty, 939 'compare' => '=', 940 ], 941 ], 803 'meta_key' => 'importer_id', 804 'meta_value' => $linkedProperty, 942 805 ]; 943 806 $linkedPropertyObject = new WP_Query( $linkedPropertyArgs ); … … 991 854 992 855 993 function show_property_attachments( $property_id ) {856 function wppd_show_property_attachments( $property_id ) { 994 857 /** 995 858 * Get all post attachments and exclude featured image … … 1017 880 } 1018 881 1019 function get_sharing_buttons( $property_id ) {882 function wppd_get_sharing_buttons( $property_id ) { 1020 883 $property_id = (int) $property_id; 1021 884 … … 1030 893 * Register property meta box 1031 894 */ 1032 function pd_add_meta_box() {1033 add_meta_box( 'pd_meta_box', 'Property Details', ' property_metabox_callback', [ 'property' ] );1034 } 1035 add_action( 'add_meta_boxes', ' pd_add_meta_box' );895 function wppd_add_meta_box() { 896 add_meta_box( 'pd_meta_box', 'Property Details', 'wppd_property_metabox_callback', [ 'property' ] ); 897 } 898 add_action( 'add_meta_boxes', 'wppd_add_meta_box' ); 1036 899 1037 900 /** 1038 901 * eCards meta box Callback 1039 902 */ 1040 function property_metabox_callback( $post ) {903 function wppd_property_metabox_callback( $post ) { 1041 904 wp_nonce_field( 'property', 'property_nonce' ); 1042 905 … … 1053 916 <p> 1054 917 <label>Property Importer ID</label> 1055 <br><input type="text" name="importer_id" value="<?php echo intval( get_post_meta( $post_id, 'importer_id', true) ); ?>">918 <br><input type="text" name="importer_id" value="<?php echo esc_attr( intval( get_post_meta( $post_id, 'importer_id', true ) ) ); ?>"> 1056 919 </p> 1057 920 … … 1067 930 <h3>Property Media</h3> 1068 931 <div class="admin-gallery"> 1069 <?php echo show_property_attachments( get_the_ID() ); ?>932 <?php echo wp_kses_post( wppd_show_property_attachments( get_the_ID() ) ); ?> 1070 933 </div> 1071 934 1072 935 <p> 1073 936 <label>Property Tour</label> 1074 <br><input type="text" name="tour" value="<?php echo get_post_meta( $post_id, 'tours', true); ?>">937 <br><input type="text" name="tour" value="<?php echo esc_attr( get_post_meta( $post_id, 'tours', true ) ); ?>"> 1075 938 </p> 1076 939 … … 1082 945 <br> 1083 946 <?php 1084 function selectPropertyStatus( $post_id, $status ) {947 function wppd_select_property_status( $post_id, $status ) { 1085 948 $propertyStatusDb = (string) get_post_meta( $post_id, 'property_status', true ); 1086 949 … … 1090 953 <select name="property_status" id="property-status" required> 1091 954 <optgroup label="Active"> 1092 <option <?php echo selectPropertyStatus( $post_id, 'For Sale'); ?>>For Sale</option>1093 <option <?php echo selectPropertyStatus( $post_id, 'To Let'); ?>>To Let</option>955 <option <?php echo esc_attr( wppd_select_property_status( $post_id, 'For Sale' ) ); ?>>For Sale</option> 956 <option <?php echo esc_attr( wppd_select_property_status( $post_id, 'To Let' ) ); ?>>To Let</option> 1094 957 </optgroup> 1095 958 <optgroup label="Inactive"> 1096 <option <?php echo selectPropertyStatus( $post_id, 'Sale Agreed'); ?>>Sale Agreed</option>1097 <option <?php echo selectPropertyStatus( $post_id, 'Sold'); ?>>Sold</option>1098 <option <?php echo selectPropertyStatus( $post_id, 'Has Been Let'); ?>>Has Been Let</option>959 <option <?php echo esc_attr( wppd_select_property_status( $post_id, 'Sale Agreed' ) ); ?>>Sale Agreed</option> 960 <option <?php echo esc_attr( wppd_select_property_status( $post_id, 'Sold' ) ); ?>>Sold</option> 961 <option <?php echo esc_attr( wppd_select_property_status( $post_id, 'Has Been Let' ) ); ?>>Has Been Let</option> 1099 962 </optgroup> 1100 963 <optgroup label="In Progress/Other"> 1101 <option <?php echo selectPropertyStatus( $post_id, 'For Sale/To Let'); ?>>For Sale/To Let</option>1102 <option <?php echo selectPropertyStatus( $post_id, 'Coming Soon'); ?>>Coming Soon</option>1103 <option <?php echo selectPropertyStatus( $post_id, 'Under Offer'); ?>>Under Offer</option>1104 <option <?php echo selectPropertyStatus( $post_id, 'Open To Offers'); ?>>Open To Offers</option>1105 <option <?php echo selectPropertyStatus( $post_id, 'Reserved'); ?>>Reserved</option>1106 <option <?php echo selectPropertyStatus( $post_id, 'For Auction'); ?>>For Auction</option>1107 <option <?php echo selectPropertyStatus( $post_id, 'Seeking'); ?>>Seeking</option>1108 <option <?php echo selectPropertyStatus( $post_id, 'Let'); ?>>Let</option>964 <option <?php echo esc_attr( wppd_select_property_status( $post_id, 'For Sale/To Let' ) ); ?>>For Sale/To Let</option> 965 <option <?php echo esc_attr( wppd_select_property_status( $post_id, 'Coming Soon' ) ); ?>>Coming Soon</option> 966 <option <?php echo esc_attr( wppd_select_property_status( $post_id, 'Under Offer' ) ); ?>>Under Offer</option> 967 <option <?php echo esc_attr( wppd_select_property_status( $post_id, 'Open To Offers' ) ); ?>>Open To Offers</option> 968 <option <?php echo esc_attr( wppd_select_property_status( $post_id, 'Reserved' ) ); ?>>Reserved</option> 969 <option <?php echo esc_attr( wppd_select_property_status( $post_id, 'For Auction' ) ); ?>>For Auction</option> 970 <option <?php echo esc_attr( wppd_select_property_status( $post_id, 'Seeking' ) ); ?>>Seeking</option> 971 <option <?php echo esc_attr( wppd_select_property_status( $post_id, 'Let' ) ); ?>>Let</option> 1109 972 </optgroup> 1110 973 </select> … … 1113 976 <p> 1114 977 <label>Property Market</label> 1115 <br><input type="text" class="regular-text" name="market" value="<?php echo get_post_meta( $post_id, 'property_market', true); ?>">978 <br><input type="text" class="regular-text" name="market" value="<?php echo esc_attr( get_post_meta( $post_id, 'property_market', true ) ); ?>"> 1116 979 </p> 1117 980 1118 981 <p> 1119 982 <label>Property Category</label> 1120 <br><input type="text" class="regular-text" name="property_category" value="<?php echo get_post_meta( $post_id, 'property_category', true); ?>">983 <br><input type="text" class="regular-text" name="property_category" value="<?php echo esc_attr( get_post_meta( $post_id, 'property_category', true ) ); ?>"> 1121 984 <br><small>e.g. Investment, Waterfront, Urban, Coastal</small> 1122 985 </p> … … 1124 987 <p> 1125 988 <label>Price</label> 1126 <br><input id="jtg_price" type="text" class="regular-text" name="price" value="<?php echo get_post_meta( $post_id, 'price', true); ?>">989 <br><input id="jtg_price" type="text" class="regular-text" name="price" value="<?php echo esc_attr( get_post_meta( $post_id, 'price', true ) ); ?>"> 1127 990 <br> 1128 991 <label>Price Term</label> 1129 <br><input id="jtg_price_term" type="text" class="regular-text" name="price_term" value="<?php echo get_post_meta( $post_id, 'price_term', true); ?>">992 <br><input id="jtg_price_term" type="text" class="regular-text" name="price_term" value="<?php echo esc_attr( get_post_meta( $post_id, 'price_term', true ) ); ?>"> 1130 993 </p> 1131 994 <p> 1132 995 <label>Bedrooms</label> 1133 <br><input id="jtg_bedrooms" type="text" class="regular-text" name="bedrooms" value="<?php echo get_post_meta( $post_id, 'bedrooms', true); ?>">996 <br><input id="jtg_bedrooms" type="text" class="regular-text" name="bedrooms" value="<?php echo esc_attr( get_post_meta( $post_id, 'bedrooms', true ) ); ?>"> 1134 997 <br> 1135 998 <label>Bathrooms</label> 1136 <br><input id="jtg_bathrooms" type="text" class="regular-text" name="bathrooms" value="<?php echo get_post_meta( $post_id, 'bathrooms', true); ?>">999 <br><input id="jtg_bathrooms" type="text" class="regular-text" name="bathrooms" value="<?php echo esc_attr( get_post_meta( $post_id, 'bathrooms', true ) ); ?>"> 1137 1000 </p> 1138 1001 <p> 1139 1002 <label>Property Size</label> 1140 <br><input id="jtg_property_size" type="text" class="regular-text" name="property_size" value="<?php echo get_post_meta( $post_id, 'property_size', true); ?>">1003 <br><input id="jtg_property_size" type="text" class="regular-text" name="property_size" value="<?php echo esc_attr( get_post_meta( $post_id, 'property_size', true ) ); ?>"> 1141 1004 <br> 1142 1005 <label>Property Floors</label> 1143 <br><input id="jtg_property_floors" type="text" class="regular-text" name="property_floors" value="<?php echo get_post_meta( $post_id, 'property_floors', true); ?>">1006 <br><input id="jtg_property_floors" type="text" class="regular-text" name="property_floors" value="<?php echo esc_attr( get_post_meta( $post_id, 'property_floors', true ) ); ?>"> 1144 1007 </p> 1145 1008 <p> 1146 1009 <label>BER Rating</label> 1147 <br><input id="jtg_ber_rating" type="text" class="regular-text" name="ber_rating" value="<?php echo get_post_meta( $post_id, 'ber_rating', true); ?>">1010 <br><input id="jtg_ber_rating" type="text" class="regular-text" name="ber_rating" value="<?php echo esc_attr( get_post_meta( $post_id, 'ber_rating', true ) ); ?>"> 1148 1011 <bR> 1149 1012 <label>Energy Details</label> 1150 <br><input id="jtg_energy_details" type="text" class="regular-text" name="energy_details" value="<?php echo get_post_meta( $post_id, 'energy_details', true); ?>">1013 <br><input id="jtg_energy_details" type="text" class="regular-text" name="energy_details" value="<?php echo esc_attr( get_post_meta( $post_id, 'energy_details', true ) ); ?>"> 1151 1014 </p> 1152 1015 … … 1160 1023 <p> 1161 1024 <label>Latitude</label> 1162 <br><input id="jtg_latitude" type="text" class="regular-text" name="latitude" value="<?php echo get_post_meta( $post_id, 'latitude', true); ?>">1025 <br><input id="jtg_latitude" type="text" class="regular-text" name="latitude" value="<?php echo esc_attr( get_post_meta( $post_id, 'latitude', true ) ); ?>"> 1163 1026 <br> 1164 1027 <label>Longitude</label> 1165 <br><input id="jtg_longitude" type="text" class="regular-text" name="longitude" value="<?php echo get_post_meta( $post_id, 'longitude', true); ?>">1028 <br><input id="jtg_longitude" type="text" class="regular-text" name="longitude" value="<?php echo esc_attr( get_post_meta( $post_id, 'longitude', true ) ); ?>"> 1166 1029 </p> 1167 1030 … … 1169 1032 <p> 1170 1033 <label>Agent ID</label> 1171 <br><input id="jtg_agent_id" type="text" class="regular-text" name="agent_id" value="<?php echo get_post_meta( $post_id, 'agent_id', true); ?>">1034 <br><input id="jtg_agent_id" type="text" class="regular-text" name="agent_id" value="<?php echo esc_attr( get_post_meta( $post_id, 'agent_id', true ) ); ?>"> 1172 1035 <br> 1173 1036 <label>Agent Name</label> 1174 <br><input id="jtg_agent_name" type="text" class="regular-text" name="agent_name" value="<?php echo get_post_meta( $post_id, 'agent_name', true); ?>">1037 <br><input id="jtg_agent_name" type="text" class="regular-text" name="agent_name" value="<?php echo esc_attr( get_post_meta( $post_id, 'agent_name', true ) ); ?>"> 1175 1038 <br> 1176 1039 <label>Agent Email</label> 1177 <br><input id="jtg_agent_email" type="text" class="regular-text" name="agent_email" value="<?php echo get_post_meta( $post_id, 'agent_email', true); ?>">1040 <br><input id="jtg_agent_email" type="text" class="regular-text" name="agent_email" value="<?php echo esc_attr( get_post_meta( $post_id, 'agent_email', true ) ); ?>"> 1178 1041 <br> 1179 1042 <label>Agent Phone</label> 1180 <br><input id="jtg_agent_number" type="text" class="regular-text" name="agent_number" value="<?php echo get_post_meta( $post_id, 'agent_number', true); ?>">1043 <br><input id="jtg_agent_number" type="text" class="regular-text" name="agent_number" value="<?php echo esc_attr( get_post_meta( $post_id, 'agent_number', true ) ); ?>"> 1181 1044 <br> 1182 1045 <label>Agent Mobile</label> 1183 <br><input id="jtg_agent_mobile" type="text" class="regular-text" name="agent_mobile" value="<?php echo get_post_meta( $post_id, 'agent_mobile', true); ?>">1046 <br><input id="jtg_agent_mobile" type="text" class="regular-text" name="agent_mobile" value="<?php echo esc_attr( get_post_meta( $post_id, 'agent_mobile', true ) ); ?>"> 1184 1047 <br> 1185 1048 <label>Agent Qualification</label> 1186 <br><input id="jtg_agent_qualification" type="text" class="regular-text" name="agent_qualification" value="<?php echo get_post_meta( $post_id, 'agent_qualification', true); ?>">1049 <br><input id="jtg_agent_qualification" type="text" class="regular-text" name="agent_qualification" value="<?php echo esc_attr( get_post_meta( $post_id, 'agent_qualification', true ) ); ?>"> 1187 1050 </p> 1188 1051 … … 1190 1053 <p> 1191 1054 <label>Brochure 1</label> 1192 <br><input id="jtg_brochure_1" type="text" class="regular-text" name="brochure_1" value="<?php echo get_post_meta( $post_id, 'brochure_1', true); ?>">1055 <br><input id="jtg_brochure_1" type="text" class="regular-text" name="brochure_1" value="<?php echo esc_url( get_post_meta( $post_id, 'brochure_1', true ) ); ?>"> 1193 1056 <br> 1194 1057 <label>Brochure 2</label> 1195 <br><input id="jtg_brochure_2" type="text" class="regular-text" name="brochure_2" value="<?php echo get_post_meta( $post_id, 'brochure_2', true); ?>">1058 <br><input id="jtg_brochure_2" type="text" class="regular-text" name="brochure_2" value="<?php echo esc_url( get_post_meta( $post_id, 'brochure_2', true ) ); ?>"> 1196 1059 <br> 1197 1060 <label>Brochure 3</label> 1198 <br><input id="jtg_brochure_3" type="text" class="regular-text" name="brochure_3" value="<?php echo get_post_meta( $post_id, 'brochure_3', true); ?>">1061 <br><input id="jtg_brochure_3" type="text" class="regular-text" name="brochure_3" value="<?php echo esc_url( get_post_meta( $post_id, 'brochure_3', true ) ); ?>"> 1199 1062 </p> 1200 1063 </div> … … 1207 1070 * Save property meta box 1208 1071 */ 1209 function property_save_postdata( $post_id ) {1072 function wppd_property_save_postdata( $post_id ) { 1210 1073 if ( ! isset( $_POST['property_nonce'] ) ) { 1211 1074 return $post_id; 1212 1075 } 1213 1076 1214 $nonce = $_POST['property_nonce'];1077 $nonce = sanitize_text_field( wp_unslash( $_POST['property_nonce'] ) ); 1215 1078 1216 1079 if ( ! wp_verify_nonce( $nonce, 'property' ) ) { … … 1224 1087 $propertyLock = isset( $_POST['property_lock'] ) ? 1 : 0; 1225 1088 1226 $propertyImporterId = isset( $_POST['importer_id'] ) ? (int) $_POST['importer_id']: '';1227 $propertyTour = isset( $_POST['tour'] ) ? $_POST['tour']: '';1228 $propertyStatus = isset( $_POST['property_status'] ) ? sanitize_text_field( $_POST['property_status']) : '';1229 $propertyMarket = isset( $_POST['market'] ) ? sanitize_text_field( $_POST['market']) : '';1230 $propertyCategory = isset( $_POST['property_category'] ) ? sanitize_text_field( $_POST['property_category']) : '';1231 1232 $propertyPrice = isset( $_POST['price'] ) ? sanitize_text_field( $_POST['price']) : '';1233 $propertyPriceTerm = isset( $_POST['price_term'] ) ? sanitize_text_field( $_POST['price_term']) : '';1234 $propertyBedrooms = isset( $_POST['bedrooms'] ) ? (int) $_POST['bedrooms']: '';1235 $propertyBathrooms = isset( $_POST['bathrooms'] ) ? (int) $_POST['bathrooms']: '';1236 $propertySize = isset( $_POST['property_size'] ) ? sanitize_text_field( $_POST['property_size']) : '';1237 $propertyFloors = isset( $_POST['property_floors'] ) ? sanitize_text_field( $_POST['property_floors']) : '';1238 $propertyBerRating = isset( $_POST['ber_rating'] ) ? sanitize_text_field( $_POST['ber_rating']) : '';1239 $propertyEnergyDetails = isset( $_POST['energy_details'] ) ? sanitize_text_field( $_POST['energy_details']) : '';1089 $propertyImporterId = isset( $_POST['importer_id'] ) ? absint( $_POST['importer_id'] ) : ''; 1090 $propertyTour = isset( $_POST['tour'] ) ? sanitize_text_field( wp_unslash( $_POST['tour'] ) ) : ''; 1091 $propertyStatus = isset( $_POST['property_status'] ) ? sanitize_text_field( wp_unslash( $_POST['property_status'] ) ) : ''; 1092 $propertyMarket = isset( $_POST['market'] ) ? sanitize_text_field( wp_unslash( $_POST['market'] ) ) : ''; 1093 $propertyCategory = isset( $_POST['property_category'] ) ? sanitize_text_field( wp_unslash( $_POST['property_category'] ) ) : ''; 1094 1095 $propertyPrice = isset( $_POST['price'] ) ? sanitize_text_field( wp_unslash( $_POST['price'] ) ) : ''; 1096 $propertyPriceTerm = isset( $_POST['price_term'] ) ? sanitize_text_field( wp_unslash( $_POST['price_term'] ) ) : ''; 1097 $propertyBedrooms = isset( $_POST['bedrooms'] ) ? absint( $_POST['bedrooms'] ) : ''; 1098 $propertyBathrooms = isset( $_POST['bathrooms'] ) ? absint( $_POST['bathrooms'] ) : ''; 1099 $propertySize = isset( $_POST['property_size'] ) ? sanitize_text_field( wp_unslash( $_POST['property_size'] ) ) : ''; 1100 $propertyFloors = isset( $_POST['property_floors'] ) ? sanitize_text_field( wp_unslash( $_POST['property_floors'] ) ) : ''; 1101 $propertyBerRating = isset( $_POST['ber_rating'] ) ? sanitize_text_field( wp_unslash( $_POST['ber_rating'] ) ) : ''; 1102 $propertyEnergyDetails = isset( $_POST['energy_details'] ) ? sanitize_text_field( wp_unslash( $_POST['energy_details'] ) ) : ''; 1240 1103 1241 1104 $propertyIsFeatured = isset( $_POST['is_featured'] ) ? 'true' : 'false'; 1242 1105 1243 $propertyLatitude = isset( $_POST['latitude'] ) ? sanitize_text_field( $_POST['latitude']) : '';1244 $propertyLongitude = isset( $_POST['longitude'] ) ? sanitize_text_field( $_POST['longitude']) : '';1245 $propertyAgentId = isset( $_POST['agent_id'] ) ? (int) $_POST['agent_id'] : '';1246 $propertyAgentName = isset( $_POST['agent_name'] ) ? sanitize_text_field( $_POST['agent_name']) : '';1247 $propertyAgentEmail = isset( $_POST['agent_email'] ) ? sanitize_email( $_POST['agent_email']) : '';1248 $propertyAgentNumber = isset( $_POST['agent_number'] ) ? sanitize_text_field( $_POST['agent_number']) : '';1249 $propertyAgentMobile = isset( $_POST['agent_mobile'] ) ? sanitize_text_field( $_POST['agent_mobile']) : '';1250 $propertyAgentQualification = isset( $_POST['agent_qualification'] ) ? sanitize_text_field( $_POST['agent_qualification']) : '';1251 1252 $propertyBrochure1 = isset( $_POST['brochure_1'] ) ? sanitize_text_field( $_POST['brochure_1']) : '';1253 $propertyBrochure2 = isset( $_POST['brochure_2'] ) ? sanitize_text_field( $_POST['brochure_2']) : '';1254 $propertyBrochure3 = isset( $_POST['brochure_3'] ) ? sanitize_text_field( $_POST['brochure_3']) : '';1106 $propertyLatitude = isset( $_POST['latitude'] ) ? sanitize_text_field( wp_unslash( $_POST['latitude'] ) ) : ''; 1107 $propertyLongitude = isset( $_POST['longitude'] ) ? sanitize_text_field( wp_unslash( $_POST['longitude'] ) ) : ''; 1108 $propertyAgentId = isset( $_POST['agent_id'] ) ? absint( $_POST['agent_id'] ) : 0; 1109 $propertyAgentName = isset( $_POST['agent_name'] ) ? sanitize_text_field( wp_unslash( $_POST['agent_name'] ) ) : ''; 1110 $propertyAgentEmail = isset( $_POST['agent_email'] ) ? sanitize_email( wp_unslash( $_POST['agent_email'] ) ) : ''; 1111 $propertyAgentNumber = isset( $_POST['agent_number'] ) ? sanitize_text_field( wp_unslash( $_POST['agent_number'] ) ) : ''; 1112 $propertyAgentMobile = isset( $_POST['agent_mobile'] ) ? sanitize_text_field( wp_unslash( $_POST['agent_mobile'] ) ) : ''; 1113 $propertyAgentQualification = isset( $_POST['agent_qualification'] ) ? sanitize_text_field( wp_unslash( $_POST['agent_qualification'] ) ) : ''; 1114 1115 $propertyBrochure1 = isset( $_POST['brochure_1'] ) ? esc_url_raw( wp_unslash( $_POST['brochure_1'] ) ) : ''; 1116 $propertyBrochure2 = isset( $_POST['brochure_2'] ) ? esc_url_raw( wp_unslash( $_POST['brochure_2'] ) ) : ''; 1117 $propertyBrochure3 = isset( $_POST['brochure_3'] ) ? esc_url_raw( wp_unslash( $_POST['brochure_3'] ) ) : ''; 1255 1118 1256 1119 update_post_meta( $post_id, 'property_lock', $propertyLock ); … … 1309 1172 update_post_meta( $post_id, 'property_order', $propertyOrder ); 1310 1173 } 1311 add_action( 'save_post', ' property_save_postdata' );1174 add_action( 'save_post', 'wppd_property_save_postdata' ); 1312 1175 1313 1176 … … 1316 1179 * Convert a multi-dimensional array into a single-dimensional array. 1317 1180 */ 1318 function array_flatten( $array ) {1181 function wppd_array_flatten( $array ) { 1319 1182 if ( ! is_array( $array ) ) { 1320 1183 return false; … … 1324 1187 foreach ( $array as $key => $value ) { 1325 1188 if ( is_array( $value ) ) { 1326 $result = array_merge( $result, array_flatten( $value ) );1189 $result = array_merge( $result, wppd_array_flatten( $value ) ); 1327 1190 } else { 1328 1191 $result[ $key ] = $value; … … 1353 1216 add_action( 'wp_footer', 'wp4pm_analytics_footer' ); 1354 1217 function wp4pm_analytics_footer() { 1355 echo '<span id="pd-ip" data-ip="' . wp4pm_get_pd_user_ip() . '"></span>';1356 } 1357 1358 1359 1360 1361 add_action( 'admin_init', ' supernova_add_property_menu_order' );1362 1363 function supernova_add_property_menu_order() {1218 echo '<span id="pd-ip" data-ip="' . esc_attr( wp4pm_get_pd_user_ip() ) . '"></span>'; 1219 } 1220 1221 1222 1223 1224 add_action( 'admin_init', 'wppd_add_property_menu_order' ); 1225 1226 function wppd_add_property_menu_order() { 1364 1227 add_post_type_support( 'property', 'page-attributes' ); 1365 1228 } … … 1368 1231 1369 1232 1370 function supernova_accordion_item( $atts, $content = null ) {1233 function wppd_accordion_item( $atts, $content = null ) { 1371 1234 $attributes = shortcode_atts( 1372 1235 [ … … 1386 1249 } 1387 1250 1388 add_shortcode( 'supernova-accordion-item', ' supernova_accordion_item' );1251 add_shortcode( 'supernova-accordion-item', 'wppd_accordion_item' ); 1389 1252 1390 1253 … … 1405 1268 } 1406 1269 1407 echo '<img src="' . $post_thumbnail_url . '" height="60" alt="' . get_the_title( $post_id) . '">';1270 echo '<img src="' . esc_url( $post_thumbnail_url ) . '" height="60" alt="' . esc_attr( get_the_title( $post_id ) ) . '">'; 1408 1271 1409 1272 break; 1410 1273 case 'views': 1411 $viewCounter = (int) pd_property_view_count( get_the_ID(), false );1274 $viewCounter = (int) wppd_property_view_count( get_the_ID(), false ); 1412 1275 1413 1276 echo number_format( $viewCounter ); … … 1424 1287 } 1425 1288 1426 echo $status;1289 echo esc_html( $status ); 1427 1290 1428 1291 break; … … 1430 1293 $m_orig = get_post_field( 'post_modified', $post_id, 'raw' ); 1431 1294 $m_stamp = strtotime( $m_orig ); 1432 $modified = date( get_option( 'date_format' ) . ', ' . get_option( 'time_format' ), $m_stamp );1295 $modified = gmdate( get_option( 'date_format' ) . ', ' . get_option( 'time_format' ), $m_stamp ); 1433 1296 $modr_id = get_post_meta( $post_id, '_edit_last', true ); 1434 1297 $auth_id = get_post_field( 'post_author', $post_id, 'raw' ); … … 1436 1299 $user_info = get_userdata( $user_id ); 1437 1300 1438 echo $modified . '<br>by <strong>' . $user_info->display_name . '<strong>';1301 echo esc_html( $modified ) . '<br>by <strong>' . esc_html( $user_info->display_name ) . '</strong>'; 1439 1302 1440 1303 break; 1441 1304 case 'modified_source': 1442 echo date( get_option( 'date_format' ) . ', ' . get_option( 'time_format' ), strtotime( get_post_meta( $post_id, 'date_modified', true ) ) ) . '<br>by <strong>' . get_post_meta( $post_id, 'source', true ) . '<strong>'; 1305 $date_modified = get_post_meta( $post_id, 'date_modified', true ); 1306 $source = get_post_meta( $post_id, 'source', true ); 1307 echo esc_html( gmdate( get_option( 'date_format' ) . ', ' . get_option( 'time_format' ), strtotime( $date_modified ) ) ) . '<br>by <strong>' . esc_html( $source ) . '</strong>'; 1443 1308 1444 1309 break; … … 1465 1330 1466 1331 /**/ 1467 add_action( 'init', ' supernova_access_init' );1468 function supernova_access_init() {1332 add_action( 'init', 'wppd_access_init' ); 1333 function wppd_access_init() { 1469 1334 if ( is_admin() && ! current_user_can( 'administrator' ) && ! ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) { 1470 wp_ redirect( home_url() );1335 wp_safe_redirect( home_url() ); 1471 1336 1472 1337 exit; 1473 1338 } 1474 1339 } 1475 add_action( 'after_setup_theme', ' supernova_remove_admin_bar' );1476 1477 function supernova_remove_admin_bar() {1340 add_action( 'after_setup_theme', 'wppd_remove_admin_bar' ); 1341 1342 function wppd_remove_admin_bar() { 1478 1343 if ( ! current_user_can( 'administrator' ) && ! is_admin() ) { 1479 1344 show_admin_bar( false ); -
property-drive/trunk/includes/inline_styling.php
r2354697 r3447995 1 1 <?php 2 if ( ! defined( 'ABSPATH' ) ) { 3 exit; // Exit if accessed directly 4 } 5 2 6 function wp4pm_add_plugin_styles() { 3 7 $ribbonColourSale = get_option('ribbon_colour_sale'); … … 11 15 }'; 12 16 13 wp_register_style('ui-custom', false );17 wp_register_style('ui-custom', false, array(), WPPD_VERSION); 14 18 wp_add_inline_style('ui-custom', $css); 15 19 } -
property-drive/trunk/includes/meta.php
r2361321 r3447995 1 1 <?php 2 if ( ! defined( 'ABSPATH' ) ) { 3 exit; // Exit if accessed directly 4 } 5 2 6 /** 3 7 * Add meta box … … 6 10 */ 7 11 function wppd_add_meta_boxes($post) { 8 add_meta_box('featured_property_meta_box', 'Advanced Property Settings', ' featured_property_build_meta_box', ['property'], 'side', 'low');12 add_meta_box('featured_property_meta_box', 'Advanced Property Settings', 'wppd_featured_property_build_meta_box', ['property'], 'side', 'low'); 9 13 } 10 14 … … 18 22 * @param post $post The post object 19 23 */ 20 function featured_property_build_meta_box($post) {24 function wppd_featured_property_build_meta_box($post) { 21 25 wp_nonce_field(basename(__FILE__), 'featured_property_meta_box_nonce'); 22 26 … … 45 49 * @param int $post_id The post ID. 46 50 */ 47 function featured_property_save_meta_box_data($post_id) {48 if (!isset($_POST['featured_property_meta_box_nonce']) || !wp_verify_nonce( $_POST['featured_property_meta_box_nonce'], basename(__FILE__))) {51 function wppd_featured_property_save_meta_box_data($post_id) { 52 if (!isset($_POST['featured_property_meta_box_nonce']) || !wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['featured_property_meta_box_nonce'] ) ), basename(__FILE__))) { 49 53 return; 50 54 } … … 56 60 } 57 61 58 $propertyTemplate = isset($_POST['property_template']) ? (int) $_POST['property_template']: '';62 $propertyTemplate = isset($_POST['property_template']) ? absint( $_POST['property_template'] ) : ''; 59 63 60 64 update_post_meta($post_id, '_property_template', $propertyTemplate); 61 65 } 62 66 63 add_action('save_post', ' featured_property_save_meta_box_data');67 add_action('save_post', 'wppd_featured_property_save_meta_box_data'); -
property-drive/trunk/includes/property_search.php
r2208719 r3447995 1 1 <?php 2 function jtg_add_query_vars($public_query_vars) { 2 if ( ! defined( 'ABSPATH' ) ) { 3 exit; // Exit if accessed directly 4 } 5 6 function wppd_add_query_vars($public_query_vars) { 3 7 $public_query_vars[] = 'property_status'; 4 8 $public_query_vars[] = 'property_type'; … … 14 18 return $public_query_vars; 15 19 } 16 add_filter('query_vars', ' jtg_add_query_vars');20 add_filter('query_vars', 'wppd_add_query_vars'); -
property-drive/trunk/includes/setup-plugin-options.php
r3209948 r3447995 1 1 <?php 2 if ( ! defined( 'ABSPATH' ) ) { 3 exit; // Exit if accessed directly 4 } 5 2 6 /** 3 7 * Build property custom post type … … 155 159 156 160 add_option( 'allow_quick_contact', 1 ); 157 add_option( 'allow_favourites', 0 );158 161 add_option( 'show_related_properties', 1 ); 159 162 -
property-drive/trunk/modules/init.php
r3059897 r3447995 1 1 <?php 2 if ( ! defined( 'ABSPATH' ) ) { 3 exit; // Exit if accessed directly 4 } 5 2 6 require_once 'user_sign_up.php'; 3 7 require_once 'user_dashboard.php'; 4 8 5 require_once 'cpt-favourites.php';6 7 9 require_once 'slider/slider.php'; -
property-drive/trunk/modules/slider/slider.php
r3059897 r3447995 1 1 <?php 2 if ( ! defined( 'ABSPATH' ) ) { 3 exit; // Exit if accessed directly 4 } 5 2 6 function wp4pm_slider_enqueue() { 3 7 wp_enqueue_style('slider', plugins_url('/slider.css', __FILE__), [], '1.0.1'); … … 7 11 wp_enqueue_script('slider', plugins_url('/slider.js', __FILE__), ['flickity'], '1.0.1', true); 8 12 wp_localize_script('slider', 'ajaxVar', [ 9 'ajaxurl' => admin_url('admin-ajax.php') 13 'ajaxurl' => admin_url('admin-ajax.php'), 14 'nonce' => wp_create_nonce('slider_nonce') 10 15 ]); 11 16 } … … 15 20 16 21 function wp4pm_show_slider($atts) { 22 // Sanitize and validate attributes 17 23 $attributes = shortcode_atts([ 18 24 'type' => 'slide', … … 26 32 ], $atts); 27 33 28 $out = '<div class="slider-wrap" data-controls="' . $attributes['controls'] . '" data-type="' . $attributes['type'] . '" data-mobile="' . $attributes['mobile'] . '" data-fullheight="' . $attributes['fullheight'] . '" data-fullwidth="' . $attributes['fullwidth'] . '" data-zoom="' . $attributes['zoom'] . '" data-ids="' . $attributes['ids'] . '" data-interval="' . $attributes['interval'] . '"><div class="slider-wrap-spinner"></div></div>'; 34 // Validate numeric values 35 $attributes['mobile'] = absint($attributes['mobile']); 36 $attributes['interval'] = absint($attributes['interval']); 37 38 // Validate boolean values 39 $attributes['controls'] = in_array($attributes['controls'], ['yes', 'no']) ? $attributes['controls'] : 'yes'; 40 $attributes['fullheight'] = in_array($attributes['fullheight'], ['yes', 'no']) ? $attributes['fullheight'] : 'no'; 41 $attributes['fullwidth'] = in_array($attributes['fullwidth'], ['yes', 'no']) ? $attributes['fullwidth'] : 'yes'; 42 $attributes['zoom'] = in_array($attributes['zoom'], ['yes', 'no']) ? $attributes['zoom'] : 'no'; 43 44 // Sanitize type 45 $attributes['type'] = sanitize_title($attributes['type']); 46 47 // Sanitize IDs 48 $attributes['ids'] = sanitize_text_field($attributes['ids']); 49 50 $out = '<div class="slider-wrap" data-controls="' . esc_attr($attributes['controls']) . '" data-type="' . esc_attr($attributes['type']) . '" data-mobile="' . esc_attr($attributes['mobile']) . '" data-fullheight="' . esc_attr($attributes['fullheight']) . '" data-fullwidth="' . esc_attr($attributes['fullwidth']) . '" data-zoom="' . esc_attr($attributes['zoom']) . '" data-ids="' . esc_attr($attributes['ids']) . '" data-interval="' . esc_attr($attributes['interval']) . '"><div class="slider-wrap-spinner"></div></div>'; 29 51 30 52 return $out; … … 36 58 37 59 function wp4pm_simple_slider_helper() { 60 // Verify nonce 61 if (!isset($_POST['nonce']) || !wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'slider_nonce')) { 62 wp_send_json_error('Invalid nonce'); 63 } 64 38 65 $out = ''; 39 66 40 $ids = sanitize_text_field($_POST['ids']); 67 // Sanitize and validate input 68 $ids = isset($_POST['ids']) ? sanitize_text_field( wp_unslash( $_POST['ids'] ) ) : ''; 69 $type = isset($_POST['type']) ? sanitize_title( wp_unslash( $_POST['type'] ) ) : ''; 70 $zoom = isset($_POST['zoom']) ? sanitize_title( wp_unslash( $_POST['zoom'] ) ) : ''; 71 $fullheight = isset($_POST['fullheight']) ? sanitize_title( wp_unslash( $_POST['fullheight'] ) ) : ''; 72 $fullwidth = isset($_POST['fullwidth']) ? sanitize_title( wp_unslash( $_POST['fullwidth'] ) ) : ''; 73 74 // Validate boolean values 75 $zoom = in_array($zoom, ['yes', 'no']) ? $zoom : 'no'; 76 $fullheight = in_array($fullheight, ['yes', 'no']) ? $fullheight : 'no'; 77 $fullwidth = in_array($fullwidth, ['yes', 'no']) ? $fullwidth : 'yes'; 41 78 42 79 if ((string) $ids !== '') { 43 80 $idArray = array_map('trim', explode(',', $ids)); 44 81 $idArray = array_filter($idArray); 82 $idArray = array_map('intval', $idArray); // Ensure all IDs are integers 45 83 } 46 47 $type = sanitize_title($_POST['type']);48 $zoom = sanitize_title($_POST['zoom']);49 50 $fullheight = sanitize_title($_POST['fullheight']);51 $fullwidth = sanitize_title($_POST['fullwidth']);52 84 53 85 $homepageHeroHeight = ((string) $fullheight === 'yes') ? 'fullvh' : ''; 54 86 $homepageHeroWidth = ((string) $fullwidth === 'yes') ? 'supernova-fullwidth' : ''; 55 87 56 $out .= '<div class="slider ' . $homepageHeroWidth . ' homepage-hero ' . $homepageHeroHeight. '">88 $out .= '<div class="slider ' . esc_attr($homepageHeroWidth) . ' homepage-hero ' . esc_attr($homepageHeroHeight) . '"> 57 89 <div class="homepage-hero-slider">'; 58 90 $args = [ … … 76 108 $hero = $hero[0]; 77 109 if ((string) get_post_meta(get_the_ID(), '_hero_property_image', true) !== '') { 78 $hero = get_post_meta(get_the_ID(), '_hero_property_image', true);110 $hero = esc_url(get_post_meta(get_the_ID(), '_hero_property_image', true)); 79 111 } 80 112 … … 82 114 $slideContent = do_shortcode(get_the_content(get_the_ID())); 83 115 if (!empty(get_post_meta(get_the_ID(), 'slide-video', true))) { 84 $dataVideo = '<video playsinline autoplay muted loop src="' . trim(get_post_meta(get_the_ID(), 'slide-video', true)) . '" type="video/mp4" width="100%" height="100%"></video>';116 $dataVideo = '<video playsinline autoplay muted loop src="' . esc_url(trim(get_post_meta(get_the_ID(), 'slide-video', true))) . '" type="video/mp4" width="100%" height="100%"></video>'; 85 117 } 86 $zoomContent = ((string) $zoom === 'yes') ? '<div class="slide-inner-zoom" style="background: url(' . $hero. ') no-repeat center center; background-size: cover;"></div>' : '';118 $zoomContent = ((string) $zoom === 'yes') ? '<div class="slide-inner-zoom" style="background: url(' . esc_url($hero) . ') no-repeat center center; background-size: cover;"></div>' : ''; 87 119 88 $out .= '<div class="slide slide-' . get_the_ID() . ' block" style="background: url(' . $hero. ') no-repeat center center; background-size: cover;">' .120 $out .= '<div class="slide slide-' . esc_attr(get_the_ID()) . ' block" style="background: url(' . esc_url($hero) . ') no-repeat center center; background-size: cover;">' . 89 121 $zoomContent . 90 122 $dataVideo . 91 92 123 '<div class="wrap">' . 93 $slideContent.124 wp_kses_post($slideContent) . 94 125 '</div> 95 126 </div>'; … … 100 131 </div>'; 101 132 102 echo $out;133 echo wp_kses_post( $out ); 103 134 104 135 wp_die(); … … 120 151 $autoPlay = ((int) get_option('flickity_autoPlay') > 0) ? (int) get_option('flickity_autoPlay') : 'false'; 121 152 122 $out = '<div class="flickity-carousel supernova-fullwidth" data-flickity=\'{ "contain": true, "imagesLoaded": true, "adaptiveHeight": false, "lazyLoad": true, "pageDots": false, "wrapAround": ' . $wrapAround . ', "groupCells": ' . $groupCells . ', "groupCells": ' . $groupCellsValue . ', "fullscreen": true, "autoplay": ' . $autoPlay. ' }\'>';153 $out = '<div class="flickity-carousel supernova-fullwidth" data-flickity=\'{ "contain": true, "imagesLoaded": true, "adaptiveHeight": false, "lazyLoad": true, "pageDots": false, "wrapAround": ' . esc_attr($wrapAround) . ', "groupCells": ' . esc_attr($groupCells) . ', "groupCells": ' . esc_attr($groupCellsValue) . ', "fullscreen": true, "autoplay": ' . esc_attr($autoPlay) . ' }\'>'; 123 154 foreach ($imageArray as $imageUri) { 124 155 $out .= '<div class="carousel-cell"> 125 <img loading="eager" src="' . $imageUri . '" height="480" alt="">156 <img loading="eager" src="' . esc_url($imageUri) . '" height="480" alt="' . esc_attr__('Property Image', 'property-drive') . '"> 126 157 </div>'; 127 158 } 128 159 $out .= '</div>'; 129 160 130 echo $out;161 echo wp_kses_post( $out ); 131 162 } 132 163 … … 140 171 $out = '<div class="flickity-carousel-parsley--wrap">'; 141 172 142 $out .= '<div class="flickity-carousel flickity-carousel-parsley supernova-fullwidth" data-flickity=\'{ "contain": true, "imagesLoaded": true, "adaptiveHeight": false, "lazyLoad": true, "pageDots": false, "wrapAround": true, "groupCells": true, "groupCells": 1, "fullscreen": true, "autoplay": ' . $autoPlay. ' }\'>';173 $out .= '<div class="flickity-carousel flickity-carousel-parsley supernova-fullwidth" data-flickity=\'{ "contain": true, "imagesLoaded": true, "adaptiveHeight": false, "lazyLoad": true, "pageDots": false, "wrapAround": true, "groupCells": true, "groupCells": 1, "fullscreen": true, "autoplay": ' . esc_attr($autoPlay) . ' }\'>'; 143 174 foreach ($imageArray as $imageUri) { 144 175 $imageUri = wppd_remove_var($imageUri, 'w'); … … 148 179 149 180 $out .= '<div class="carousel-cell"> 150 <img loading="eager" src="' . $imageUri . '" height="720" alt="">181 <img loading="eager" src="' . esc_url($imageUri) . '" height="720" alt="' . esc_attr__('Property Image', 'property-drive') . '"> 151 182 </div>'; 152 183 } … … 154 185 $out .= '<div class="flickity-carousel-parsley--elements"> 155 186 <ul> 156 <li><a href="#" id="flickity-view-fullscreen"> Gallery</a></li>187 <li><a href="#" id="flickity-view-fullscreen">' . esc_html__('Gallery', 'property-drive') . '</a></li> 157 188 </ul> 158 189 </div>'; 159 190 $out .= '</div>'; 160 191 161 echo $out;192 echo wp_kses_post( $out ); 162 193 } -
property-drive/trunk/modules/user_dashboard.php
r3059897 r3447995 1 1 <?php 2 function jtg_user_dashboard() { 2 if ( ! defined( 'ABSPATH' ) ) { 3 exit; // Exit if accessed directly 4 } 5 6 function wppd_user_dashboard() { 3 7 $out = ''; 4 8 … … 12 16 // Save user details 13 17 if (isset($_POST['supernova-save-user-profile'])) { 14 wp_update_user([ 15 'ID' => $userData->ID, 16 'first_name' => sanitize_text_field($_POST['first_name']), 17 'last_name' => sanitize_text_field($_POST['last_name']), 18 'user_email' => sanitize_email($_POST['user_email']) 19 ]); 20 update_user_meta($userData->ID, 'user_phone', sanitize_text_field($_POST['user_phone'])); 18 if ( ! isset( $_POST['user_profile_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['user_profile_nonce'] ) ), 'user_profile_update' ) ) { 19 $out .= '<p>Security check failed.</p>'; 20 } else { 21 wp_update_user([ 22 'ID' => $userData->ID, 23 'first_name' => isset( $_POST['first_name'] ) ? sanitize_text_field( wp_unslash( $_POST['first_name'] ) ) : '', 24 'last_name' => isset( $_POST['last_name'] ) ? sanitize_text_field( wp_unslash( $_POST['last_name'] ) ) : '', 25 'user_email' => isset( $_POST['user_email'] ) ? sanitize_email( wp_unslash( $_POST['user_email'] ) ) : '' 26 ]); 27 update_user_meta($userData->ID, 'user_phone', isset( $_POST['user_phone'] ) ? sanitize_text_field( wp_unslash( $_POST['user_phone'] ) ) : ''); 21 28 22 $out .= '<p>Profile updated successfully.</p>'; 29 $out .= '<p>Profile updated successfully.</p>'; 30 } 23 31 } 24 32 25 $out .= '<h2>' . $userData->first_name . ' ' . $userData->last_name;33 $out .= '<h2>' . esc_html( $userData->first_name ) . ' ' . esc_html( $userData->last_name ); 26 34 $out .= '</h2>'; 27 35 28 $out .= '<p>Hi ' . $userData->first_name . ', you can manage your profile and account settings. <a href="' . wp_logout_url(home_url()) . '">Logout</a>.</p>';36 $out .= '<p>Hi ' . esc_html( $userData->first_name ) . ', you can manage your profile and account settings. <a href="' . esc_url( wp_logout_url(home_url()) ) . '">Logout</a>.</p>'; 29 37 30 38 $out .= '<details class="user-dashboard-menu-item"> … … 36 44 <h3>My Profile</h3> 37 45 <form class="supernova-profile-form" method="post"> 46 ' . wp_nonce_field( 'user_profile_update', 'user_profile_nonce', true, false ) . ' 38 47 <div class="wp-block-columns has-2-columns"> 39 48 <div class="wp-block-column"> 40 49 <p> 41 50 First Name<br> 42 <input type="text" id="first_name" name="first_name" value="' . $userData->first_name. '" size="48">51 <input type="text" id="first_name" name="first_name" value="' . esc_attr( $userData->first_name ) . '" size="48"> 43 52 </p> 44 53 <p> 45 54 Last Name<br> 46 <input type="text" id="last_name" name="last_name" value="' . $userData->last_name. '" size="48">55 <input type="text" id="last_name" name="last_name" value="' . esc_attr( $userData->last_name ) . '" size="48"> 47 56 </p> 48 57 </div> … … 50 59 <p> 51 60 Phone Number<br> 52 <input type="text" id="user_phone" name="user_phone" value="' . get_the_author_meta('user_phone', $userData->ID) . '" size="48">61 <input type="text" id="user_phone" name="user_phone" value="' . esc_attr( get_the_author_meta('user_phone', $userData->ID) ) . '" size="48"> 53 62 </p> 54 63 <p> 55 64 Email Address<br> 56 <input type="email" id="user_email" name="user_email" value="' . $userData->user_email. '" size="48">65 <input type="email" id="user_email" name="user_email" value="' . esc_attr( $userData->user_email ) . '" size="48"> 57 66 </p> 58 67 <p> … … 65 74 66 75 <details class="user-dashboard-menu-item"> 67 <summary title="Click to expand this section">68 My Favourite Properties69 <small>Save favourite properties in a shortlist.</small>70 </summary>71 72 <h3>Favourite Properties</h3>';73 74 $property_favourites = get_posts([75 'post_type' => 'favourite',76 'posts_per_page' => -1,77 'post_status' => 'private',78 'author' => get_current_user_id(),79 ]);80 81 if ($property_favourites) {82 $out .= '<div>83 <table width="100%">84 <thead>85 <tr>86 <th></th>87 <th>Property Name</th>88 <th>Added</th>89 </tr>90 </thead>91 <tbody>';92 93 foreach ($property_favourites as $favourite) {94 $propertyId = get_post_meta($favourite->ID, '_property_id', true);95 $property_title = get_the_title($propertyId);96 $property_url = get_permalink($propertyId);97 98 $out .= '<tr data-property-id="' . $propertyId . '" id="favourite-row-' . $favourite->ID . '">99 <td>100 <a href="#" class="remove-user-favourite" data-favourite-id="' . $favourite->ID . '">101 Delete102 </a>103 </td>104 <td>105 <a href="'.$property_url.'" target="_blank">'.$property_title.'</a>106 </td>107 <td>' . $favourite->post_date . '</td>108 </tr>';109 }110 111 $out .= '</tbody>112 </table>113 </div>';114 } else {115 $out .= '<p>You have not saved any properties to your favourites list yet, you can do this by visiting a property and clicking the red heart.</p>116 <p>To remove a favourite, you can do so from here or clicking the empty heart on the property.</p>';117 }118 $out .= '</details>';119 120 $out .= '<details class="user-dashboard-menu-item">121 76 <summary title="Click to expand this section"> 122 77 My Documents … … 142 97 $attachmentsQuery->the_post(); 143 98 $out .= '<div> 144 <a href="' . $attachmentsQuery->post->guid . '" class="ui-button" target="_blank">View document</a>' . $attachmentsQuery->post->post_title.99 <a href="' . esc_url( $attachmentsQuery->post->guid ) . '" class="ui-button" target="_blank">View document</a>' . esc_html( $attachmentsQuery->post->post_title ) . 145 100 '</div>'; 146 101 } … … 179 134 180 135 '<p> 181 <small>Your account gives you access to alerts, notifications , favouritesand more.</small>136 <small>Your account gives you access to alerts, notifications and more.</small> 182 137 </p> 183 138 </div> … … 185 140 <h4>Sign Up</h4>' . 186 141 187 supernova_custom_registration() . '142 wppd_custom_registration() . ' 188 143 </div> 189 144 </div> … … 195 150 } 196 151 197 add_shortcode('user-dashboard', ' jtg_user_dashboard');152 add_shortcode('user-dashboard', 'wppd_user_dashboard'); -
property-drive/trunk/modules/user_sign_up.php
r2210797 r3447995 1 1 <?php 2 function supernova_custom_registration() { 2 if ( ! defined( 'ABSPATH' ) ) { 3 exit; // Exit if accessed directly 4 } 5 6 function wppd_custom_registration() { 3 7 $out = ''; 4 8 5 9 if (isset($_POST['supernova_register'])) { 6 global $registrationErrors; 10 if ( ! isset( $_POST['user_registration_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['user_registration_nonce'] ) ), 'user_registration' ) ) { 11 $out .= '<div class="ui-notification ui-notification--error">Security check failed.</div>'; 12 return $out; 13 } 14 15 global $wppd_registration_errors; 7 16 8 $ registrationErrors = new WP_Error;17 $wppd_registration_errors = new WP_Error; 9 18 10 $username = sanitize_user($_POST['username']); 11 $password = esc_attr($_POST['password']); 12 $email = sanitize_email($_POST['email']); 13 $firstName = sanitize_text_field($_POST['fname']); 14 $lastName = sanitize_text_field($_POST['lname']); 19 $username = isset( $_POST['username'] ) ? sanitize_user( wp_unslash( $_POST['username'] ) ) : ''; 20 $password_raw = isset( $_POST['password'] ) ? sanitize_text_field( wp_unslash( $_POST['password'] ) ) : ''; 21 // Passwords should not be sanitized as it would strip special characters needed for security 22 // Only validate that it's a string and doesn't contain null bytes 23 $password = is_string( $password_raw ) ? str_replace( "\0", '', $password_raw ) : ''; 24 $email = isset( $_POST['email'] ) ? sanitize_email( wp_unslash( $_POST['email'] ) ) : ''; 25 $firstName = isset( $_POST['fname'] ) ? sanitize_text_field( wp_unslash( $_POST['fname'] ) ) : ''; 26 $lastName = isset( $_POST['lname'] ) ? sanitize_text_field( wp_unslash( $_POST['lname'] ) ) : ''; 15 27 16 28 if (empty($username) || empty($password) || empty($email)) { 17 $ registrationErrors->add('field', 'You have to fill in all the required fields.');29 $wppd_registration_errors->add('field', 'You have to fill in all the required fields.'); 18 30 } 19 31 if (!validate_username($username) || username_exists($username) || 4 > strlen($username)) { 20 $ registrationErrors->add('username_invalid', 'The username is invalid or already in use.');32 $wppd_registration_errors->add('username_invalid', 'The username is invalid or already in use.'); 21 33 } 22 34 if (5 > strlen($password)) { 23 $ registrationErrors->add('password', 'Your password needs to be longer than 5 characters.');35 $wppd_registration_errors->add('password', 'Your password needs to be longer than 5 characters.'); 24 36 } 25 37 if (!is_email($email) || email_exists($email)) { 26 $ registrationErrors->add('email_invalid', 'The email address is invalid or already in use.');38 $wppd_registration_errors->add('email_invalid', 'The email address is invalid or already in use.'); 27 39 } 28 if (is_wp_error($ registrationErrors)) {29 foreach ($ registrationErrors->get_error_messages() as $error) {40 if (is_wp_error($wppd_registration_errors)) { 41 foreach ($wppd_registration_errors->get_error_messages() as $error) { 30 42 $out .= '<div class="ui-notification ui-notification--warning">' . $error . '</div>'; 31 43 } 32 44 } 33 45 34 if (1 > count($ registrationErrors->get_error_messages())) {46 if (1 > count($wppd_registration_errors->get_error_messages())) { 35 47 $userData = [ 36 48 'user_login' => $username, … … 48 60 $out .= '<div class="supernova-registration-form"> 49 61 <form method="post"> 62 ' . wp_nonce_field( 'user_registration', 'user_registration_nonce', true, false ) . ' 50 63 <p> 51 64 <label for="username">Username <b>*</b></label> … … 77 90 } 78 91 79 add_shortcode('supernova-registration', ' supernova_custom_registration');92 add_shortcode('supernova-registration', 'wppd_custom_registration'); -
property-drive/trunk/property-drive.php
r3209948 r3447995 1 1 <?php 2 if ( ! defined( 'ABSPATH' ) ) { 3 exit; // Exit if accessed directly 4 } 5 2 6 /** 3 7 * Plugin Name: Property Drive … … 9 13 * License: GNU General Public License v3 or later 10 14 * License URI: https://www.gnu.org/licenses/gpl-3.0.html 15 * Text Domain: property-drive 11 16 */ 12 17 … … 81 86 array( 82 87 'ajaxurl' => admin_url( 'admin-ajax.php' ), 88 'nonce' => wp_create_nonce( 'wp4pm_ajax_nonce' ), 83 89 ) 84 90 ); … … 88 94 wp_enqueue_style( 'wp-color-picker' ); 89 95 90 wp_enqueue_style( 'admin-ui', plugins_url( 'assets/css/ui-admin.css', __FILE__ ) );96 wp_enqueue_style( 'admin-ui', plugins_url( 'assets/css/ui-admin.css', __FILE__ ), array(), WPPD_VERSION ); 91 97 92 98 wp_enqueue_script( 'sortable', plugins_url( 'assets/js/Sortable.min.js', __FILE__ ), array(), '1.7.0', true ); 93 99 94 wp_enqueue_script( 'jtg-admin-ui-js', plugins_url( 'assets/js/admin_ui.js', __FILE__ ), array( 'sortable', 'wp-color-picker', 'jquery' ), '', true );100 wp_enqueue_script( 'jtg-admin-ui-js', plugins_url( 'assets/js/admin_ui.js', __FILE__ ), array( 'sortable', 'wp-color-picker', 'jquery' ), WPPD_VERSION, true ); 95 101 wp_localize_script( 96 102 'jtg-admin-ui-js', … … 141 147 $out .= wp4pm_get_property_status_ribbon( $property_id ); 142 148 $out .= wp4pm_get_property_image_count( $property_id, true ); 143 $out .= wp4pm_get_favourite_icon( $property_id );144 149 145 150 // Thumbnail -
property-drive/trunk/readme.txt
r3059897 r3447995 3 3 Tags: property, real estate, estate agents, house, home 4 4 Requires at least: 5.6 5 Tested up to: 6. 55 Tested up to: 6.9 6 6 Requires PHP: 7.0 7 7 Stable tag: 1.1.2 … … 16 16 17 17 Property Drive uses custom embedded icons with no external dependencies, Google Maps (API key required), Google Street View, OpenStreetMap, multiselect filters, a full page Map Navigator and more. 18 19 == Third-Party Services == 20 21 This plugin uses the following third-party services: 22 23 * **Google Maps**: This plugin may use Google Maps API to display property locations on maps. When enabled, property location data may be sent to Google Maps servers. Google Maps requires an API key to be configured in the plugin settings. 24 * Service: https://www.google.com/maps 25 * Terms of Service: https://www.google.com/intl/en_us/help/terms_maps.html 26 * Privacy Policy: https://policies.google.com/privacy 27 28 * **YouTube**: This plugin may embed YouTube videos when property content contains YouTube video links. When YouTube videos are embedded, data may be sent to YouTube servers. 29 * Service: https://www.youtube.com 30 * Terms of Service: https://www.youtube.com/static?template=terms 31 * Privacy Policy: https://policies.google.com/privacy 18 32 19 33 If you have a Property Drive account, you can hook up to the API and synchronize your existing properties. -
property-drive/trunk/shortcodes/property-grid.php
r3059897 r3447995 1 1 <?php 2 if ( ! defined( 'ABSPATH' ) ) { 3 exit; // Exit if accessed directly 4 } 5 2 6 function wp4pm_property_grid($atts) { 3 7 $attributes = shortcode_atts([ … … 32 36 'post_type' => 'property', 33 37 'post_status' => 'publish', 34 'suppress_filters' => true,35 38 'paged' => $paged, 36 39 ]; … … 236 239 'taxonomy' => 'property_type', 237 240 'field' => 'slug', 238 'terms' => array_flatten($propertyTypeArray)241 'terms' => wppd_array_flatten($propertyTypeArray) 239 242 ]); 240 243 } … … 253 256 } 254 257 255 256 258 // Read-only GET params for display sort order; no state change — nonce not required. 259 // phpcs:disable WordPress.Security.NonceVerification.Recommended 257 260 if (isset($_GET['orderby'])) { 258 $orderBy = (string) sanitize_text_field( $_GET['orderby']);259 $order = (string) sanitize_text_field($_GET['order_direction']);261 $orderBy = (string) sanitize_text_field( wp_unslash( $_GET['orderby'] ) ); 262 $order = isset( $_GET['order_direction'] ) ? (string) sanitize_text_field( wp_unslash( $_GET['order_direction'] ) ) : 'ASC'; 260 263 261 264 if ($orderBy === 'price') { … … 314 317 } 315 318 } 319 // phpcs:enable WordPress.Security.NonceVerification.Recommended 316 320 317 321 $query = new WP_Query($queryArgsMeta); -
property-drive/trunk/shortcodes/property-map.php
r3059897 r3447995 1 1 <?php 2 if ( ! defined( 'ABSPATH' ) ) { 3 exit; // Exit if accessed directly 4 } 5 2 6 function wp4pm_property_map($atts) { 3 7 $attributes = shortcode_atts([ … … 26 30 'post_type' => 'property', 27 31 'post_status' => 'publish', 28 'suppress_filters' => true,29 32 'paged' => $paged, 30 33 ]; … … 211 214 'taxonomy' => 'property_type', 212 215 'field' => 'slug', 213 'terms' => array_flatten($propertyTypeArray)216 'terms' => wppd_array_flatten($propertyTypeArray) 214 217 ]); 215 218 } … … 228 231 } 229 232 230 231 233 // Read-only GET params for display sort order; no state change — nonce not required. 234 // phpcs:disable WordPress.Security.NonceVerification.Recommended 232 235 if (isset($_GET['orderby'])) { 233 $orderBy = (string) sanitize_text_field( $_GET['orderby']);234 $order = (string) sanitize_text_field($_GET['order_direction']);236 $orderBy = (string) sanitize_text_field( wp_unslash( $_GET['orderby'] ) ); 237 $order = isset( $_GET['order_direction'] ) ? (string) sanitize_text_field( wp_unslash( $_GET['order_direction'] ) ) : 'ASC'; 235 238 236 239 if ($orderBy === 'price') { … … 289 292 } 290 293 } 294 // phpcs:enable WordPress.Security.NonceVerification.Recommended 291 295 292 296 $query = new WP_Query($queryArgsMeta); -
property-drive/trunk/shortcodes/search-form-results.php
r3059897 r3447995 1 1 <?php 2 if ( ! defined( 'ABSPATH' ) ) { 3 exit; // Exit if accessed directly 4 } 5 2 6 /** 3 7 * Display property search results … … 32 36 * Check if this is a search 33 37 */ 38 // Read-only GET params from search form; used only to filter/order display — nonce not required. 39 // phpcs:disable WordPress.Security.NonceVerification.Recommended 34 40 if (isset($_GET['property_type']) || isset($_GET['property_status']) || isset($_GET['group_type']) || isset($_GET['location']) || isset($_GET['property_keyword'])) { 35 41 $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; … … 38 44 39 45 // Build search query arguments 40 if (isset($_GET['group_type']) && (string) sanitize_text_field( $_GET['group_type']) !== '') {41 if (sanitize_text_field( $_GET['group_type']) === 'pm_commercial') {46 if (isset($_GET['group_type']) && (string) sanitize_text_field( wp_unslash( $_GET['group_type'] ) ) !== '') { 47 if (sanitize_text_field( wp_unslash( $_GET['group_type'] ) ) === 'pm_commercial') { 42 48 $tax_query[] = [[ 43 49 'taxonomy' => 'property_type', … … 56 62 ] 57 63 ]]; 58 } else if ((string) sanitize_text_field( $_GET['group_type']) === 'pm_residential') {64 } else if ((string) sanitize_text_field( wp_unslash( $_GET['group_type'] ) ) === 'pm_residential') { 59 65 $tax_query[] = [[ 60 66 'taxonomy' => 'property_type', … … 68 74 ] 69 75 ]]; 70 } else if ((string) sanitize_text_field( $_GET['group_type']) === 'pm_land') {76 } else if ((string) sanitize_text_field( wp_unslash( $_GET['group_type'] ) ) === 'pm_land') { 71 77 $tax_query[] = [[ 72 78 'taxonomy' => 'property_type', … … 84 90 } 85 91 86 if (isset($_GET['property_type']) && (string) sanitize_text_field( $_GET['property_type']) !== '') {92 if (isset($_GET['property_type']) && (string) sanitize_text_field( wp_unslash( $_GET['property_type'] ) ) !== '') { 87 93 $tax_query[] = [[ 88 94 'taxonomy' => 'property_type', 89 95 'field' => 'slug', 90 'terms' => sanitize_text_field( $_GET['property_type'])96 'terms' => sanitize_text_field( wp_unslash( $_GET['property_type'] ) ) 91 97 ]]; 92 98 } 93 99 94 if (isset($_GET['property_status']) && sanitize_text_field( $_GET['property_status']) !== '') {95 $propertyStatusArray = array_map('trim', explode(',', sanitize_text_field( $_GET['property_status'])));100 if (isset($_GET['property_status']) && sanitize_text_field( wp_unslash( $_GET['property_status'] ) ) !== '') { 101 $propertyStatusArray = array_map('trim', explode(',', sanitize_text_field( wp_unslash( $_GET['property_status'] ) ))); 96 102 $propertyStatusArray = array_filter($propertyStatusArray); 97 103 … … 104 110 105 111 if (isset($_GET['location'])) { 106 $locationAreas = sanitize_text_field( $_GET['location']);112 $locationAreas = sanitize_text_field( wp_unslash( $_GET['location'] ) ); 107 113 108 114 $meta_query[] = [ … … 113 119 } 114 120 if (isset($_GET['t'])) { 115 $multiType = sanitize_text_field($_GET['t']); 121 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Unslashed here, then sanitized via array_map(sanitize_text_field) below. 122 $t_raw = isset( $_GET['t'] ) ? wp_unslash( $_GET['t'] ) : []; 123 $t_raw = is_array( $t_raw ) ? $t_raw : [ $t_raw ]; 124 $multiType = array_map( 'sanitize_text_field', $t_raw ); 116 125 $propertyType = $propertyLivingType = []; 117 126 … … 140 149 141 150 if (isset($_GET['location_area'])) { 142 $locationAreas = sanitize_text_field( $_GET['location_area']);151 $locationAreas = sanitize_text_field( wp_unslash( $_GET['location_area'] ) ); 143 152 144 153 $meta_query[] = [ … … 151 160 $locationCounty = 0; 152 161 153 if (isset($_GET['location_county']) && sanitize_text_field( $_GET['location_county']) !== '') {162 if (isset($_GET['location_county']) && sanitize_text_field( wp_unslash( $_GET['location_county'] ) ) !== '') { 154 163 $locationArray = [ 155 164 1 => 'Dublin', … … 181 190 ]; 182 191 183 $locationId = absint($_GET['location_county']);192 $locationId = isset( $_GET['location_county'] ) ? absint( $_GET['location_county'] ) : 0; 184 193 $locationCounty = (string) $locationArray[$locationId]; 185 194 … … 195 204 'key' => 'bedrooms', 196 205 'type' => 'NUMERIC', 197 'value' => (int) $_GET['beds'],206 'value' => absint( $_GET['beds'] ), 198 207 'compare' => '>=' 199 208 ]; 200 209 } 201 210 if (isset($_GET['min_price']) || isset($_GET['max_price'])) { 202 $minPrice = isset($_GET['min_price']) ? (int) $_GET['min_price']: 0;203 $maxPrice = isset($_GET['max_price']) ? (int) $_GET['max_price']: 10000000;211 $minPrice = isset($_GET['min_price']) ? absint( $_GET['min_price'] ) : 0; 212 $maxPrice = isset($_GET['max_price']) ? absint( $_GET['max_price'] ) : 10000000; 204 213 205 214 $meta_query[] = [ … … 213 222 $order_direction = 'ASC'; 214 223 if (isset($_GET['order_direction']) ) { 215 if ($_GET['order_direction'] == 'ASC') { 224 $order_direction_input = sanitize_text_field( wp_unslash( $_GET['order_direction'] ) ); 225 if ($order_direction_input === 'ASC') { 216 226 $order_direction = 'ASC'; 217 227 } else { … … 220 230 } 221 231 222 if (isset($_GET['orderby']) && (string) $_GET['orderby']=== 'date') {232 if (isset($_GET['orderby']) && (string) sanitize_text_field( wp_unslash( $_GET['orderby'] ) ) === 'date') { 223 233 $args = [ 224 234 'paged' => $paged, … … 230 240 'meta_query' => $meta_query 231 241 ]; 232 } else if ( !$_GET) {242 } else if (empty($_GET)) { 233 243 $args = [ 234 244 'paged' => $paged, … … 260 270 261 271 if (isset($_GET['orderby'])) { 262 $orderBy = (string) sanitize_text_field( $_GET['orderby']);272 $orderBy = (string) sanitize_text_field( wp_unslash( $_GET['orderby'] ) ); 263 273 if ($orderBy === 'price') { 264 274 $args['orderby'] = 'meta_value'; … … 273 283 } 274 284 275 if (isset($_GET['property_keyword']) && sanitize_text_field( $_GET['property_keyword']) !== '') {276 $args['s'] = sanitize_text_field( $_GET['property_keyword']);285 if (isset($_GET['property_keyword']) && sanitize_text_field( wp_unslash( $_GET['property_keyword'] ) ) !== '') { 286 $args['s'] = sanitize_text_field( wp_unslash( $_GET['property_keyword'] ) ); 277 287 } 278 288 } else { 279 289 280 290 } 291 // phpcs:enable WordPress.Security.NonceVerification.Recommended 281 292 282 293 $query = new WP_Query($args); -
property-drive/trunk/shortcodes/search-form.php
r2354697 r3447995 1 1 <?php 2 if ( ! defined( 'ABSPATH' ) ) { 3 exit; // Exit if accessed directly 4 } 5 2 6 function wp4pm_get_pd_user_ip() { 7 $ipAddress = ''; 3 8 if (!empty($_SERVER['HTTP_CLIENT_IP'])) { 4 $ipAddress = $_SERVER['HTTP_CLIENT_IP'];9 $ipAddress = sanitize_text_field( wp_unslash( $_SERVER['HTTP_CLIENT_IP'] ) ); 5 10 } else if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { 6 $ipAddress = $_SERVER['HTTP_X_FORWARDED_FOR'];7 } else {8 $ipAddress = $_SERVER['REMOTE_ADDR'];11 $ipAddress = sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ); 12 } else if (!empty($_SERVER['REMOTE_ADDR'])) { 13 $ipAddress = sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ); 9 14 } 10 15 … … 31 36 } 32 37 33 function jtg_search_type_4_shortcode($atts) { 38 function wppd_search_type_4_shortcode($atts) { 39 // Add nonce field to the form 40 $nonce = wp_create_nonce('property_search_nonce'); 41 34 42 $resultsPage = get_permalink((int) get_option('search_results_page')); 35 43 if (!get_option('search_results_page')) { … … 53 61 $jtg_table_name = $wpdb->prefix . 'postmeta'; 54 62 55 $termsType = get_terms('property_type', 'hide_empty=1'); 63 // Sanitize and validate input parameters 64 $termsType = get_terms(['taxonomy' => 'property_type', 'hide_empty' => false]); 56 65 $termsStatus = wp4pm_get_meta_values('property_status'); 57 $counties = $wpdb->get_results("SELECT DISTINCT meta_value from $jtg_table_name where meta_key='county' ORDER BY meta_value ASC");58 $ max_price_in_db = $wpdb->get_results("SELECT max(cast(meta_value as unsigned)) as meta_value FROM $jtg_table_name WHERE meta_key='price'");59 60 / **61 * Get search form builder options 62 */63 $searchFieldGroup = (int) get_option('search_field_group');64 $searchFieldType = (int) get_option('search_field_type');65 $searchFieldStatus = (int) get_option('search_field_status');66 $searchFieldStatusGroup = (int) get_option('search_field_status_group');67 $searchFieldPrice = (int) get_option('search_field_price');68 $searchFieldBeds = (int) get_option('search_field_beds');69 $searchFieldBaths = (int) get_option('search_field_baths');70 $searchFieldKeyword = (int) get_option('search_field_keyword');71 72 $searchField Location = (int) get_option('search_field_location');73 $searchField MultiType = (int) get_option('search_field_multitype');74 75 $searchFieldFeatures = (int) get_option('search_field_features');76 66 // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Distinct counties and max price for search form options; prepared, read-only. 67 $counties = $wpdb->get_results($wpdb->prepare("SELECT DISTINCT meta_value FROM {$wpdb->prefix}postmeta WHERE meta_key = %s ORDER BY meta_value ASC", 'county')); 68 $max_price_in_db = $wpdb->get_results($wpdb->prepare("SELECT max(cast(meta_value as unsigned)) as meta_value FROM {$wpdb->prefix}postmeta WHERE meta_key = %s", 'price')); 69 // phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching 70 71 // Sanitize search field options 72 $searchFieldGroup = absint(get_option('search_field_group')); 73 $searchFieldType = absint(get_option('search_field_type')); 74 $searchFieldStatus = absint(get_option('search_field_status')); 75 $searchFieldStatusGroup = absint(get_option('search_field_status_group')); 76 $searchFieldPrice = absint(get_option('search_field_price')); 77 $searchFieldBeds = absint(get_option('search_field_beds')); 78 $searchFieldBaths = absint(get_option('search_field_baths')); 79 $searchFieldKeyword = absint(get_option('search_field_keyword')); 80 $searchFieldLocation = absint(get_option('search_field_location')); 81 $searchFieldMultiType = absint(get_option('search_field_multitype')); 82 $searchFieldFeatures = absint(get_option('search_field_features')); 83 84 // Read-only GET params to pre-fill form defaults (e.g. from search results URL); no state change — nonce not required. 85 // phpcs:disable WordPress.Security.NonceVerification.Recommended 77 86 if ($searchFieldGroup === 1 && (string) $show_type !== 'no') { 78 $checkedGroupType = (isset($_GET['group_type'])) ? sanitize_text_field( $_GET['group_type']) : 'pm_residential';87 $checkedGroupType = (isset($_GET['group_type'])) ? sanitize_text_field( wp_unslash( $_GET['group_type'] ) ) : 'pm_residential'; 79 88 80 89 if ((string) $default_type !== '') { … … 85 94 <div class="property-group-switch"> 86 95 <input type="radio" id="pm_residential" name="group_type" value="pm_residential" ' . checked($checkedGroupType, 'pm_residential', false) . '> 87 <label for="pm_residential"> Residential</label>96 <label for="pm_residential">' . esc_html__('Residential', 'property-drive') . '</label> 88 97 89 98 <input type="radio" id="pm_commercial" name="group_type" value="pm_commercial" ' . checked($checkedGroupType, 'pm_commercial', false) . '> 90 <label for="pm_commercial"> Commercial</label>';99 <label for="pm_commercial">' . esc_html__('Commercial', 'property-drive') . '</label>'; 91 100 92 101 if ((string) $land === 'yes') { 93 102 $show .= '<input type="radio" id="pm_land" name="group_type" value="pm_land" ' . checked($checkedGroupType, 'pm_land', false) . '> 94 <label for="pm_land"> Land</label>';103 <label for="pm_land">' . esc_html__('Land', 'property-drive') . '</label>'; 95 104 } 96 105 $show .= '</div> … … 101 110 102 111 if ($searchFieldStatusGroup === 1) { 103 $checkedStatusGroupType = (isset($_GET['property_status'])) ? sanitize_text_field( $_GET['property_status']) : 'For Sale';112 $checkedStatusGroupType = (isset($_GET['property_status'])) ? sanitize_text_field( wp_unslash( $_GET['property_status'] ) ) : 'For Sale'; 104 113 105 114 if ((string) $default_status !== '') { … … 124 133 } 125 134 if ($searchFieldType === 1) { 126 $searchString['type'] = '<select name="property_type" id="property_type_select" class="wp4pm-flex-item advanced-search-trigger" aria-label=" Property Type">127 <option value=""> Any Property Type</option>';135 $searchString['type'] = '<select name="property_type" id="property_type_select" class="wp4pm-flex-item advanced-search-trigger" aria-label="' . esc_attr__('Property Type', 'property-drive') . '"> 136 <option value="">' . esc_html__('Any Property Type', 'property-drive') . '</option>'; 128 137 129 138 foreach ($termsType as $row) { 130 $searchString['type'] .= '<option value="' . $row->slug .'">' . $row->name. '</option>';139 $searchString['type'] .= '<option value="' . esc_attr($row->slug) . '">' . esc_html($row->name) . '</option>'; 131 140 } 132 141 … … 134 143 } 135 144 if ($searchFieldFeatures === 1) { 136 $searchString['features'] = '<select name="f[]" id="property_features_select" class="wp4pm-flex-item" aria-label="Property Features" size="1" multiple>'; 137 138 //foreach ($termsType as $row) { 139 //$searchString['features'] .= '<option value="'. $row->slug .'">' . $row->name . '</option>'; 140 $searchString['features'] .= '<option value="">Swimming Pool</option>'; 141 $searchString['features'] .= '<option value="">Garage</option>'; 142 $searchString['features'] .= '<option value="">Garden</option>'; 143 //} 145 $searchString['features'] = '<select name="f[]" id="property_features_select" class="wp4pm-flex-item" aria-label="' . esc_attr__('Property Features', 'property-drive') . '" size="1" multiple>'; 146 147 $searchString['features'] .= '<option value="">' . esc_html__('Swimming Pool', 'property-drive') . '</option>'; 148 $searchString['features'] .= '<option value="">' . esc_html__('Garage', 'property-drive') . '</option>'; 149 $searchString['features'] .= '<option value="">' . esc_html__('Garden', 'property-drive') . '</option>'; 144 150 145 151 $searchString['features'] .= '</select>'; … … 148 154 $keywordPlaceholder = trim($keyword_placeholder); 149 155 150 $value = isset($_GET['property_keyword']) ? urldecode($_GET['property_keyword']) : ''; 151 $searchString['keyword'] = '<input type="text" id="keyword" name="property_keyword" placeholder="' . $keywordPlaceholder . '" class="wp4pm-flex-item" value="' . $value . '" aria-label="Keyword">'; 156 $keyword_raw = isset( $_GET['property_keyword'] ) ? sanitize_text_field( wp_unslash( $_GET['property_keyword'] ) ) : ''; 157 $value = ! empty( $keyword_raw ) ? sanitize_text_field( urldecode( $keyword_raw ) ) : ''; 158 $searchString['keyword'] = '<input type="text" id="keyword" name="property_keyword" placeholder="' . esc_attr($keywordPlaceholder) . '" class="wp4pm-flex-item" value="' . esc_attr($value) . '" aria-label="' . esc_attr__('Keyword', 'property-drive') . '">'; 152 159 } 153 160 if ($searchFieldPrice === 1) { 154 161 $searchString['price'] = '<div class="wp4pm-flex-item flex-container-nowrap"> 155 <select name="min_price" id="min_price" aria-label=" Minimum Price">156 <option value="" selected disabled> Min Price</option>162 <select name="min_price" id="min_price" aria-label="' . esc_attr__('Minimum Price', 'property-drive') . '"> 163 <option value="" selected disabled>' . esc_html__('Min Price', 'property-drive') . '</option> 157 164 <option value="10000">10,000</option> 158 165 <option value="20000">20,000</option> … … 165 172 <option value="500000">500,000</option> 166 173 </select> 167 <select name="max_price" id="max_price" aria-label=" Maximum Price">168 <option value="" selected disabled> Max Price</option>174 <select name="max_price" id="max_price" aria-label="' . esc_attr__('Maximum Price', 'property-drive') . '"> 175 <option value="" selected disabled>' . esc_html__('Max Price', 'property-drive') . '</option> 169 176 <option value="10000">10,000</option> 170 177 <option value="20000">20,000</option> … … 186 193 } 187 194 if ($searchFieldStatus === 1) { 188 $searchString['status'] = '<select id="property_status" name="property_status" class="wp4pm-flex-item" aria-label=" Property Status">189 <option value="" selected> Any Property Status</option>';195 $searchString['status'] = '<select id="property_status" name="property_status" class="wp4pm-flex-item" aria-label="' . esc_attr__('Property Status', 'property-drive') . '"> 196 <option value="" selected>' . esc_html__('Any Property Status', 'property-drive') . '</option>'; 190 197 191 198 foreach ($termsStatus as $row) { 192 $searchString['status'] .= '<option>' . $row. '</option>';199 $searchString['status'] .= '<option>' . esc_html($row) . '</option>'; 193 200 } 194 201 $searchString['status'] .= '</select>'; 195 202 } 196 203 if ($searchFieldBeds === 1) { 197 $searchString['beds'] = '<select id="bedrooms" name="beds" class="wp4pm-flex-item" aria-label=" Bedrooms">198 <option value="" disabled selected> Select Bedrooms</option>204 $searchString['beds'] = '<select id="bedrooms" name="beds" class="wp4pm-flex-item" aria-label="' . esc_attr__('Bedrooms', 'property-drive') . '"> 205 <option value="" disabled selected>' . esc_html__('Select Bedrooms', 'property-drive') . '</option> 199 206 <option value="1">1+</option> 200 207 <option value="2">2+</option> … … 208 215 } 209 216 if ($searchFieldBaths === 1) { 210 $searchString['baths'] = '<select id="bathrooms" name="baths" class="wp4pm-flex-item" aria-label=" Bathrooms">211 <option value="" disabled selected> Select Bathrooms</option>217 $searchString['baths'] = '<select id="bathrooms" name="baths" class="wp4pm-flex-item" aria-label="' . esc_attr__('Bathrooms', 'property-drive') . '"> 218 <option value="" disabled selected>' . esc_html__('Select Bathrooms', 'property-drive') . '</option> 212 219 <option value="1">1+</option> 213 220 <option value="2">2+</option> … … 338 345 $searchString['multitype'] = $string; 339 346 } 347 // phpcs:enable WordPress.Security.NonceVerification.Recommended 340 348 341 349 /** 342 350 * Build search form 343 351 */ 344 $out = '<form id="wp4pm-search" class="wp4pm-' . $layout . '" method="get" action="' . $results . '"> 345 <input type="hidden" id="wp4pm-ip-address" value="' . wp4pm_get_pd_user_ip() . '"> 352 $out = '<form id="wp4pm-search" class="wp4pm-' . esc_attr($layout) . '" method="get" action="' . esc_url($results) . '"> 353 <input type="hidden" id="wp4pm-ip-address" value="' . esc_attr(wp4pm_get_pd_user_ip()) . '"> 354 <input type="hidden" name="_wpnonce" value="' . esc_attr($nonce) . '"> 346 355 <div class="wp4pm-search-progress-wrap"> 347 356 <div class="wp4pm-search-progress"></div> … … 349 358 <div class="wp4pm wp4pm-flex">'; 350 359 351 $searchFieldArray = explode('|', (string) get_option('search_field_array'));360 $searchFieldArray = array_map('sanitize_text_field', explode('|', (string) get_option('search_field_array'))); 352 361 foreach ($searchFieldArray as $searchFieldItem) { 353 362 if (isset($searchString[$searchFieldItem])) { … … 356 365 } 357 366 358 $out .= '<button type="submit" class="wp4pm-flex-item wp4pm-btn-primary"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="search" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-search fa-w-16 fa-fw"><path fill="currentColor" d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z" class=""></path></svg> Search</button>367 $out .= '<button type="submit" class="wp4pm-flex-item wp4pm-btn-primary"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="search" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-search fa-w-16 fa-fw"><path fill="currentColor" d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z" class=""></path></svg> ' . esc_html__('Search', 'property-drive') . '</button> 359 368 </div> 360 369 <div id="wp4pm-status"></div> … … 363 372 return $out; 364 373 } 365 add_shortcode('jtg_search_type_4', ' jtg_search_type_4_shortcode');366 add_shortcode('search_form', ' jtg_search_type_4_shortcode');367 add_shortcode('property-search', ' jtg_search_type_4_shortcode');374 add_shortcode('jtg_search_type_4', 'wppd_search_type_4_shortcode'); 375 add_shortcode('search_form', 'wppd_search_type_4_shortcode'); 376 add_shortcode('property-search', 'wppd_search_type_4_shortcode'); -
property-drive/trunk/templates/part-sidebar-classic.php
r3059897 r3447995 1 1 <?php 2 if ( ! defined( 'ABSPATH' ) ) { 3 exit; // Exit if accessed directly 4 } 5 2 6 function wp4pm_get_sidebar_classic($propertyId, $propertyDetails) { 3 7 $agentEmailAddress = get_option('agency_email'); … … 35 39 $out .= '<div class="sidebar-section sidebar-sharing"> 36 40 <div id="share-buttons">'; 37 $out .= get_sharing_buttons($propertyId);41 $out .= wppd_get_sharing_buttons($propertyId); 38 42 $out .= '</div> 39 43 </div>'; -
property-drive/trunk/templates/single-property.php
r3209948 r3447995 1 1 <?php 2 if ( ! defined( 'ABSPATH' ) ) { 3 exit; // Exit if accessed directly 4 } 5 2 6 get_header(); 3 7 … … 6 10 while ( have_posts() ) { 7 11 the_post(); 8 $property_id = (int) get_the_ID(); 9 10 wp4pm_update_property_attachments( $property_id ); ?> 11 12 <article id="pd-property-<?php echo esc_attr( $property_id ); ?>" <?php post_class( 'pid-' . esc_attr( $property_id ) ); ?> data-pid="<?php echo esc_attr( $property_id ); ?>"> 12 13 $wppd_property_id = (int) get_the_ID(); 14 15 wp4pm_update_property_attachments( $wppd_property_id ); ?> 16 17 <article id="pd-property-<?php echo esc_attr( $wppd_property_id ); ?>" <?php post_class( 'pid-' . esc_attr( $wppd_property_id ) ); ?> data-pid="<?php echo esc_attr( $wppd_property_id ); ?>"> 13 18 <?php 14 $ image_array = get_post_meta( $property_id, 'detail_images_array', true );15 $ image_array = array_map( 'trim', explode( ',', $image_array ) );16 $ image_array = array_filter( $image_array );17 18 if ( count( $ image_array ) > 0 ) {19 $ cinematic_image_uri = preg_replace( '#&h=.*&#', '&h=1440&', $image_array[0] );20 $ cinematic_image_uri = preg_replace( '#&w=.*&#', '&w=1920&', $cinematic_image_uri );19 $wppd_image_array = get_post_meta( $wppd_property_id, 'detail_images_array', true ); 20 $wppd_image_array = array_map( 'trim', explode( ',', $wppd_image_array ) ); 21 $wppd_image_array = array_filter( $wppd_image_array ); 22 23 if ( count( $wppd_image_array ) > 0 ) { 24 $wppd_cinematic_image_uri = preg_replace( '#&h=.*&#', '&h=1440&', $wppd_image_array[0] ); 25 $wppd_cinematic_image_uri = preg_replace( '#&w=.*&#', '&w=1920&', $wppd_cinematic_image_uri ); 21 26 } else { 22 $ cinematic_image_uri = get_the_post_thumbnail_url( $property_id );27 $wppd_cinematic_image_uri = get_the_post_thumbnail_url( $wppd_property_id ); 23 28 } 24 29 25 $property_details = get_post_meta( $property_id ); 26 $property_type = get_the_terms( $property_id, 'property_type' ); 27 $property_status = get_post_meta( $property_id, 'property_status', true ); 28 29 $property_area = get_the_terms( $property_id, 'property_area' ); 30 $property_area = ( $property_area ) ? $property_area[0]->name : ''; 31 32 if ( (int) get_option( 'inactive_not_clickable' ) === 1 && ( sanitize_title( $property_status ) === 'sold' || sanitize_title( $property_status ) === 'has-been-let' ) ) { 30 $wppd_property_details = get_post_meta( $wppd_property_id ); 31 $wppd_property_type = get_the_terms( $wppd_property_id, 'property_type' ); 32 $wppd_property_status = get_post_meta( $wppd_property_id, 'property_status', true ); 33 34 $wppd_property_area = get_the_terms( $wppd_property_id, 'property_area' ); 35 $wppd_property_area = ( $wppd_property_area ) ? $wppd_property_area[0]->name : ''; 36 37 // Validate property status 38 $wppd_property_status = sanitize_text_field( $wppd_property_status ); 39 $wppd_is_inactive = (int) get_option( 'inactive_not_clickable' ) === 1 && 40 (sanitize_title( $wppd_property_status ) === 'sold' || sanitize_title( $wppd_property_status ) === 'has-been-let'); 41 42 if ( $wppd_is_inactive ) { 33 43 echo '<div class="grid-wrap grid-single-property grid-single-property--not-available" itemscope itemtype="http://schema.org/Place"> 34 <h2> Property not available.</h2>44 <h2>' . esc_html__( 'Property not available.', 'property-drive' ) . '</h2> 35 45 </div>'; 36 46 … … 38 48 } 39 49 40 // Build the Favourite action string41 $favourite_string = '';42 if ( (int) get_option( 'allow_favourites' ) === 1 ) {43 $favourite_string = '<span class="pd-box-favourite" data-property-id="' . $property_id . '" tooltip="Save property" flow="right"></span>';44 }45 46 50 // Build the title string 47 $ property_title_string = get_the_title() . $favourite_string;51 $wppd_property_title = get_the_title(); 48 52 49 53 // Generate priceValidUntil 50 $ date = new DateTime( $post->post_date );51 $ date->modify( '+90 day' );52 $ price_valid_until = $date->format( 'Y-m-d' );54 $wppd_date = new DateTime( $post->post_date ); 55 $wppd_date->modify( '+90 day' ); 56 $wppd_price_valid_until = $wppd_date->format( 'Y-m-d' ); 53 57 ?> 54 <div id="single-hero-image" data-src="<?php echo esc_url( $ cinematic_image_uri ); ?>"></div>58 <div id="single-hero-image" data-src="<?php echo esc_url( $wppd_cinematic_image_uri ); ?>"></div> 55 59 56 60 <script type="application/ld+json"> … … 61 65 "@type": "PostalAddress", 62 66 "@context": "http://schema.org", 63 "streetAddress": "<?php echo esc_html( get_the_title() ); ?>",64 "addressLocality": "<?php echo esc_html( $property_area ); ?>",65 "addressRegion": "<?php echo esc_html( $property_area ); ?>"67 "streetAddress": <?php echo wp_json_encode(get_the_title()); ?>, 68 "addressLocality": <?php echo wp_json_encode($wppd_property_area); ?>, 69 "addressRegion": <?php echo wp_json_encode($wppd_property_area); ?> 66 70 }, 67 71 "geo": { 68 72 "@type": "GeoCoordinates", 69 73 "@context": "http://schema.org", 70 "latitude": <?php echo floatval( $property_details['latitude'][0]); ?>,71 "longitude": <?php echo floatval( $property_details['longitude'][0]); ?>74 "latitude": <?php echo floatval($wppd_property_details['latitude'][0] ?? 0); ?>, 75 "longitude": <?php echo floatval($wppd_property_details['longitude'][0] ?? 0); ?> 72 76 }, 73 "url": "<?php echo esc_url( get_permalink() ); ?>"77 "url": <?php echo wp_json_encode(get_permalink()); ?> 74 78 } 75 79 </script> … … 78 82 "@context": "http://schema.org", 79 83 "@type": "Product", 80 "name": "<?php echo esc_html( get_the_title() ); ?>",81 "image": "<?php echo esc_url( $cinematic_image_uri ); ?>",84 "name": <?php echo wp_json_encode(get_the_title()); ?>, 85 "image": <?php echo wp_json_encode($wppd_cinematic_image_uri); ?>, 82 86 "offers": { 83 87 "@type": "Offer", 84 88 "priceCurrency": "EUR", 85 89 <?php 86 if ( (int) $property_details['price'][0] !== '' && (int) $property_details['price'][0] > 0) {87 echo '"price": "' . floatval( $property_details['price'][0]) . '",' . "\n";90 if (isset($wppd_property_details['price'][0]) && (int) $wppd_property_details['price'][0] !== '' && (int) $wppd_property_details['price'][0] > 0) { 91 echo '"price": "' . floatval($wppd_property_details['price'][0]) . '",' . "\n"; 88 92 } 89 93 ?> 90 "validFrom": "<?php echo get_the_date( 'Y-m-d' ); ?>",91 "priceValidUntil": "<?php echo esc_html( $price_valid_until ); ?>",94 "validFrom": <?php echo wp_json_encode(get_the_date('Y-m-d')); ?>, 95 "priceValidUntil": <?php echo wp_json_encode($wppd_price_valid_until); ?>, 92 96 "availability": "http://schema.org/InStock", 93 "url": "<?php echo esc_url( get_permalink() ); ?>",97 "url": <?php echo wp_json_encode(get_permalink()); ?>, 94 98 "seller": { 95 99 "@type": "Organization", 96 "name": " 97 <?php 98 $wp_seo_titles = get_option( 'wpseo_titles' ); 99 echo esc_html( $wp_seo_titles['company_name'] ); 100 ?> 101 " 100 "name": <?php echo wp_json_encode($wp_seo_titles['company_name'] ?? ''); ?> 102 101 } 103 102 }, 104 "description": "<?php echo esc_html( wp_strip_tags( get_the_excerpt() ) ); ?>"103 "description": <?php echo wp_json_encode(wp_strip_tags(get_the_excerpt())); ?> 105 104 } 106 105 </script> 107 106 108 <div id="single-property-container" data-property-id="<?php echo esc_attr( $ property_id ); ?>"></div>107 <div id="single-property-container" data-property-id="<?php echo esc_attr( $wppd_property_id ); ?>"></div> 109 108 110 109 <div class="grid-wrap grid-single-property" itemscope itemtype="http://schema.org/Place"> 111 110 <div class="print-view"> 112 <p><img src="<?php echo esc_url( wppd_get_thumbnail_url( $ property_id ) ); ?>" alt="">113 <h2 class="single-property-title"><?php echo wp_kses_post( $ property_title_string); ?></h2>111 <p><img src="<?php echo esc_url( wppd_get_thumbnail_url( $wppd_property_id ) ); ?>" alt="<?php echo esc_attr__( 'Property Image', 'property-drive' ); ?>"> 112 <h2 class="single-property-title"><?php echo wp_kses_post( $wppd_property_title ); ?></h2> 114 113 </div> 115 114 <?php 116 115 // Get property template 117 $ property_template = (int) get_option( 'cinematic_overlay' );118 if ( get_post_meta( $ property_id, '_property_template', true ) !== '' && (int) get_post_meta( $property_id, '_property_template', true ) !== 999 ) {119 $ property_template = (int) $property_details['_property_template'][0];120 $ property_template = ( $property_template !== 'none' ) ? (int) $property_template : (int) get_option( 'cinematic_overlay' );116 $wppd_property_template = (int) get_option( 'cinematic_overlay' ); 117 if ( get_post_meta( $wppd_property_id, '_property_template', true ) !== '' && (int) get_post_meta( $wppd_property_id, '_property_template', true ) !== 999 ) { 118 $wppd_property_template = (int) $wppd_property_details['_property_template'][0]; 119 $wppd_property_template = ( $wppd_property_template !== 'none' ) ? (int) $wppd_property_template : (int) get_option( 'cinematic_overlay' ); 121 120 } 122 121 123 $ agent_email_address = get_option( 'agency_email' );124 if ( $ property_details['agent_email'][0] ) {125 $ agent_email_address = $property_details['agent_email'][0];122 $wppd_agent_email_address = get_option( 'agency_email' ); 123 if ( $wppd_property_details['agent_email'][0] ) { 124 $wppd_agent_email_address = $wppd_property_details['agent_email'][0]; 126 125 } 127 126 128 if ( $ property_template === 2 ) {129 echo '<div class="supernova-fullwidth supernova-property-hero" style="background: url(' . esc_url( wppd_get_thumbnail_url( $ property_id ) ) . ') no-repeat center center; background-size: cover; margin-top: -128px;">130 <h1 class="single-property-title grid-wrap overlaid">' . wp_kses_post( $ property_title_string) . '</h1>127 if ( $wppd_property_template === 2 ) { 128 echo '<div class="supernova-fullwidth supernova-property-hero" style="background: url(' . esc_url( wppd_get_thumbnail_url( $wppd_property_id ) ) . ') no-repeat center center; background-size: cover; margin-top: -128px;"> 129 <h1 class="single-property-title grid-wrap overlaid">' . wp_kses_post( $wppd_property_title ) . '</h1> 131 130 </div> 132 131 <div class="pd-section-breakdown"> 133 132 <ul class="grid-wrap"> 134 <li><a href="#"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="arrow-up" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" class="svg-inline--fa fa-arrow-up fa-w-14 fa-fw"><path fill="currentColor" d="M34.9 289.5l-22.2-22.2c-9.4-9.4-9.4-24.6 0-33.9L207 39c9.4-9.4 24.6-9.4 33.9 0l194.3 194.3c9.4 9.4 9.4 24.6 0 33.9L413 289.4c-9.5 9.5-25 9.3-34.3-.4L264 168.6V456c0 13.3-10.7 24-24 24h-32c-13.3 0-24-10.7-24-24V168.6L69.2 289.1c-9.3 9.8-24.8 10-34.3.4z" class=""></path></svg> Top</a></li>135 <li><a href="#property-page-slider"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="images" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" class="svg-inline--fa fa-images fa-w-18 fa-fw"><path fill="currentColor" d="M480 416v16c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V176c0-26.51 21.49-48 48-48h16v208c0 44.112 35.888 80 80 80h336zm96-80V80c0-26.51-21.49-48-48-48H144c-26.51 0-48 21.49-48 48v256c0 26.51 21.49 48 48 48h384c26.51 0 48-21.49 48-48zM256 128c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-96 144l55.515-55.515c4.686-4.686 12.284-4.686 16.971 0L272 256l135.515-135.515c4.686-4.686 12.284-4.686 16.971 0L512 208v112H160v-48z" class=""></path></svg> Gallery</a></li>136 <li><a href="#pd-property-page-description"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="file-alt" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" class="svg-inline--fa fa-file-alt fa-w-12 fa-fw"><path fill="currentColor" d="M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm64 236c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12v8zm0-64c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12v8zm0-72v8c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12zm96-114.1v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z" class=""></path></svg> Description</a></li>137 <li><a href="#listing-map"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="map-marker-alt" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" class="svg-inline--fa fa-map-marker-alt fa-w-12 fa-fw"><path fill="currentColor" d="M172.268 501.67C26.97 291.031 0 269.413 0 192 0 85.961 85.961 0 192 0s192 85.961 192 192c0 77.413-26.97 99.031-172.268 309.67-9.535 13.774-29.93 13.773-39.464 0zM192 272c44.183 0 80-35.817 80-80s-35.817-80-80-80-80 35.817-80 80 35.817 80 80 80z" class=""></path></svg> Location</a></li>133 <li><a href="#"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="arrow-up" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" class="svg-inline--fa fa-arrow-up fa-w-14 fa-fw"><path fill="currentColor" d="M34.9 289.5l-22.2-22.2c-9.4-9.4-9.4-24.6 0-33.9L207 39c9.4-9.4 24.6-9.4 33.9 0l194.3 194.3c9.4 9.4 9.4 24.6 0 33.9L413 289.4c-9.5 9.5-25 9.3-34.3-.4L264 168.6V456c0 13.3-10.7 24-24 24h-32c-13.3 0-24-10.7-24-24V168.6L69.2 289.1c-9.3 9.8-24.8 10-34.3.4z" class=""></path></svg> ' . esc_html__( 'Top', 'property-drive' ) . '</a></li> 134 <li><a href="#property-page-slider"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="images" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" class="svg-inline--fa fa-images fa-w-18 fa-fw"><path fill="currentColor" d="M480 416v16c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48V176c0-26.51 21.49-48 48-48h16v208c0 44.112 35.888 80 80 80h336zm96-80V80c0-26.51-21.49-48-48-48H144c-26.51 0-48 21.49-48 48v256c0 26.51 21.49 48 48 48h384c26.51 0 48-21.49 48-48zM256 128c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-96 144l55.515-55.515c4.686-4.686 12.284-4.686 16.971 0L272 256l135.515-135.515c4.686-4.686 12.284-4.686 16.971 0L512 208v112H160v-48z" class=""></path></svg> ' . esc_html__( 'Gallery', 'property-drive' ) . '</a></li> 135 <li><a href="#pd-property-page-description"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="file-alt" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" class="svg-inline--fa fa-file-alt fa-w-12 fa-fw"><path fill="currentColor" d="M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm64 236c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12v8zm0-64c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12v8zm0-72v8c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12zm96-114.1v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z" class=""></path></svg> ' . esc_html__( 'Description', 'property-drive' ) . '</a></li> 136 <li><a href="#listing-map"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="map-marker-alt" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" class="svg-inline--fa fa-map-marker-alt fa-w-12 fa-fw"><path fill="currentColor" d="M172.268 501.67C26.97 291.031 0 269.413 0 192 0 85.961 85.961 0 192 0s192 85.961 192 192c0 77.413-26.97 99.031-172.268 309.67-9.535 13.774-29.93 13.773-39.464 0zM192 272c44.183 0 80-35.817 80-80s-35.817-80-80-80-80 35.817-80 80 35.817 80 80 80z" class=""></path></svg> ' . esc_html__( 'Location', 'property-drive' ) . '</a></li> 138 137 </ul> 139 138 </div>'; 140 } elseif ( $ property_template === 3 ) {139 } elseif ( $wppd_property_template === 3 ) { 141 140 /** 142 141 * Flickity (Sydney Gallery 143 142 */ 144 wp4pm_show_flickity_gallery( $ property_id );145 echo '<h1 class="single-property-title">' . wp_kses_post( $ property_title_string) . '</h1>';146 } elseif ( $ property_template === 4 ) {143 wp4pm_show_flickity_gallery( $wppd_property_id ); 144 echo '<h1 class="single-property-title">' . wp_kses_post( $wppd_property_title ) . '</h1>'; 145 } elseif ( $wppd_property_template === 4 ) { 147 146 /** 148 147 * Flickity (Parsley) Gallery 149 148 */ 150 wp4pm_show_flickity_parsley_gallery( $ property_id );151 echo '<h1 class="single-property-title">' . wp_kses_post( $ property_title_string) . '</h1>';152 } elseif ( $ property_template === 1 ) {153 echo '<h1 class="single-property-title">' . wp_kses_post( $ property_title_string) . '</h1>';149 wp4pm_show_flickity_parsley_gallery( $wppd_property_id ); 150 echo '<h1 class="single-property-title">' . wp_kses_post( $wppd_property_title ) . '</h1>'; 151 } elseif ( $wppd_property_template === 1 ) { 152 echo '<h1 class="single-property-title">' . wp_kses_post( $wppd_property_title ) . '</h1>'; 154 153 } else { 155 echo '<h1 class="single-property-title">' . wp_kses_post( $ property_title_string) . '</h1>';154 echo '<h1 class="single-property-title">' . wp_kses_post( $wppd_property_title ) . '</h1>'; 156 155 } 157 156 … … 169 168 <?php 170 169 // Only show price if property is not sold or sale agreed 171 if ( ! in_array( $ property_status, [ 'Sale Agreed', 'Sold', 'Let', 'Has Been Let' ] ) ) {170 if ( ! in_array( $wppd_property_status, [ 'Sale Agreed', 'Sold', 'Let', 'Has Been Let' ] ) ) { 172 171 ?> 173 172 <div class="grid-property-attribute grid-property-attribute-price flex-element"> 174 <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="euro-sign" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" class="svg-inline--fa fa-euro-sign fa-w-10 fa-fw"><path fill="currentColor" d="M310.706 413.765c-1.314-6.63-7.835-10.872-14.424-9.369-10.692 2.439-27.422 5.413-45.426 5.413-56.763 0-101.929-34.79-121.461-85.449h113.689a12 12 0 0 0 11.708-9.369l6.373-28.36c1.686-7.502-4.019-14.631-11.708-14.631H115.22c-1.21-14.328-1.414-28.287.137-42.245H261.95a12 12 0 0 0 11.723-9.434l6.512-29.755c1.638-7.484-4.061-14.566-11.723-14.566H130.184c20.633-44.991 62.69-75.03 117.619-75.03 14.486 0 28.564 2.25 37.851 4.145 6.216 1.268 12.347-2.498 14.002-8.623l11.991-44.368c1.822-6.741-2.465-13.616-9.326-14.917C290.217 34.912 270.71 32 249.635 32 152.451 32 74.03 92.252 45.075 176H12c-6.627 0-12 5.373-12 12v29.755c0 6.627 5.373 12 12 12h21.569c-1.009 13.607-1.181 29.287-.181 42.245H12c-6.627 0-12 5.373-12 12v28.36c0 6.627 5.373 12 12 12h30.114C67.139 414.692 145.264 480 249.635 480c26.301 0 48.562-4.544 61.101-7.788 6.167-1.595 10.027-7.708 8.788-13.957l-8.818-44.49z" class=""></path></svg><br><span>Price</span><br><em><?php echo esc_html( wp4pm_get_property_price( $ property_id ) ); ?></em>175 <?php echo esc_html( wp4pm_get_property_price_term( $ property_id ) ); ?>173 <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="euro-sign" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" class="svg-inline--fa fa-euro-sign fa-w-10 fa-fw"><path fill="currentColor" d="M310.706 413.765c-1.314-6.63-7.835-10.872-14.424-9.369-10.692 2.439-27.422 5.413-45.426 5.413-56.763 0-101.929-34.79-121.461-85.449h113.689a12 12 0 0 0 11.708-9.369l6.373-28.36c1.686-7.502-4.019-14.631-11.708-14.631H115.22c-1.21-14.328-1.414-28.287.137-42.245H261.95a12 12 0 0 0 11.723-9.434l6.512-29.755c1.638-7.484-4.061-14.566-11.723-14.566H130.184c20.633-44.991 62.69-75.03 117.619-75.03 14.486 0 28.564 2.25 37.851 4.145 6.216 1.268 12.347-2.498 14.002-8.623l11.991-44.368c1.822-6.741-2.465-13.616-9.326-14.917C290.217 34.912 270.71 32 249.635 32 152.451 32 74.03 92.252 45.075 176H12c-6.627 0-12 5.373-12 12v29.755c0 6.627 5.373 12 12 12h21.569c-1.009 13.607-1.181 29.287-.181 42.245H12c-6.627 0-12 5.373-12 12v28.36c0 6.627 5.373 12 12 12h30.114C67.139 414.692 145.264 480 249.635 480c26.301 0 48.562-4.544 61.101-7.788 6.167-1.595 10.027-7.708 8.788-13.957l-8.818-44.49z" class=""></path></svg><br><span>Price</span><br><em><?php echo esc_html( wp4pm_get_property_price( $wppd_property_id ) ); ?></em> 174 <?php echo esc_html( wp4pm_get_property_price_term( $wppd_property_id ) ); ?> 176 175 </div> 177 176 <?php } ?> 178 177 179 178 <div class="grid-property-attribute grid-property-attribute-name flex-element"> 180 <?php if ( $ property_type[0]->name === 'Parking Space' ) { ?>179 <?php if ( $wppd_property_type[0]->name === 'Parking Space' ) { ?> 181 180 <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="parking" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" class="svg-inline--fa fa-parking fa-w-14 fa-fw"><path fill="currentColor" d="M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM240 320h-48v48c0 8.8-7.2 16-16 16h-32c-8.8 0-16-7.2-16-16V144c0-8.8 7.2-16 16-16h96c52.9 0 96 43.1 96 96s-43.1 96-96 96zm0-128h-48v64h48c17.6 0 32-14.4 32-32s-14.4-32-32-32z" class=""></path></svg> 182 181 <?php } else { ?> … … 185 184 <br><span>Type</span> 186 185 187 <?php if ( $ property_type[0]->name === 'Parking Space' ) { ?>186 <?php if ( $wppd_property_type[0]->name === 'Parking Space' ) { ?> 188 187 <br><em>Parking Space</em> 189 <?php } elseif ( (string) $ property_details['property_market'][0] === 'New Developments' ) { ?>188 <?php } elseif ( (string) $wppd_property_details['property_market'][0] === 'New Developments' ) { ?> 190 189 <br><em>New Development</em> 191 190 <?php } else { ?> 192 191 <br><em> 193 192 <?php 194 if ( ! empty( wp4pm_get_property_living_type( $ property_id ) ) ) {195 echo esc_html( wp4pm_get_property_living_type( $ property_id ) ) . ' '; }193 if ( ! empty( wp4pm_get_property_living_type( $wppd_property_id ) ) ) { 194 echo esc_html( wp4pm_get_property_living_type( $wppd_property_id ) ) . ' '; } 196 195 ?> 197 <?php echo esc_html( $ property_type[0]->name ); ?></em>196 <?php echo esc_html( $wppd_property_type[0]->name ); ?></em> 198 197 <?php } ?> 199 198 </div> 200 199 201 <div class="grid-property-attribute grid-property-attribute-status grid-property-attribute-status-<?php echo esc_html( sanitize_title( $ property_status ) ); ?> flex-element">202 <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="th" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-th fa-w-16 fa-fw"><path fill="currentColor" d="M149.333 56v80c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24h101.333c13.255 0 24 10.745 24 24zm181.334 240v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.256 0 24.001-10.745 24.001-24zm32-240v80c0 13.255 10.745 24 24 24H488c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24zm-32 80V56c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.256 0 24.001-10.745 24.001-24zm-205.334 56H24c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24zM0 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H24c-13.255 0-24 10.745-24 24zm386.667-56H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24zm0 160H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24zM181.333 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24z" class=""></path></svg><br><span>Status</span><br><em><?php echo esc_html( $ property_status ); ?></em>200 <div class="grid-property-attribute grid-property-attribute-status grid-property-attribute-status-<?php echo esc_html( sanitize_title( $wppd_property_status ) ); ?> flex-element"> 201 <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="th" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-th fa-w-16 fa-fw"><path fill="currentColor" d="M149.333 56v80c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24h101.333c13.255 0 24 10.745 24 24zm181.334 240v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.256 0 24.001-10.745 24.001-24zm32-240v80c0 13.255 10.745 24 24 24H488c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24zm-32 80V56c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.256 0 24.001-10.745 24.001-24zm-205.334 56H24c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24zM0 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H24c-13.255 0-24 10.745-24 24zm386.667-56H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24zm0 160H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24zM181.333 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24z" class=""></path></svg><br><span>Status</span><br><em><?php echo esc_html( $wppd_property_status ); ?></em> 203 202 </div> 204 203 205 <?php if ( (int) wp4pm_get_property_bedrooms( $ property_id ) > 0 || ( (string) $property_details['property_market'][0] === 'New Developments' && (int) getLinkedPropertiesBedroomRange( $property_details['linked_properties'][0] ) > 0 ) ) { ?>204 <?php if ( (int) wp4pm_get_property_bedrooms( $wppd_property_id ) > 0 || ( (string) $wppd_property_details['property_market'][0] === 'New Developments' && (int) wppd_get_linked_properties_bedroom_range( $wppd_property_details['linked_properties'][0] ) > 0 ) ) { ?> 206 205 <div class="grid-property-attribute grid-property-attribute-bedrooms flex-element"> 207 <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="bed" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" class="svg-inline--fa fa-bed fa-w-20 fa-fw"><path fill="currentColor" d="M176 256c44.11 0 80-35.89 80-80s-35.89-80-80-80-80 35.89-80 80 35.89 80 80 80zm352-128H304c-8.84 0-16 7.16-16 16v144H64V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v352c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16v-48h512v48c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16V240c0-61.86-50.14-112-112-112z" class=""></path></svg><br><span>BEDROOMS</span><br><em><?php echo esc_html( wp4pm_get_property_bedrooms( $ property_id ) ); ?></em>208 </div> 209 <?php } ?> 210 211 <?php if ( (int) wp4pm_get_property_bathrooms( $ property_id ) > 0 ) { ?>206 <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="bed" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" class="svg-inline--fa fa-bed fa-w-20 fa-fw"><path fill="currentColor" d="M176 256c44.11 0 80-35.89 80-80s-35.89-80-80-80-80 35.89-80 80 35.89 80 80 80zm352-128H304c-8.84 0-16 7.16-16 16v144H64V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v352c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16v-48h512v48c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16V240c0-61.86-50.14-112-112-112z" class=""></path></svg><br><span>BEDROOMS</span><br><em><?php echo esc_html( wp4pm_get_property_bedrooms( $wppd_property_id ) ); ?></em> 207 </div> 208 <?php } ?> 209 210 <?php if ( (int) wp4pm_get_property_bathrooms( $wppd_property_id ) > 0 ) { ?> 212 211 <div class="grid-property-attribute grid-property-attribute-bathrooms flex-element"> 213 <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="bath" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-bath fa-w-16 fa-fw"><path fill="currentColor" d="M488 256H80V112c0-17.645 14.355-32 32-32 11.351 0 21.332 5.945 27.015 14.88-16.492 25.207-14.687 59.576 6.838 83.035-4.176 4.713-4.021 11.916.491 16.428l11.314 11.314c4.686 4.686 12.284 4.686 16.971 0l95.03-95.029c4.686-4.686 4.686-12.284 0-16.971l-11.314-11.314c-4.512-4.512-11.715-4.666-16.428-.491-17.949-16.469-42.294-21.429-64.178-15.365C163.281 45.667 139.212 32 112 32c-44.112 0-80 35.888-80 80v144h-8c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h8v32c0 28.43 12.362 53.969 32 71.547V456c0 13.255 10.745 24 24 24h16c13.255 0 24-10.745 24-24v-8h256v8c0 13.255 10.745 24 24 24h16c13.255 0 24-10.745 24-24v-32.453c19.638-17.578 32-43.117 32-71.547v-32h8c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24z" class=""></path></svg><br><span>BATHROOMS</span><br><em><?php echo esc_html( wp4pm_get_property_bathrooms( $ property_id ) ); ?></em>214 </div> 215 <?php } ?> 216 217 <?php if ( $ property_type[0]->name !== 'Parking Space' && (string) $property_details['property_market'][0] !== 'New Developments' ) { ?>212 <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="bath" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-bath fa-w-16 fa-fw"><path fill="currentColor" d="M488 256H80V112c0-17.645 14.355-32 32-32 11.351 0 21.332 5.945 27.015 14.88-16.492 25.207-14.687 59.576 6.838 83.035-4.176 4.713-4.021 11.916.491 16.428l11.314 11.314c4.686 4.686 12.284 4.686 16.971 0l95.03-95.029c4.686-4.686 4.686-12.284 0-16.971l-11.314-11.314c-4.512-4.512-11.715-4.666-16.428-.491-17.949-16.469-42.294-21.429-64.178-15.365C163.281 45.667 139.212 32 112 32c-44.112 0-80 35.888-80 80v144h-8c-13.255 0-24 10.745-24 24v16c0 13.255 10.745 24 24 24h8v32c0 28.43 12.362 53.969 32 71.547V456c0 13.255 10.745 24 24 24h16c13.255 0 24-10.745 24-24v-8h256v8c0 13.255 10.745 24 24 24h16c13.255 0 24-10.745 24-24v-32.453c19.638-17.578 32-43.117 32-71.547v-32h8c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24z" class=""></path></svg><br><span>BATHROOMS</span><br><em><?php echo esc_html( wp4pm_get_property_bathrooms( $wppd_property_id ) ); ?></em> 213 </div> 214 <?php } ?> 215 216 <?php if ( $wppd_property_type[0]->name !== 'Parking Space' && (string) $wppd_property_details['property_market'][0] !== 'New Developments' ) { ?> 218 217 <div class="grid-property-attribute grid-property-attribute-ber flex-element"> 219 218 <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="thermometer-empty" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 512" class="svg-inline--fa fa-thermometer-empty fa-w-8 fa-fw"><path fill="currentColor" d="M192 384c0 35.346-28.654 64-64 64s-64-28.654-64-64c0-35.346 28.654-64 64-64s64 28.654 64 64zm32-84.653c19.912 22.563 32 52.194 32 84.653 0 70.696-57.303 128-128 128-.299 0-.609-.001-.909-.003C56.789 511.509-.357 453.636.002 383.333.166 351.135 12.225 321.755 32 299.347V96c0-53.019 42.981-96 96-96s96 42.981 96 96v203.347zM208 384c0-34.339-19.37-52.19-32-66.502V96c0-26.467-21.533-48-48-48S80 69.533 80 96v221.498c-12.732 14.428-31.825 32.1-31.999 66.08-.224 43.876 35.563 80.116 79.423 80.42L128 464c44.112 0 80-35.888 80-80z" class=""></path></svg><br><span>BER</span><br> 220 <?php echo wp_kses_post( wp4pm_get_property_ber( $ property_id ) ); ?>221 </div> 222 <?php } ?> 223 224 <?php if ( isset( $ property_details['brochure_1'] ) && $property_details['brochure_1'][0] != '' ) { ?>219 <?php echo wp_kses_post( wp4pm_get_property_ber( $wppd_property_id ) ); ?> 220 </div> 221 <?php } ?> 222 223 <?php if ( isset( $wppd_property_details['brochure_1'] ) && $wppd_property_details['brochure_1'][0] != '' ) { ?> 225 224 <div class="grid-property-attribute grid-property-attribute-brochure flex-element"> 226 <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="file-pdf" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" class="svg-inline--fa fa-file-pdf fa-w-12 fa-fw"><path fill="currentColor" d="M181.9 256.1c-5-16-4.9-46.9-2-46.9 8.4 0 7.6 36.9 2 46.9zm-1.7 47.2c-7.7 20.2-17.3 43.3-28.4 62.7 18.3-7 39-17.2 62.9-21.9-12.7-9.6-24.9-23.4- 34.5-40.8zM86.1 428.1c0 .8 13.2-5.4 34.9-40.2-6.7 6.3-29.1 24.5-34.9 40.2zM248 160h136v328c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V24C0 10.7 10.7 0 24 0h200v136c0 13.2 10.8 24 24 24zm-8 171.8c-20-12.2-33.3-29-42.7-53.8 4.5-18.5 11.6-46.6 6.2-64.2-4.7-29.4-42.4-26.5-47.8-6.8-5 18.3-.4 44.1 8.1 77-11.6 27.6-28.7 64.6-40.8 85.8-.1 0-.1.1-.2.1-27.1 13.9-73.6 44.5-54.5 68 5.6 6.9 16 10 21.5 10 17.9 0 35.7-18 61.1-61.8 25.8-8.5 54.1-19.1 79-23.2 21.7 11.8 47.1 19.5 64 19.5 29.2 0 31.2-32 19.7-43.4-13.9-13.6-54.3-9.7-73.6-7.2zM377 105L279 7c-4.5-4.5-10.6-7-17-7h-6v128h128v-6.1c0-6.3-2.5-12.4-7-16.9zm-74.1 255.3c4.1-2.7-2.5-11.9-42.8-9 37.1 15.8 42.8 9 42.8 9z" class=""></path></svg>225 <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="file-pdf" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" class="svg-inline--fa fa-file-pdf fa-w-12 fa-fw"><path fill="currentColor" d="M181.9 256.1c-5-16-4.9-46.9-2-46.9 8.4 0 7.6 36.9 2 46.9zm-1.7 47.2c-7.7 20.2-17.3 43.3-28.4 62.7 18.3-7 39-17.2 62.9-21.9-12.7-9.6-24.9-23.4-23.4-34.5-40.8zM86.1 428.1c0 .8 13.2-5.4 34.9-40.2-6.7 6.3-29.1 24.5-34.9 40.2zM248 160h136v328c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V24C0 10.7 10.7 0 24 0h200v136c0 13.2 10.8 24 24 24zm-8 171.8c-20-12.2-33.3-29-42.7-53.8 4.5-18.5 11.6-46.6 6.2-64.2-4.7-29.4-42.4-26.5-47.8-6.8-5 18.3-.4 44.1 8.1 77-11.6 27.6-28.7 64.6-40.8 85.8-.1 0-.1.1-.2.1-27.1 13.9-73.6 44.5-54.5 68 5.6 6.9 16 10 21.5 10 17.9 0 35.7-18 61.1-61.8 25.8-8.5 54.1-19.1 79-23.2 21.7 11.8 47.1 19.5 64 19.5 29.2 0 31.2-32 19.7-43.4-13.9-13.6-54.3-9.7-73.6-7.2zM377 105L279 7c-4.5-4.5-10.6-7-17-7h-6v128h128v-6.1c0-6.3-2.5-12.4-7-16.9zm-74.1 255.3c4.1-2.7-2.5-11.9-42.8-9 37.1 15.8 42.8 9 42.8 9z" class=""></path></svg> 227 226 <br><span>Brochure</span> 228 227 229 <?php if ( $ property_details['brochure_1'][0] != '' && $property_details['brochure_2'][0] == '' ) { ?>230 <br><a target="_blank" href="<?php echo esc_url( $ property_details['brochure_1'][0] ); ?>">View Now</a>228 <?php if ( $wppd_property_details['brochure_1'][0] != '' && $wppd_property_details['brochure_2'][0] == '' ) { ?> 229 <br><a target="_blank" href="<?php echo esc_url( $wppd_property_details['brochure_1'][0] ); ?>">View Now</a> 231 230 <?php } else { ?> 232 <br><a target="_blank" href="<?php echo esc_url( $ property_details['brochure_1'][0] ); ?>">1</a>233 <?php if ( isset( $ property_details['brochure_2'][0] ) && $property_details['brochure_2'][0] !== '' ) { ?>234 <a target="_blank" href="<?php echo esc_url( $ property_details['brochure_2'][0] ); ?>">2</a>231 <br><a target="_blank" href="<?php echo esc_url( $wppd_property_details['brochure_1'][0] ); ?>">1</a> 232 <?php if ( isset( $wppd_property_details['brochure_2'][0] ) && $wppd_property_details['brochure_2'][0] !== '' ) { ?> 233 <a target="_blank" href="<?php echo esc_url( $wppd_property_details['brochure_2'][0] ); ?>">2</a> 235 234 <?php } ?> 236 <?php if ( isset( $ property_details['brochure_3'][0] ) && $property_details['brochure_3'][0] !== '' ) { ?>237 <a target="_blank" href="<?php echo esc_url( $ property_details['brochure_3'][0] ); ?>">3</a>235 <?php if ( isset( $wppd_property_details['brochure_3'][0] ) && $wppd_property_details['brochure_3'][0] !== '' ) { ?> 236 <a target="_blank" href="<?php echo esc_url( $wppd_property_details['brochure_3'][0] ); ?>">3</a> 238 237 <?php } ?> 239 238 <?php } ?> … … 241 240 <?php } ?> 242 241 243 <?php if ( $ property_details['property_size'][0] ) { ?>242 <?php if ( $wppd_property_details['property_size'][0] ) { ?> 244 243 <div class="grid-property-attribute grid-property-attribute-size flex-element"> 245 <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="arrows-alt" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-arrows-alt fa-w-16 fa-fw"><path fill="currentColor" d="M352.201 425.775l-79.196 79.196c-9.373 9.373-24.568 9.373-33.941 0l-79.196-79.196c-15.119-15.119-4.411-40.971 16.971-40.97h51.162L228 284H127.196v51.162c0 21.382-25.851 32.09-40.971 16.971L7.029 272.937c-9.373-9.373-9.373-24.569 0-33.941L86.225 159.8c15.119-15.119 40.971-4.411 40.971 16.971V228H228V127.196h-51.23c-21.382 0-32.09-25.851-16.971-40.971l79.196-79.196c9.373-9.373 24.568-9.373 33.941 0l79.196 79.196c15.119 15.119 4.411 40.971-16.971 40.971h-51.162V228h100.804v-51.162c0-21.382 25.851-32.09 40.97-16.971l79.196 79.196c9.373 9.373 9.373 24.569 0 33.941L425.773 352.2c-15.119 15.119-40.971 4.411-40.97-16.971V284H284v100.804h51.23c21.382 0 32.09 25.851 16.971 40.971z" class=""></path></svg><br><span>Area</span><br><em><?php echo esc_html( strtok( $ property_details['property_size'][0], 'm' ) . 'm.' ); ?></em>244 <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="arrows-alt" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-arrows-alt fa-w-16 fa-fw"><path fill="currentColor" d="M352.201 425.775l-79.196 79.196c-9.373 9.373-24.568 9.373-33.941 0l-79.196-79.196c-15.119-15.119-4.411-40.971 16.971-40.97h51.162L228 284H127.196v51.162c0 21.382-25.851 32.09-40.971 16.971L7.029 272.937c-9.373-9.373-9.373-24.569 0-33.941L86.225 159.8c15.119-15.119 40.971-4.411 40.971 16.971V228H228V127.196h-51.23c-21.382 0-32.09-25.851-16.971-40.971l79.196-79.196c9.373-9.373 24.568-9.373 33.941 0l79.196 79.196c15.119 15.119 4.411 40.971-16.971 40.971h-51.162V228h100.804v-51.162c0-21.382 25.851-32.09 40.97-16.971l79.196 79.196c9.373 9.373 9.373 24.569 0 33.941L425.773 352.2c-15.119 15.119-40.971 4.411-40.97-16.971V284H284v100.804h51.23c21.382 0 32.09 25.851 16.971 40.971z" class=""></path></svg><br><span>Area</span><br><em><?php echo esc_html( strtok( $wppd_property_details['property_size'][0], 'm' ) . 'm.' ); ?></em> 246 245 </div> 247 246 <?php } ?> 248 247 249 248 <?php 250 if ( isset( $ property_details['property_floors'] ) ) {251 if ( sanitize_text_field( $ property_details['property_floors'][0] ) !== '' ) {249 if ( isset( $wppd_property_details['property_floors'] ) ) { 250 if ( sanitize_text_field( $wppd_property_details['property_floors'][0] ) !== '' ) { 252 251 ?> 253 252 <div class="grid-property-attribute grid-property-attribute-floorplan flex-element"> … … 271 270 272 271 <div class="grid-property-attribute grid-property-attribute-location flex-element"> 273 <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="map-marker-alt" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" class="svg-inline--fa fa-map-marker-alt fa-w-12 fa-fw"><path fill="currentColor" d="M172.268 501.67C26.97 291.031 0 269.413 0 192 0 85.961 85.961 0 192 0s192 85.961 192 192c0 77.413-26.97 99.031-172.268 309.67-9.535 13.774-29.93 13.773-39.464 0zM192 272c44.183 0 80-35.817 80-80s-35.817-80-80-80-80 35.817-80 80 35.817 80 80 80z" class=""></path></svg><br><span>Location</span><br><a href="#listing-map"><?php echo esc_html( $ property_area ); ?></a>272 <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="map-marker-alt" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" class="svg-inline--fa fa-map-marker-alt fa-w-12 fa-fw"><path fill="currentColor" d="M172.268 501.67C26.97 291.031 0 269.413 0 192 0 85.961 85.961 0 192 0s192 85.961 192 192c0 77.413-26.97 99.031-172.268 309.67-9.535 13.774-29.93 13.773-39.464 0zM192 272c44.183 0 80-35.817 80-80s-35.817-80-80-80-80 35.817-80 80 35.817 80 80 80z" class=""></path></svg><br><span>Location</span><br><a href="#listing-map"><?php echo esc_html( $wppd_property_area ); ?></a> 274 273 </div> 275 274 </section> … … 279 278 * Show the carousel for classic, cover or cinematic overlays 280 279 */ 281 if ( in_array( (int) $ property_template, [ 0, 1, 2 ] ) ) {282 wppd_show_property_images( $ property_id );280 if ( in_array( (int) $wppd_property_template, [ 0, 1, 2 ] ) ) { 281 wppd_show_property_images( $wppd_property_id ); 283 282 } 284 285 do_action( 'after_slider', $property_id );286 283 287 284 /** 288 285 * Show property description 289 286 */ 290 wppd_property_description( $ property_id );287 wppd_property_description( $wppd_property_id ); 291 288 292 289 /** 293 290 * Show property floorplans 294 291 */ 295 wppd_property_floorplans( $ property_id );292 wppd_property_floorplans( $wppd_property_id ); 296 293 297 294 /** 298 295 * Show property directions 299 296 */ 300 wppd_property_directions( $ property_id );297 wppd_property_directions( $wppd_property_id ); 301 298 302 299 /** 303 300 * Show property gallery (flexbin) 304 301 */ 305 wppd_property_flexbin( $ property_id );306 307 308 309 if ( $ property_details['property_market'][0] == 'New Developments' ) {310 $ linked_properties = $property_details['linked_properties'][0];311 312 if ( (string) $ linked_properties !== '' ) {302 wppd_property_flexbin( $wppd_property_id ); 303 304 305 306 if ( $wppd_property_details['property_market'][0] == 'New Developments' ) { 307 $wppd_linked_properties = $wppd_property_details['linked_properties'][0]; 308 309 if ( (string) $wppd_linked_properties !== '' ) { 313 310 ?> 314 311 <section class="grid-property-types-within"> … … 316 313 317 314 <?php 318 $ linked_properties_array = explode( ',', $linked_properties );319 $ importer_ids = [];320 321 foreach ( $ linked_properties_array as $linked_property ) {322 $ linked_property_args = [315 $wppd_linked_properties_array = explode( ',', $wppd_linked_properties ); 316 $wppd_importer_ids = []; 317 318 foreach ( $wppd_linked_properties_array as $wppd_linked_property ) { 319 $wppd_linked_property_args = [ 323 320 'post_type' => 'property', 324 321 'posts_per_page' => 1, … … 326 323 [ 327 324 'key' => 'importer_id', 328 'value' => $ linked_property,325 'value' => $wppd_linked_property, 329 326 'compare' => '=', 330 327 ], 331 328 ], 332 329 ]; 333 $ linked_property_object = new WP_Query( $linked_property_args );334 if ( $ linked_property_object->have_posts() ) {335 while ( $ linked_property_object->have_posts() ) {336 $ linked_property_object->the_post();337 $ importer_ids[] = $linked_property_object->post->ID;330 $wppd_linked_property_object = new WP_Query( $wppd_linked_property_args ); 331 if ( $wppd_linked_property_object->have_posts() ) { 332 while ( $wppd_linked_property_object->have_posts() ) { 333 $wppd_linked_property_object->the_post(); 334 $wppd_importer_ids[] = $wppd_linked_property_object->post->ID; 338 335 } 339 336 } 340 337 } 341 338 342 if ( count( $ importer_ids ) > 0 ) {343 echo do_shortcode( '[property-grid columns="3" in="' . implode( ',', $ importer_ids ) . '"]' );339 if ( count( $wppd_importer_ids ) > 0 ) { 340 echo do_shortcode( '[property-grid columns="3" in="' . implode( ',', $wppd_importer_ids ) . '"]' ); 344 341 } 345 342 ?> … … 356 353 // get reusable gutenberg block: 357 354 if ( (int) get_option( 'reusable_sidebar_id' ) > 0 ) { 358 $ reusable_sidebar_block = get_post( (int) get_option( 'reusable_sidebar_id' ) );359 360 echo wp_kses_post( apply_filters( 'the_content', $ reusable_sidebar_block->post_content ) );355 $wppd_reusable_sidebar_block = get_post( (int) get_option( 'reusable_sidebar_id' ) ); 356 357 echo wp_kses_post( apply_filters( 'the_content', $wppd_reusable_sidebar_block->post_content ) ); 361 358 } elseif ( is_active_sidebar( 'sidebar-widget' ) ) { 362 359 dynamic_sidebar( 'sidebar-widget' ); 363 360 } else { 364 echo wp_kses_post( wp4pm_get_sidebar_classic( $ property_id, $property_details ) );361 echo wp_kses_post( wp4pm_get_sidebar_classic( $wppd_property_id, $wppd_property_details ) ); 365 362 } 366 363 ?> … … 372 369 <section id="listing-map"> 373 370 <h4 class="listing-section-title">Location</h4> 374 <?php $location = $property_details['latitude'][0] . ',' . $property_details['longitude'][0]; ?>375 371 376 372 <?php if ( (string) get_option( 'map_provider' ) === 'osm' ) { ?> … … 379 375 <script> 380 376 window.addEventListener('load', function () { 381 var osmMap = L.map('osm-map').setView([<?php echo floatval( $ property_details['latitude'][0] ); ?>, <?php echo floatval( $property_details['longitude'][0] ); ?>], 16);382 383 L.marker([<?php echo floatval( $ property_details['latitude'][0] ); ?>, <?php echo floatval( $property_details['longitude'][0] ); ?>])377 var osmMap = L.map('osm-map').setView([<?php echo floatval( $wppd_property_details['latitude'][0] ); ?>, <?php echo floatval( $wppd_property_details['longitude'][0] ); ?>], 16); 378 379 L.marker([<?php echo floatval( $wppd_property_details['latitude'][0] ); ?>, <?php echo floatval( $wppd_property_details['longitude'][0] ); ?>]) 384 380 .addTo(osmMap) 385 381 .bindPopup('<?php echo esc_html( get_the_title() ); ?>'); … … 405 401 $per_page = (int) get_option( 'flex_grid_size' ); 406 402 407 $ property_county = get_the_terms( $property_id, 'property_county' );408 $ property_county = ( $property_county ) ? $property_county[0]->slug : '';409 410 $ property_area = get_the_terms( $property_id, 'property_area' );411 $ property_area = ( $property_area ) ? $property_area[0]->slug : '';412 413 $ property_price = get_post_meta( $property_id, 'price', true );414 $ property_price_min = (int) $property_price - 20000;415 $ property_price_max = (int) $property_price + 20000;416 417 $ custom_taxterms = wp_get_object_terms( $post->ID, 'property_type', [ 'fields' => 'ids' ] );418 $ args = [403 $wppd_property_county = get_the_terms( $wppd_property_id, 'property_county' ); 404 $wppd_property_county = ( $wppd_property_county ) ? $wppd_property_county[0]->slug : ''; 405 406 $wppd_property_area = get_the_terms( $wppd_property_id, 'property_area' ); 407 $wppd_property_area = ( $wppd_property_area ) ? $wppd_property_area[0]->slug : ''; 408 409 $wppd_property_price = get_post_meta( $wppd_property_id, 'price', true ); 410 $wppd_property_price_min = (int) $wppd_property_price - 20000; 411 $wppd_property_price_max = (int) $wppd_property_price + 20000; 412 413 $wppd_custom_taxterms = wp_get_object_terms( $post->ID, 'property_type', [ 'fields' => 'ids' ] ); 414 $wppd_args = [ 419 415 'post_type' => 'property', 420 416 'post_status' => 'publish', … … 429 425 [ 430 426 'key' => 'price', 431 'value' => [ $ property_price_min, $property_price_max ],427 'value' => [ $wppd_property_price_min, $wppd_property_price_max ], 432 428 'type' => 'numeric', 433 429 'compare' => 'BETWEEN', … … 439 435 'taxonomy' => 'property_type', 440 436 'field' => 'id', 441 'terms' => $ custom_taxterms,437 'terms' => $wppd_custom_taxterms, 442 438 ], 443 439 [ 444 440 'taxonomy' => 'property_area', 445 441 'field' => 'slug', 446 'terms' => [ $ property_area ],442 'terms' => [ $wppd_property_area ], 447 443 'operator' => 'IN', 448 444 ], … … 450 446 'post__not_in' => [ $post->ID ], 451 447 ]; 452 $ related_properties = new WP_Query( $args );453 454 if ( (int) $ related_properties->found_posts > 0 ) {448 $wppd_related_properties = new WP_Query( $wppd_args ); 449 450 if ( (int) $wppd_related_properties->found_posts > 0 ) { 455 451 ?> 456 452 <section class="property-grid"> … … 459 455 <div class="flex-container"> 460 456 <?php 461 if ( $ related_properties->have_posts() ) :462 while ( $ related_properties->have_posts() ) :463 $ related_properties->the_post();457 if ( $wppd_related_properties->have_posts() ) : 458 while ( $wppd_related_properties->have_posts() ) : 459 $wppd_related_properties->the_post(); 464 460 echo wp_kses_post( wp4pm_get_property_box( $post->ID ) ); 465 461 endwhile; … … 478 474 } 479 475 480 wp_reset_ query();476 wp_reset_postdata(); 481 477 482 478 get_footer(); -
property-drive/trunk/templates/template-parts.php
r3209948 r3447995 1 1 <?php 2 if ( ! defined( 'ABSPATH' ) ) { 3 exit; // Exit if accessed directly 4 } 5 2 6 /** 3 7 * Display the property description. … … 289 293 $out .= '<p><small>Share to social networks via the icons below.</small></p> 290 294 <p id="share-buttons">'; 291 $out .= get_sharing_buttons( $propertyId );295 $out .= wppd_get_sharing_buttons( $propertyId ); 292 296 $out .= '</p> 293 297 </div>
Note: See TracChangeset
for help on using the changeset viewer.