Plugin Directory

Changeset 3447995


Ignore:
Timestamp:
01/27/2026 03:14:40 PM (2 months ago)
Author:
butterflymedia
Message:

Plugin update to address guidelines violation

Location:
property-drive/trunk
Files:
7 deleted
21 edited

Legend:

Unmodified
Added
Removed
  • property-drive/trunk/assets/css/ui.css

    r3059897 r3447995  
    961961    position: relative;
    962962}
    963 .property-card--image-count,
    964 .pd-box-favourite {
     963.property-card--image-count {
    965964    position: absolute;
    966965    z-index: 0;
     
    971970    font-size: 18px;
    972971    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;
    984972}
    985973
     
    16761664@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
    16771665    .leaflet-control-fullscreen a {
    1678         background-image:url(../images/fullscreen@2x.png);
     1666        background-image:url(../images/fullscreen-2x.png);
    16791667    }
    16801668}
  • property-drive/trunk/assets/js/init.js

    r3059897 r3447995  
    44 * Licensed GPLv3
    55 */
    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}
     6function 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 }
    77
    88
     
    3939
    4040    location.search = query.join("&");
    41 }
    42 
    43 
    44 
    45 function get_favourites() {
    46     // Get favorites from local storage or empty array
    47     var favourites = JSON.parse(localStorage.getItem('favourites')) || [];
    48 
    49     // Add class 'fav' to each favorite
    50     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 listener
    57     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 in
    73         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 success
    80             }
    81         };
    82         request.send('action=save_user_favourite&property_id=' + id);
    83     });
    8441}
    8542
     
    10966        }
    11067    };
    111     request.onerror = function() {
     68    request.onerror = function () {
    11269        // Connection error
    11370    };
     
    201158    //    a = addressPoints[i];
    202159    //    title = a[2];
    203         //marker = L.marker(new L.LatLng(a[0], a[1]), {
    204         //    title: title,
    205         //    icon: icon
    206         //});
    207         //marker.bindPopup(getDetailsById(title));
    208         //marker.addTo(osmMap); // Regular marker
    209         //markers.addLayer(marker); // Marker clusterer
    210 
    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: title
    219         });
    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    /**/
    223180    //}
    224181    //osmMap.addLayer(markers); // Marker clusterer
     
    296253        }
    297254    };
    298     request.onerror = function() {
     255    request.onerror = function () {
    299256        // Connection error
    300257    };
     
    545502
    546503
    547     /**
    548      * Basic favourites engine
    549      *
    550      * Local storage stores strings so we use JSON to stringify for storage and parse to get out of storage
    551      */
    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 favourites
    568         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 
    606504    document.querySelector('body').addEventListener('click', function (e) {
    607505        /**
     
    618516                    '<input type="text" id="contact-phone" placeholder="Phone"><br>' +
    619517                    '<textarea id="contact-message" rows="3"></textarea>' +
    620                 '</p>';
     518                    '</p>';
    621519
    622520            var options = {
     
    646544                    request.onload = function () {
    647545                        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' });
    649547                        }
    650548                    };
     
    670568            request.onload = function () {
    671569                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' });
    673571
    674572                    // Reset fields on success
     
    701599        });
    702600
    703         window.addEventListener('click', function(event) {
     601        window.addEventListener('click', function (event) {
    704602            if (event.target == modal) {
    705603                modal.style.display = 'none';
  • property-drive/trunk/includes/admin/build_admin_page.php

    r3059897 r3447995  
    11<?php
    2 function pm_menu_links() {
     2if ( ! defined( 'ABSPATH' ) ) {
     3    exit; // Exit if accessed directly
     4}
     5
     6function wppd_menu_links() {
    37    add_menu_page('Property Drive Settings', 'Property Drive', 'manage_options', 'property_drive', 'wppd_build_admin_page', 'dashicons-admin-home', 4);
    48}
    59
    6 add_action('admin_menu', 'pm_menu_links');
     10add_action('admin_menu', 'wppd_menu_links');
    711
    812function wppd_dashboard_help() {
     
    1822    $propertyArgs = [
    1923        'post_type' => 'property',
    20         'meta_query' => [
    21             [
    22                 'key' => 'property_view_count'
    23             ]
    24         ]
     24        'meta_key'  => 'property_view_count',
    2525    ];
    2626
     
    6161    $nonce = wp_create_nonce('wppd_property_admin');
    6262
    63     $jtg_plugin_logo = plugin_dir_url(dirname(__DIR__)) . 'assets/images/4property-logo.png';
    64 
    6563    $plugin_version_dir = plugin_dir_path(dirname(__DIR__)).'property-drive.php';
    6664    $plugin_version = get_plugin_data($plugin_version_dir, 'Version');
     
    7371
    7472        <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>
    8280        </h2>
    8381
    8482        <?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>
    8684
    8785            <h2 class="titleblock">Welcome to WP Property Drive! Get the most out of your properties.</h2>
    8886
    8987            <?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>
    9488        <?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>
    9690
    9791            <?php
    9892            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'] ) ) : '');
    110108
    111109                echo '<div class="updated notice is-dismissible"><p>Settings updated successfully!</p></div>';
     
    117115
    118116            <form method="post">
     117                <?php wp_nonce_field( 'wppd_property_admin', 'wppd_property_admin_nonce' ); ?>
    119118                <table class="form-table">
    120119                    <tbody>
     
    122121                            <th scope="row"><label>Estate Agency Name</label></th>
    123122                            <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">
    125124                                <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
    126125                            </td>
     
    129128                            <th scope="row"><label>Estate Agency Email Address</label></th>
    130129                            <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">
    132131                                <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
    133132                                <input type="checkbox" name="mask_agency_email" value="1" <?php checked(1, (int) get_option('mask_agency_email')); ?>> Mask this information
     
    137136                            <th scope="row"><label>Estate Agency Phone Number</label></th>
    138137                            <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">
    140139                                <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
    141140                                <input type="checkbox" name="mask_agency_phone" value="1" <?php checked(1, (int) get_option('mask_agency_phone')); ?>> Mask this information
     
    151150                                    if (get_option('agency_logo')) {
    152151                                        $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>';
    154153                                    } else {
    155154                                        echo '<p>No image selected.</p>';
     
    157156
    158157                                    if (!empty($_POST['image'])) {
    159                                         $image_url = esc_url($_POST['image']);
     158                                        $image_url = esc_url_raw( wp_unslash( $_POST['image'] ) );
    160159                                    }
    161160
    162161                                    wp_enqueue_media();
    163162                                    ?>
    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') ); ?>">
    165164                                    <input id="pm-upload-image-btn" type="button" class="jtg-logo-upload-btn button button-secondary" value="Upload Logo">
    166165                                </div>
     
    208207            </script>
    209208        <?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>
    211210
    212211            <?php
    213212            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);
    234231
    235232                echo '<div class="updated notice is-dismissible"><p>Settings updated successfully!</p></div>';
     
    256253                                    <input type="checkbox" id="allow_quick_contact" name="allow_quick_contact" value="1" <?php echo ((int) get_option('allow_quick_contact') === 1) ? 'checked' : ''; ?>>
    257254                                    <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>
    262255                                </p>
    263256                            </td>
     
    329322                                <br><small>Select your reusable sidebar or <a href="' . admin_url('edit.php?post_type=wp_block') . '">create one now</a>.</small>';
    330323
    331                                 echo $out;
     324                                echo wp_kses_post( $out );
    332325                                ?>
    333326                            </td>
     
    375368            <?php
    376369            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);
    388384
    389385                // 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);
    391387
    392388                // 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);
    397393                //
    398394
    399                 if ((int) $_POST['force_cinematic_overlay'] === 1) {
     395                if (isset( $_POST['force_cinematic_overlay'] ) && absint( $_POST['force_cinematic_overlay'] ) === 1) {
    400396                    $tempArgs = [
    401397                        'fields' => 'ids',
     
    415411
    416412                // 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);
    418414
    419415                echo '<div class="updated notice is-dismissible"><p>Settings updated successfully!</p></div>';
     
    422418
    423419            <form method="post">
     420                <?php wp_nonce_field( 'wppd_property_admin', 'wppd_property_admin_nonce' ); ?>
    424421                <div class="flex-container">
    425422                    <div class="flex-item flex-item-half flex-item-box">
     
    474471                                        <p>
    475472                                            <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') ); ?>">
    477474                                        </p>
    478475                                        <p>
    479476                                            <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') ); ?>">
    481478                                        </p>
    482479                                        <p>
    483480                                            <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') ); ?>">
    485482                                        </p>
    486483                                    </td>
     
    496493                                            wp_dropdown_pages([
    497494                                                'name' => 'property_map_id',
    498                                                 'selected' => get_option('property_map_id')
     495                                                'selected' => (int) get_option('property_map_id')
    499496                                            ]);
    500497                                            ?>
     
    571568            <?php
    572569            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);
    590590
    591591                echo '<div class="updated notice is-dismissible"><p>Settings updated successfully!</p></div>';
     
    594594
    595595            <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') ); ?>">
    597598                <table class="form-table">
    598599                    <tbody>
     
    645646                                        }
    646647
    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>
    650651                                        </li>';
    651652                                    }
     
    676677        <?php } else if ($tab === 'users') {
    677678            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);
    679683
    680684                echo '<div class="updated notice is-dismissible"><p>Settings updated successfully!</p></div>';
     
    684688
    685689            <form method="post" action="">
     690                <?php wp_nonce_field( 'wppd_property_admin', 'wppd_property_admin_nonce' ); ?>
    686691                <table class="form-table">
    687692                    <tbody>
     
    705710                                <p>
    706711                                    <input type="checkbox" checked disabled> Profile Editor<br>
    707                                     <input type="checkbox" checked disabled> Favourite Properties<br>
    708712                                </p>
    709713                            </td>
  • property-drive/trunk/includes/helpers.php

    r3209948 r3447995  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) {
     3    exit; // Exit if accessed directly
     4}
     5
    26function wppd_show_property_images( $property_id ) {
    37    $image_array = get_post_meta( $property_id, 'detail_images_array', true );
     
    121125
    122126    if ( isset( $linkedProperties ) && (string) $linkedProperties !== '' ) {
    123         $out .= get_combined_property_ber( $linkedProperties );
     127        $out .= wppd_get_combined_property_ber( $linkedProperties );
    124128    } elseif ( in_array( $berRating, [ 'A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3', 'D1', 'D2', 'E1', 'E2', 'F', 'G' ] ) ) {
    125129        $out = '<div class="bercrumb ber-' . $berRatingClass . '">
     
    151155 * @return string $out
    152156 */
    153 function get_combined_property_ber( $linkedProperties ) {
     157function wppd_get_combined_property_ber( $linkedProperties ) {
    154158    if ( (string) $linkedProperties !== '' ) {
    155159        $linkedPropertiesArray = explode( ',', $linkedProperties );
     
    160164                'post_type'      => 'property',
    161165                '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,
    169168            ];
    170169            $linkedPropertyObject = new WP_Query( $linkedPropertyArgs );
     
    237236    }
    238237
    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 );
    241240    } elseif ( $bedrooms > 0 ) {
    242241        return $iconString . $bedrooms;
     
    280279function wp4pm_get_property_price( $property_id ) {
    281280    $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 );
    283282
    284283    $currency        = get_option( 'jtg_currency' );
    285     $currency_info   = jtg_currency_symbol( $currency );
     284    $currency_info   = wppd_currency_symbol( $currency );
    286285    $currency_symbol = $currency_info['symbol'];
    287286
     
    577576
    578577/**
    579  * Get favourite icon.
    580  *
    581  * @since 2.1.6
    582  *
    583  * @param  int    $property_id Property ID.
    584  * @return string
    585  */
    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 /**
    595578 * Get property image count.
    596579 *
     
    617600
    618601
    619 function jtg_currency_symbol( $currency ) {
     602function wppd_currency_symbol( $currency ) {
    620603    $currency_symbol = [
    621604        'symbol'     => '&euro;',
     
    646629}
    647630
    648 function pd_property_view_count( $post_id, $update = false ) {
     631function wppd_property_view_count( $post_id, $update = false ) {
    649632    $viewsCount = get_post_meta( $post_id, 'property_view_count', true ) ?? 0;
    650633
     
    666649 * @return null
    667650 */
    668 function pd_property_view_increment() {
    669     $property_id = $_POST['propertyId'];
     651function 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    }
    670664
    671665    $viewsCount = get_post_meta( $property_id, 'property_view_count', true );
     
    674668    update_post_meta( $property_id, 'property_view_count', $viewsCount );
    675669
    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 &amp; Commercial',
    696         'Residential units only',
    697         'Residential & Commercial units',
    698         'Residential &amp; Commercial units',
    699         'With Offices',
    700         'Block',
    701         'Residential & Commercial',
    702         'Residential &amp; 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}
     672add_action( 'wp_ajax_pd_property_view_increment', 'wppd_property_view_increment' );
     673add_action( 'wp_ajax_nopriv_pd_property_view_increment', 'wppd_property_view_increment' );
     674
     675
     676
     677function 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 );
    825692
    826693    $subjectLine = 'Contact Request (ACQ)';
     
    829696    <p>Contact details:</p>
    830697    <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>
    836703    </ul>';
    837704
    838705    $headers[] = 'Content-Type: text/html;';
    839706    $headers[] = 'X-Mailer: WordPress/PropertyDrive;';
    840     $headers[] = "Reply-To: $name <$email>;";
     707    $headers[] = 'Reply-To: ' . sanitize_email( $name ) . ' <' . sanitize_email( $email ) . '>';
    841708
    842709    wp_mail( $to, $subjectLine, $body, $headers );
    843710}
    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'];
     711add_action( 'wp_ajax_pd_request_contact', 'wppd_request_contact' );
     712add_action( 'wp_ajax_nopriv_pd_request_contact', 'wppd_request_contact' );
     713
     714
     715
     716function 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'] ) ) : '';
    851724
    852725    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 ) . '"]' ) );
    854727    }
    855728
    856729    wp_die();
    857730}
    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' );
     731add_action( 'wp_ajax_get_properties_by_id', 'wppd_get_properties_by_id' );
     732add_action( 'wp_ajax_nopriv_get_properties_by_id', 'wppd_get_properties_by_id' );
    860733
    861734
     
    871744 * @param int $parentId WordPress property (CPT) ID.
    872745 */
    873 function getLinkedPropertiesPriceRange( $parentId ) {
     746function wppd_get_linked_properties_price_range( $parentId ) {
    874747    if ( get_post_meta( $parentId, 'property_market', true ) == 'New Developments' ) {
    875748        $currency        = get_option( 'jtg_currency' );
    876         $currency_info   = jtg_currency_symbol( $currency );
     749        $currency_info   = wppd_currency_symbol( $currency );
    877750        $currency_symbol = $currency_info['symbol'];
    878751
     
    887760                    'post_type'      => 'property',
    888761                    '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,
    896764                ];
    897765                $linkedPropertyObject = new WP_Query( $linkedPropertyArgs );
     
    924792 * @param string $propertyList A list of importer_ids.
    925793 */
    926 function getLinkedPropertiesBedroomRange( $propertyList ) {
     794function wppd_get_linked_properties_bedroom_range( $propertyList ) {
    927795    if ( (string) $propertyList !== '' ) {
    928796        $linkedPropertiesArray = explode( ',', $propertyList );
     
    933801                'post_type'      => 'property',
    934802                '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,
    942805            ];
    943806            $linkedPropertyObject = new WP_Query( $linkedPropertyArgs );
     
    991854
    992855
    993 function show_property_attachments( $property_id ) {
     856function wppd_show_property_attachments( $property_id ) {
    994857    /**
    995858     * Get all post attachments and exclude featured image
     
    1017880}
    1018881
    1019 function get_sharing_buttons( $property_id ) {
     882function wppd_get_sharing_buttons( $property_id ) {
    1020883    $property_id = (int) $property_id;
    1021884
     
    1030893 * Register property meta box
    1031894 */
    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' );
     895function wppd_add_meta_box() {
     896    add_meta_box( 'pd_meta_box', 'Property Details', 'wppd_property_metabox_callback', [ 'property' ] );
     897}
     898add_action( 'add_meta_boxes', 'wppd_add_meta_box' );
    1036899
    1037900/**
    1038901 * eCards meta box Callback
    1039902 */
    1040 function property_metabox_callback( $post ) {
     903function wppd_property_metabox_callback( $post ) {
    1041904    wp_nonce_field( 'property', 'property_nonce' );
    1042905
     
    1053916    <p>
    1054917        <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 ) ) ); ?>">
    1056919    </p>
    1057920
     
    1067930    <h3>Property Media</h3>
    1068931    <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() ) ); ?>
    1070933    </div>
    1071934
    1072935    <p>
    1073936        <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 ) ); ?>">
    1075938    </p>
    1076939
     
    1082945                <br>
    1083946                <?php
    1084                 function selectPropertyStatus( $post_id, $status ) {
     947                function wppd_select_property_status( $post_id, $status ) {
    1085948                    $propertyStatusDb = (string) get_post_meta( $post_id, 'property_status', true );
    1086949
     
    1090953                <select name="property_status" id="property-status" required>
    1091954                    <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>
    1094957                    </optgroup>
    1095958                    <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>
    1099962                    </optgroup>
    1100963                    <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>
    1109972                    </optgroup>
    1110973                </select>
     
    1113976            <p>
    1114977                <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 ) ); ?>">
    1116979            </p>
    1117980
    1118981            <p>
    1119982                <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 ) ); ?>">
    1121984                <br><small>e.g. Investment, Waterfront, Urban, Coastal</small>
    1122985            </p>
     
    1124987            <p>
    1125988                <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 ) ); ?>">
    1127990                <br>
    1128991                <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 ) ); ?>">
    1130993            </p>
    1131994            <p>
    1132995                <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 ) ); ?>">
    1134997                <br>
    1135998                <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 ) ); ?>">
    11371000            </p>
    11381001            <p>
    11391002                <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 ) ); ?>">
    11411004                <br>
    11421005                <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 ) ); ?>">
    11441007            </p>
    11451008            <p>
    11461009                <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 ) ); ?>">
    11481011                <bR>
    11491012                <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 ) ); ?>">
    11511014            </p>
    11521015
     
    11601023            <p>
    11611024                <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 ) ); ?>">
    11631026                <br>
    11641027                <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 ) ); ?>">
    11661029            </p>
    11671030
     
    11691032            <p>
    11701033                <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 ) ); ?>">
    11721035                <br>
    11731036                <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 ) ); ?>">
    11751038                <br>
    11761039                <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 ) ); ?>">
    11781041                <br>
    11791042                <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 ) ); ?>">
    11811044                <br>
    11821045                <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 ) ); ?>">
    11841047                <br>
    11851048                <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 ) ); ?>">
    11871050            </p>
    11881051
     
    11901053            <p>
    11911054                <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 ) ); ?>">
    11931056                <br>
    11941057                <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 ) ); ?>">
    11961059                <br>
    11971060                <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 ) ); ?>">
    11991062            </p>
    12001063        </div>
     
    12071070 * Save property meta box
    12081071 */
    1209 function property_save_postdata( $post_id ) {
     1072function wppd_property_save_postdata( $post_id ) {
    12101073    if ( ! isset( $_POST['property_nonce'] ) ) {
    12111074        return $post_id;
    12121075    }
    12131076
    1214     $nonce = $_POST['property_nonce'];
     1077    $nonce = sanitize_text_field( wp_unslash( $_POST['property_nonce'] ) );
    12151078
    12161079    if ( ! wp_verify_nonce( $nonce, 'property' ) ) {
     
    12241087    $propertyLock = isset( $_POST['property_lock'] ) ? 1 : 0;
    12251088
    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'] ) ) : '';
    12401103
    12411104    $propertyIsFeatured = isset( $_POST['is_featured'] ) ? 'true' : 'false';
    12421105
    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'] ) ) : '';
    12551118
    12561119    update_post_meta( $post_id, 'property_lock', $propertyLock );
     
    13091172    update_post_meta( $post_id, 'property_order', $propertyOrder );
    13101173}
    1311 add_action( 'save_post', 'property_save_postdata' );
     1174add_action( 'save_post', 'wppd_property_save_postdata' );
    13121175
    13131176
     
    13161179 * Convert a multi-dimensional array into a single-dimensional array.
    13171180 */
    1318 function array_flatten( $array ) {
     1181function wppd_array_flatten( $array ) {
    13191182    if ( ! is_array( $array ) ) {
    13201183        return false;
     
    13241187    foreach ( $array as $key => $value ) {
    13251188        if ( is_array( $value ) ) {
    1326             $result = array_merge( $result, array_flatten( $value ) );
     1189            $result = array_merge( $result, wppd_array_flatten( $value ) );
    13271190        } else {
    13281191            $result[ $key ] = $value;
     
    13531216add_action( 'wp_footer', 'wp4pm_analytics_footer' );
    13541217function 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
     1224add_action( 'admin_init', 'wppd_add_property_menu_order' );
     1225
     1226function wppd_add_property_menu_order() {
    13641227    add_post_type_support( 'property', 'page-attributes' );
    13651228}
     
    13681231
    13691232
    1370 function supernova_accordion_item( $atts, $content = null ) {
     1233function wppd_accordion_item( $atts, $content = null ) {
    13711234    $attributes = shortcode_atts(
    13721235        [
     
    13861249}
    13871250
    1388 add_shortcode( 'supernova-accordion-item', 'supernova_accordion_item' );
     1251add_shortcode( 'supernova-accordion-item', 'wppd_accordion_item' );
    13891252
    13901253
     
    14051268            }
    14061269
    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 ) ) . '">';
    14081271
    14091272            break;
    14101273        case 'views':
    1411             $viewCounter = (int) pd_property_view_count( get_the_ID(), false );
     1274            $viewCounter = (int) wppd_property_view_count( get_the_ID(), false );
    14121275
    14131276            echo number_format( $viewCounter );
     
    14241287            }
    14251288
    1426             echo $status;
     1289            echo esc_html( $status );
    14271290
    14281291            break;
     
    14301293            $m_orig    = get_post_field( 'post_modified', $post_id, 'raw' );
    14311294            $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 );
    14331296            $modr_id   = get_post_meta( $post_id, '_edit_last', true );
    14341297            $auth_id   = get_post_field( 'post_author', $post_id, 'raw' );
     
    14361299            $user_info = get_userdata( $user_id );
    14371300
    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>';
    14391302
    14401303            break;
    14411304        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>';
    14431308
    14441309            break;
     
    14651330
    14661331/**/
    1467 add_action( 'init', 'supernova_access_init' );
    1468 function supernova_access_init() {
     1332add_action( 'init', 'wppd_access_init' );
     1333function wppd_access_init() {
    14691334    if ( is_admin() && ! current_user_can( 'administrator' ) && ! ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
    1470         wp_redirect( home_url() );
     1335        wp_safe_redirect( home_url() );
    14711336
    14721337        exit;
    14731338    }
    14741339}
    1475 add_action( 'after_setup_theme', 'supernova_remove_admin_bar' );
    1476 
    1477 function supernova_remove_admin_bar() {
     1340add_action( 'after_setup_theme', 'wppd_remove_admin_bar' );
     1341
     1342function wppd_remove_admin_bar() {
    14781343    if ( ! current_user_can( 'administrator' ) && ! is_admin() ) {
    14791344        show_admin_bar( false );
  • property-drive/trunk/includes/inline_styling.php

    r2354697 r3447995  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) {
     3    exit; // Exit if accessed directly
     4}
     5
    26function wp4pm_add_plugin_styles() {
    37    $ribbonColourSale = get_option('ribbon_colour_sale');
     
    1115    }';
    1216
    13     wp_register_style('ui-custom', false);
     17    wp_register_style('ui-custom', false, array(), WPPD_VERSION);
    1418    wp_add_inline_style('ui-custom', $css);
    1519}
  • property-drive/trunk/includes/meta.php

    r2361321 r3447995  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) {
     3    exit; // Exit if accessed directly
     4}
     5
    26/**
    37 * Add meta box
     
    610 */
    711function 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');
    913}
    1014
     
    1822 * @param post $post The post object
    1923 */
    20 function featured_property_build_meta_box($post) {
     24function wppd_featured_property_build_meta_box($post) {
    2125    wp_nonce_field(basename(__FILE__), 'featured_property_meta_box_nonce');
    2226
     
    4549 * @param int $post_id The post ID.
    4650 */
    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__))) {
     51function 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__))) {
    4953        return;
    5054    }
     
    5660    }
    5761
    58     $propertyTemplate = isset($_POST['property_template']) ? (int) $_POST['property_template'] : '';
     62    $propertyTemplate = isset($_POST['property_template']) ? absint( $_POST['property_template'] ) : '';
    5963
    6064    update_post_meta($post_id, '_property_template', $propertyTemplate);
    6165}
    6266
    63 add_action('save_post', 'featured_property_save_meta_box_data');
     67add_action('save_post', 'wppd_featured_property_save_meta_box_data');
  • property-drive/trunk/includes/property_search.php

    r2208719 r3447995  
    11<?php
    2 function jtg_add_query_vars($public_query_vars) {
     2if ( ! defined( 'ABSPATH' ) ) {
     3    exit; // Exit if accessed directly
     4}
     5
     6function wppd_add_query_vars($public_query_vars) {
    37    $public_query_vars[] = 'property_status';
    48    $public_query_vars[] = 'property_type';
     
    1418    return $public_query_vars;
    1519}
    16 add_filter('query_vars', 'jtg_add_query_vars');
     20add_filter('query_vars', 'wppd_add_query_vars');
  • property-drive/trunk/includes/setup-plugin-options.php

    r3209948 r3447995  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) {
     3    exit; // Exit if accessed directly
     4}
     5
    26/**
    37 * Build property custom post type
     
    155159
    156160    add_option( 'allow_quick_contact', 1 );
    157     add_option( 'allow_favourites', 0 );
    158161    add_option( 'show_related_properties', 1 );
    159162
  • property-drive/trunk/modules/init.php

    r3059897 r3447995  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) {
     3    exit; // Exit if accessed directly
     4}
     5
    26require_once 'user_sign_up.php';
    37require_once 'user_dashboard.php';
    48
    5 require_once 'cpt-favourites.php';
    6 
    79require_once 'slider/slider.php';
  • property-drive/trunk/modules/slider/slider.php

    r3059897 r3447995  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) {
     3    exit; // Exit if accessed directly
     4}
     5
    26function wp4pm_slider_enqueue() {
    37    wp_enqueue_style('slider', plugins_url('/slider.css', __FILE__), [], '1.0.1');
     
    711    wp_enqueue_script('slider', plugins_url('/slider.js', __FILE__), ['flickity'], '1.0.1', true);
    812    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')
    1015    ]);
    1116}
     
    1520
    1621function wp4pm_show_slider($atts) {
     22    // Sanitize and validate attributes
    1723    $attributes = shortcode_atts([
    1824        'type' => 'slide',
     
    2632    ], $atts);
    2733
    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>';
    2951
    3052    return $out;
     
    3658
    3759function 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
    3865    $out = '';
    3966
    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';
    4178
    4279    if ((string) $ids !== '') {
    4380        $idArray = array_map('trim', explode(',', $ids));
    4481        $idArray = array_filter($idArray);
     82        $idArray = array_map('intval', $idArray); // Ensure all IDs are integers
    4583    }
    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']);
    5284
    5385    $homepageHeroHeight = ((string) $fullheight === 'yes') ? 'fullvh' : '';
    5486    $homepageHeroWidth = ((string) $fullwidth === 'yes') ? 'supernova-fullwidth' : '';
    5587
    56     $out .= '<div class="slider ' . $homepageHeroWidth . ' homepage-hero ' . $homepageHeroHeight . '">
     88    $out .= '<div class="slider ' . esc_attr($homepageHeroWidth) . ' homepage-hero ' . esc_attr($homepageHeroHeight) . '">
    5789        <div class="homepage-hero-slider">';
    5890            $args = [
     
    76108                    $hero = $hero[0];
    77109                    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));
    79111                    }
    80112
     
    82114                    $slideContent = do_shortcode(get_the_content(get_the_ID()));
    83115                    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>';
    85117                    }
    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>' : '';
    87119
    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;">' .
    89121                        $zoomContent .
    90122                        $dataVideo .
    91 
    92123                        '<div class="wrap">' .
    93                             $slideContent .
     124                            wp_kses_post($slideContent) .
    94125                        '</div>
    95126                    </div>';
     
    100131    </div>';
    101132
    102     echo $out;
     133    echo wp_kses_post( $out );
    103134
    104135    wp_die();
     
    120151    $autoPlay = ((int) get_option('flickity_autoPlay') > 0) ? (int) get_option('flickity_autoPlay') : 'false';
    121152
    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) . ' }\'>';
    123154        foreach ($imageArray as $imageUri) {
    124155            $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') . '">
    126157            </div>';
    127158        }
    128159    $out .= '</div>';
    129160
    130     echo $out;
     161    echo wp_kses_post( $out );
    131162}
    132163
     
    140171    $out = '<div class="flickity-carousel-parsley--wrap">';
    141172
    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) . ' }\'>';
    143174        foreach ($imageArray as $imageUri) {
    144175            $imageUri = wppd_remove_var($imageUri, 'w');
     
    148179
    149180            $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') . '">
    151182            </div>';
    152183        }
     
    154185    $out .= '<div class="flickity-carousel-parsley--elements">
    155186        <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>
    157188        </ul>
    158189    </div>';
    159190    $out .= '</div>';
    160191
    161     echo $out;
     192    echo wp_kses_post( $out );
    162193}
  • property-drive/trunk/modules/user_dashboard.php

    r3059897 r3447995  
    11<?php
    2 function jtg_user_dashboard() {
     2if ( ! defined( 'ABSPATH' ) ) {
     3    exit; // Exit if accessed directly
     4}
     5
     6function wppd_user_dashboard() {
    37    $out = '';
    48
     
    1216        // Save user details
    1317        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'] ) ) : '');
    2128
    22             $out .= '<p>Profile updated successfully.</p>';
     29                $out .= '<p>Profile updated successfully.</p>';
     30            }
    2331        }
    2432
    25         $out .= '<h2>' . $userData->first_name . ' ' . $userData->last_name;
     33        $out .= '<h2>' . esc_html( $userData->first_name ) . ' ' . esc_html( $userData->last_name );
    2634        $out .= '</h2>';
    2735
    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>';
    2937
    3038        $out .= '<details class="user-dashboard-menu-item">
     
    3644            <h3>My Profile</h3>
    3745            <form class="supernova-profile-form" method="post">
     46                ' . wp_nonce_field( 'user_profile_update', 'user_profile_nonce', true, false ) . '
    3847                <div class="wp-block-columns has-2-columns">
    3948                    <div class="wp-block-column">
    4049                        <p>
    4150                            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">
    4352                        </p>
    4453                        <p>
    4554                            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">
    4756                        </p>
    4857                    </div>
     
    5059                        <p>
    5160                            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">
    5362                        </p>
    5463                        <p>
    5564                            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">
    5766                        </p>
    5867                        <p>
     
    6574
    6675        <details class="user-dashboard-menu-item">
    67             <summary title="Click to expand this section">
    68                 My Favourite Properties
    69                 <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                                             Delete
    102                                         </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">
    12176            <summary title="Click to expand this section">
    12277                My Documents
     
    14297                            $attachmentsQuery->the_post();
    14398                            $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 ) .
    145100                            '</div>';
    146101                        }
     
    179134
    180135                '<p>
    181                     <small>Your account gives you access to alerts, notifications, favourites and more.</small>
     136                    <small>Your account gives you access to alerts, notifications and more.</small>
    182137                </p>
    183138            </div>
     
    185140                <h4>Sign Up</h4>' .
    186141
    187                 supernova_custom_registration() . '
     142                wppd_custom_registration() . '
    188143            </div>
    189144        </div>
     
    195150}
    196151
    197 add_shortcode('user-dashboard', 'jtg_user_dashboard');
     152add_shortcode('user-dashboard', 'wppd_user_dashboard');
  • property-drive/trunk/modules/user_sign_up.php

    r2210797 r3447995  
    11<?php
    2 function supernova_custom_registration() {
     2if ( ! defined( 'ABSPATH' ) ) {
     3    exit; // Exit if accessed directly
     4}
     5
     6function wppd_custom_registration() {
    37    $out = '';
    48
    59    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;
    716
    8         $registrationErrors = new WP_Error;
     17        $wppd_registration_errors = new WP_Error;
    918
    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'] ) ) : '';
    1527
    1628        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.');
    1830        }
    1931        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.');
    2133        }
    2234        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.');
    2436        }
    2537        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.');
    2739        }
    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) {
    3042                $out .= '<div class="ui-notification ui-notification--warning">' . $error . '</div>';
    3143            }
    3244        }
    3345
    34         if (1 > count($registrationErrors->get_error_messages())) {
     46        if (1 > count($wppd_registration_errors->get_error_messages())) {
    3547            $userData = [
    3648                'user_login' => $username,
     
    4860    $out .= '<div class="supernova-registration-form">
    4961        <form method="post">
     62            ' . wp_nonce_field( 'user_registration', 'user_registration_nonce', true, false ) . '
    5063            <p>
    5164                <label for="username">Username <b>*</b></label>
     
    7790}
    7891
    79 add_shortcode('supernova-registration', 'supernova_custom_registration');
     92add_shortcode('supernova-registration', 'wppd_custom_registration');
  • property-drive/trunk/property-drive.php

    r3209948 r3447995  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) {
     3    exit; // Exit if accessed directly
     4}
     5
    26/**
    37 * Plugin Name: Property Drive
     
    913 * License: GNU General Public License v3 or later
    1014 * License URI: https://www.gnu.org/licenses/gpl-3.0.html
     15 * Text Domain: property-drive
    1116 */
    1217
     
    8186        array(
    8287            'ajaxurl' => admin_url( 'admin-ajax.php' ),
     88            'nonce' => wp_create_nonce( 'wp4pm_ajax_nonce' ),
    8389        )
    8490    );
     
    8894    wp_enqueue_style( 'wp-color-picker' );
    8995
    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 );
    9197
    9298    wp_enqueue_script( 'sortable', plugins_url( 'assets/js/Sortable.min.js', __FILE__ ), array(), '1.7.0', true );
    9399
    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 );
    95101    wp_localize_script(
    96102        'jtg-admin-ui-js',
     
    141147            $out .= wp4pm_get_property_status_ribbon( $property_id );
    142148            $out .= wp4pm_get_property_image_count( $property_id, true );
    143             $out .= wp4pm_get_favourite_icon( $property_id );
    144149
    145150            // Thumbnail
  • property-drive/trunk/readme.txt

    r3059897 r3447995  
    33Tags: property, real estate, estate agents, house, home
    44Requires at least: 5.6
    5 Tested up to: 6.5
     5Tested up to: 6.9
    66Requires PHP: 7.0
    77Stable tag: 1.1.2
     
    1616
    1717Property 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
     21This 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
    1832
    1933If 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  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) {
     3    exit; // Exit if accessed directly
     4}
     5
    26function wp4pm_property_grid($atts) {
    37    $attributes = shortcode_atts([
     
    3236        'post_type' => 'property',
    3337        'post_status' => 'publish',
    34         'suppress_filters' => true,
    3538        'paged' => $paged,
    3639    ];
     
    236239            'taxonomy' => 'property_type',
    237240            'field' => 'slug',
    238             'terms' => array_flatten($propertyTypeArray)
     241            'terms' => wppd_array_flatten($propertyTypeArray)
    239242        ]);
    240243    }
     
    253256    }
    254257
    255 
    256 
     258    // Read-only GET params for display sort order; no state change — nonce not required.
     259    // phpcs:disable WordPress.Security.NonceVerification.Recommended
    257260    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';
    260263
    261264        if ($orderBy === 'price') {
     
    314317        }
    315318    }
     319    // phpcs:enable WordPress.Security.NonceVerification.Recommended
    316320
    317321    $query = new WP_Query($queryArgsMeta);
  • property-drive/trunk/shortcodes/property-map.php

    r3059897 r3447995  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) {
     3    exit; // Exit if accessed directly
     4}
     5
    26function wp4pm_property_map($atts) {
    37    $attributes = shortcode_atts([
     
    2630        'post_type' => 'property',
    2731        'post_status' => 'publish',
    28         'suppress_filters' => true,
    2932        'paged' => $paged,
    3033    ];
     
    211214            'taxonomy' => 'property_type',
    212215            'field' => 'slug',
    213             'terms' => array_flatten($propertyTypeArray)
     216            'terms' => wppd_array_flatten($propertyTypeArray)
    214217        ]);
    215218    }
     
    228231    }
    229232
    230 
    231 
     233    // Read-only GET params for display sort order; no state change — nonce not required.
     234    // phpcs:disable WordPress.Security.NonceVerification.Recommended
    232235    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';
    235238
    236239        if ($orderBy === 'price') {
     
    289292        }
    290293    }
     294    // phpcs:enable WordPress.Security.NonceVerification.Recommended
    291295
    292296    $query = new WP_Query($queryArgsMeta);
  • property-drive/trunk/shortcodes/search-form-results.php

    r3059897 r3447995  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) {
     3    exit; // Exit if accessed directly
     4}
     5
    26/**
    37 * Display property search results
     
    3236     * Check if this is a search
    3337     */
     38    // Read-only GET params from search form; used only to filter/order display — nonce not required.
     39    // phpcs:disable WordPress.Security.NonceVerification.Recommended
    3440    if (isset($_GET['property_type']) || isset($_GET['property_status']) || isset($_GET['group_type']) || isset($_GET['location']) || isset($_GET['property_keyword'])) {
    3541        $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
     
    3844
    3945        // 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') {
    4248                $tax_query[] = [[
    4349                    'taxonomy' => 'property_type',
     
    5662                    ]
    5763                ]];
    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') {
    5965                $tax_query[] = [[
    6066                    'taxonomy' => 'property_type',
     
    6874                    ]
    6975                ]];
    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') {
    7177                $tax_query[] = [[
    7278                    'taxonomy' => 'property_type',
     
    8490        }
    8591
    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'] ) ) !== '') {
    8793            $tax_query[] = [[
    8894                'taxonomy' => 'property_type',
    8995                'field' => 'slug',
    90                 'terms' => sanitize_text_field($_GET['property_type'])
     96                'terms' => sanitize_text_field( wp_unslash( $_GET['property_type'] ) )
    9197            ]];
    9298        }
    9399
    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'] ) )));
    96102            $propertyStatusArray = array_filter($propertyStatusArray);
    97103
     
    104110
    105111        if (isset($_GET['location'])) {
    106             $locationAreas = sanitize_text_field($_GET['location']);
     112            $locationAreas = sanitize_text_field( wp_unslash( $_GET['location'] ) );
    107113
    108114            $meta_query[] = [
     
    113119        }
    114120        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 );
    116125            $propertyType = $propertyLivingType = [];
    117126
     
    140149
    141150        if (isset($_GET['location_area'])) {
    142             $locationAreas = sanitize_text_field($_GET['location_area']);
     151            $locationAreas = sanitize_text_field( wp_unslash( $_GET['location_area'] ) );
    143152
    144153            $meta_query[] = [
     
    151160        $locationCounty = 0;
    152161
    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'] ) ) !== '') {
    154163            $locationArray = [
    155164                1 => 'Dublin',
     
    181190            ];
    182191
    183             $locationId = absint($_GET['location_county']);
     192            $locationId = isset( $_GET['location_county'] ) ? absint( $_GET['location_county'] ) : 0;
    184193            $locationCounty = (string) $locationArray[$locationId];
    185194
     
    195204                'key' => 'bedrooms',
    196205                'type' => 'NUMERIC',
    197                 'value' => (int) $_GET['beds'],
     206                'value' => absint( $_GET['beds'] ),
    198207                'compare' => '>='
    199208            ];
    200209        }
    201210        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;
    204213
    205214            $meta_query[] = [
     
    213222        $order_direction = 'ASC';
    214223        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') {
    216226                $order_direction = 'ASC';
    217227            } else {
     
    220230        }
    221231
    222         if (isset($_GET['orderby']) && (string) $_GET['orderby'] === 'date') {
     232        if (isset($_GET['orderby']) && (string) sanitize_text_field( wp_unslash( $_GET['orderby'] ) ) === 'date') {
    223233            $args = [
    224234                'paged' => $paged,
     
    230240                'meta_query' => $meta_query
    231241            ];
    232         } else if (!$_GET) {
     242        } else if (empty($_GET)) {
    233243            $args = [
    234244                'paged' => $paged,
     
    260270
    261271        if (isset($_GET['orderby'])) {
    262             $orderBy = (string) sanitize_text_field($_GET['orderby']);
     272            $orderBy = (string) sanitize_text_field( wp_unslash( $_GET['orderby'] ) );
    263273            if ($orderBy === 'price') {
    264274                $args['orderby'] = 'meta_value';
     
    273283        }
    274284
    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'] ) );
    277287        }
    278288    } else {
    279289
    280290    }
     291    // phpcs:enable WordPress.Security.NonceVerification.Recommended
    281292
    282293    $query = new WP_Query($args);
  • property-drive/trunk/shortcodes/search-form.php

    r2354697 r3447995  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) {
     3    exit; // Exit if accessed directly
     4}
     5
    26function wp4pm_get_pd_user_ip() {
     7    $ipAddress = '';
    38    if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
    4         $ipAddress = $_SERVER['HTTP_CLIENT_IP'];
     9        $ipAddress = sanitize_text_field( wp_unslash( $_SERVER['HTTP_CLIENT_IP'] ) );
    510    } 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'] ) );
    914    }
    1015
     
    3136}
    3237
    33 function jtg_search_type_4_shortcode($atts) {
     38function wppd_search_type_4_shortcode($atts) {
     39    // Add nonce field to the form
     40    $nonce = wp_create_nonce('property_search_nonce');
     41   
    3442    $resultsPage = get_permalink((int) get_option('search_results_page'));
    3543    if (!get_option('search_results_page')) {
     
    5361    $jtg_table_name = $wpdb->prefix . 'postmeta';
    5462
    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]);
    5665    $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     $searchFieldLocation = (int) get_option('search_field_location');
    73     $searchFieldMultiType = (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
    7786    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';
    7988
    8089        if ((string) $default_type !== '') {
     
    8594            <div class="property-group-switch">
    8695                <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>
    8897
    8998                <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>';
    91100
    92101                if ((string) $land === 'yes') {
    93102                    $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>';
    95104                }
    96105            $show .= '</div>
     
    101110
    102111    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';
    104113
    105114        if ((string) $default_status !== '') {
     
    124133    }
    125134    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>';
    128137
    129138            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>';
    131140            }
    132141
     
    134143    }
    135144    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>';
    144150
    145151        $searchString['features'] .= '</select>';
     
    148154        $keywordPlaceholder = trim($keyword_placeholder);
    149155
    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') . '">';
    152159    }
    153160    if ($searchFieldPrice === 1) {
    154161        $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>
    157164                <option value="10000">10,000</option>
    158165                <option value="20000">20,000</option>
     
    165172                <option value="500000">500,000</option>
    166173            </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>
    169176                <option value="10000">10,000</option>
    170177                <option value="20000">20,000</option>
     
    186193    }
    187194    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>';
    190197
    191198            foreach ($termsStatus as $row) {
    192                 $searchString['status'] .= '<option>' . $row . '</option>';
     199                $searchString['status'] .= '<option>' . esc_html($row) . '</option>';
    193200            }
    194201        $searchString['status'] .= '</select>';
    195202    }
    196203    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>
    199206            <option value="1">1+</option>
    200207            <option value="2">2+</option>
     
    208215    }
    209216    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>
    212219            <option value="1">1+</option>
    213220            <option value="2">2+</option>
     
    338345        $searchString['multitype'] = $string;
    339346    }
     347    // phpcs:enable WordPress.Security.NonceVerification.Recommended
    340348
    341349    /**
    342350     * Build search form
    343351     */
    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) . '">
    346355        <div class="wp4pm-search-progress-wrap">
    347356            <div class="wp4pm-search-progress"></div>
     
    349358        <div class="wp4pm wp4pm-flex">';
    350359
    351             $searchFieldArray = explode('|', (string) get_option('search_field_array'));
     360            $searchFieldArray = array_map('sanitize_text_field', explode('|', (string) get_option('search_field_array')));
    352361            foreach ($searchFieldArray as $searchFieldItem) {
    353362                if (isset($searchString[$searchFieldItem])) {
     
    356365            }
    357366
    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>
    359368        </div>
    360369        <div id="wp4pm-status"></div>
     
    363372    return $out;
    364373}
    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');
     374add_shortcode('jtg_search_type_4', 'wppd_search_type_4_shortcode');
     375add_shortcode('search_form', 'wppd_search_type_4_shortcode');
     376add_shortcode('property-search', 'wppd_search_type_4_shortcode');
  • property-drive/trunk/templates/part-sidebar-classic.php

    r3059897 r3447995  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) {
     3    exit; // Exit if accessed directly
     4}
     5
    26function wp4pm_get_sidebar_classic($propertyId, $propertyDetails) {
    37    $agentEmailAddress = get_option('agency_email');
     
    3539    $out .= '<div class="sidebar-section sidebar-sharing">
    3640        <div id="share-buttons">';
    37             $out .= get_sharing_buttons($propertyId);
     41            $out .= wppd_get_sharing_buttons($propertyId);
    3842        $out .= '</div>
    3943    </div>';
  • property-drive/trunk/templates/single-property.php

    r3209948 r3447995  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) {
     3    exit; // Exit if accessed directly
     4}
     5
    26get_header();
    37
     
    610while ( have_posts() ) {
    711    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 ); ?>">
    1318        <?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 );
    2126        } 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 );
    2328        }
    2429
    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 ) {
    3343            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>
    3545            </div>';
    3646
     
    3848        }
    3949
    40         // Build the Favourite action string
    41         $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 
    4650        // Build the title string
    47         $property_title_string = get_the_title() . $favourite_string;
     51        $wppd_property_title = get_the_title();
    4852
    4953        // 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' );
    5357        ?>
    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>
    5559
    5660        <script type="application/ld+json">
     
    6165                "@type": "PostalAddress",
    6266                "@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); ?>
    6670            },
    6771            "geo": {
    6872                "@type": "GeoCoordinates",
    6973                "@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); ?>
    7276            },
    73             "url": "<?php echo esc_url( get_permalink() ); ?>"
     77            "url": <?php echo wp_json_encode(get_permalink()); ?>
    7478        }
    7579        </script>
     
    7882            "@context": "http://schema.org",
    7983            "@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); ?>,
    8286            "offers": {
    8387                "@type": "Offer",
    8488                "priceCurrency": "EUR",
    8589                <?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";
    8892                }
    8993                ?>
    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); ?>,
    9296                "availability": "http://schema.org/InStock",
    93                 "url": "<?php echo esc_url( get_permalink() ); ?>",
     97                "url": <?php echo wp_json_encode(get_permalink()); ?>,
    9498                "seller": {
    9599                    "@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'] ?? ''); ?>
    102101                }
    103102            },
    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())); ?>
    105104        }
    106105        </script>
    107106
    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>
    109108
    110109        <div class="grid-wrap grid-single-property" itemscope itemtype="http://schema.org/Place">
    111110            <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>
    114113            </div>
    115114            <?php
    116115            // 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' );
    121120            }
    122121
    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];
    126125            }
    127126
    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>
    131130                </div>
    132131                <div class="pd-section-breakdown">
    133132                    <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>
    138137                    </ul>
    139138                </div>';
    140             } elseif ( $property_template === 3 ) {
     139            } elseif ( $wppd_property_template === 3 ) {
    141140                /**
    142141                 * Flickity (Sydney Gallery
    143142                 */
    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 ) {
    147146                /**
    148147                 * Flickity (Parsley) Gallery
    149148                 */
    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>';
    154153            } 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>';
    156155            }
    157156
     
    169168                        <?php
    170169                        // 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' ] ) ) {
    172171                            ?>
    173172                            <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 ) ); ?>
    176175                            </div>
    177176                        <?php } ?>
    178177
    179178                        <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' ) { ?>
    181180                                <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>
    182181                            <?php } else { ?>
     
    185184                            <br><span>Type</span>
    186185
    187                             <?php if ( $property_type[0]->name === 'Parking Space' ) { ?>
     186                            <?php if ( $wppd_property_type[0]->name === 'Parking Space' ) { ?>
    188187                                <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' ) { ?>
    190189                                <br><em>New Development</em>
    191190                            <?php } else { ?>
    192191                                <br><em>
    193192                                <?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 ) ) . ' '; }
    196195                                ?>
    197                                 <?php echo esc_html( $property_type[0]->name ); ?></em>
     196                                <?php echo esc_html( $wppd_property_type[0]->name ); ?></em>
    198197                            <?php } ?>
    199198                        </div>
    200199
    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>
    203202                        </div>
    204203
    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 ) ) { ?>
    206205                            <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 ) { ?>
    212211                            <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' ) { ?>
    218217                            <div class="grid-property-attribute grid-property-attribute-ber flex-element">
    219218                                <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] != '' ) { ?>
    225224                            <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>
    227226                                <br><span>Brochure</span>
    228227
    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>
    231230                                <?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>
    235234                                    <?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>
    238237                                    <?php } ?>
    239238                                <?php } ?>
     
    241240                        <?php } ?>
    242241
    243                         <?php if ( $property_details['property_size'][0] ) { ?>
     242                        <?php if ( $wppd_property_details['property_size'][0] ) { ?>
    244243                            <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>
    246245                            </div>
    247246                        <?php } ?>
    248247
    249248                        <?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] ) !== '' ) {
    252251                                ?>
    253252                                <div class="grid-property-attribute grid-property-attribute-floorplan flex-element">
     
    271270
    272271                        <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>
    274273                        </div>
    275274                    </section>
     
    279278                     * Show the carousel for classic, cover or cinematic overlays
    280279                     */
    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 );
    283282                    }
    284 
    285                     do_action( 'after_slider', $property_id );
    286283
    287284                    /**
    288285                     * Show property description
    289286                     */
    290                     wppd_property_description( $property_id );
     287                    wppd_property_description( $wppd_property_id );
    291288
    292289                    /**
    293290                     * Show property floorplans
    294291                     */
    295                     wppd_property_floorplans( $property_id );
     292                    wppd_property_floorplans( $wppd_property_id );
    296293
    297294                    /**
    298295                     * Show property directions
    299296                     */
    300                     wppd_property_directions( $property_id );
     297                    wppd_property_directions( $wppd_property_id );
    301298
    302299                    /**
    303300                     * Show property gallery (flexbin)
    304301                     */
    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 !== '' ) {
    313310                            ?>
    314311                            <section class="grid-property-types-within">
     
    316313
    317314                                <?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   = [
    323320                                        'post_type'      => 'property',
    324321                                        'posts_per_page' => 1,
     
    326323                                            [
    327324                                                'key'     => 'importer_id',
    328                                                 'value'   => $linked_property,
     325                                                'value'   => $wppd_linked_property,
    329326                                                'compare' => '=',
    330327                                            ],
    331328                                        ],
    332329                                    ];
    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;
    338335                                        }
    339336                                    }
    340337                                }
    341338
    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 ) . '"]' );
    344341                                }
    345342                                ?>
     
    356353                        // get reusable gutenberg block:
    357354                        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 ) );
    361358                        } elseif ( is_active_sidebar( 'sidebar-widget' ) ) {
    362359                            dynamic_sidebar( 'sidebar-widget' );
    363360                        } 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 ) );
    365362                        }
    366363                        ?>
     
    372369                <section id="listing-map">
    373370                    <h4 class="listing-section-title">Location</h4>
    374                     <?php $location = $property_details['latitude'][0] . ',' . $property_details['longitude'][0]; ?>
    375371
    376372                    <?php if ( (string) get_option( 'map_provider' ) === 'osm' ) { ?>
     
    379375                        <script>
    380376                        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] ); ?>])
    384380                                .addTo(osmMap)
    385381                                .bindPopup('<?php echo esc_html( get_the_title() ); ?>');
     
    405401                $per_page = (int) get_option( 'flex_grid_size' );
    406402
    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               = [
    419415                    'post_type'      => 'property',
    420416                    'post_status'    => 'publish',
     
    429425                        [
    430426                            'key'     => 'price',
    431                             'value'   => [ $property_price_min, $property_price_max ],
     427                            'value'   => [ $wppd_property_price_min, $wppd_property_price_max ],
    432428                            'type'    => 'numeric',
    433429                            'compare' => 'BETWEEN',
     
    439435                            'taxonomy' => 'property_type',
    440436                            'field'    => 'id',
    441                             'terms'    => $custom_taxterms,
     437                            'terms'    => $wppd_custom_taxterms,
    442438                        ],
    443439                        [
    444440                            'taxonomy' => 'property_area',
    445441                            'field'    => 'slug',
    446                             'terms'    => [ $property_area ],
     442                            'terms'    => [ $wppd_property_area ],
    447443                            'operator' => 'IN',
    448444                        ],
     
    450446                    'post__not_in'   => [ $post->ID ],
    451447                ];
    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 ) {
    455451                    ?>
    456452                    <section class="property-grid">
     
    459455                        <div class="flex-container">
    460456                            <?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();
    464460                                    echo wp_kses_post( wp4pm_get_property_box( $post->ID ) );
    465461                                endwhile;
     
    478474}
    479475
    480 wp_reset_query();
     476wp_reset_postdata();
    481477
    482478get_footer();
  • property-drive/trunk/templates/template-parts.php

    r3209948 r3447995  
    11<?php
     2if ( ! defined( 'ABSPATH' ) ) {
     3    exit; // Exit if accessed directly
     4}
     5
    26/**
    37 * Display the property description.
     
    289293                $out     .= '<p><small>Share to social networks via the icons below.</small></p>
    290294                <p id="share-buttons">';
    291                     $out .= get_sharing_buttons( $propertyId );
     295                    $out .= wppd_get_sharing_buttons( $propertyId );
    292296                $out     .= '</p>
    293297            </div>
Note: See TracChangeset for help on using the changeset viewer.