API Docs for: 1.38.2
Show:

File: core/class_core.php

<?php
/**
 * WP-Property Core Framework
 *
 * Contains primary functions for setting up the framework of the plugin.
 *
 * @version 1.08
 * @author Usability Dynamics, Inc. <info@usabilitydynamics.com>
 * @package WP-Property
 * @subpackage Main
 */
class WPP_Core {

  /**
   * Highest-level function initialized on plugin load
   *
   * @since 1.11
   *
   */
  function WPP_Core() {
    global $wp_properties;

    //** Determine if memory limit is low and increase it */
    if ( (int) ini_get( 'memory_limit' ) < 128 ) {
      ini_set( 'memory_limit', '128M' );
    }

    //** Load premium features */
    WPP_F::load_premium();

    //** Modify request to change feed */
    add_filter( 'request', 'property_feed' );

    //** Check if Facebook tries to request site */
    add_action( 'init', array( 'WPP_F', 'check_facebook_tabs' ) );

    //** Hook in upper init */
    add_action( 'init', array( $this, 'init_upper' ), 0 );

    //** Hook in lower init */
    add_action( 'init', array( $this, 'init_lower' ), 100 );

    //** Setup template_redirect */
    add_action( "template_redirect", array( $this, 'template_redirect' ) );

    //** Pre-init action hook */
    do_action( 'wpp_pre_init' );

    //* set WPP capabilities */
    $this->set_capabilities();

    // Check settings data on accord with existing wp_properties data before option updates
    add_filter( 'wpp_settings_save', array( 'WPP_Core', 'check_wp_settings_data' ), 0, 2 );

  }

  /**
   * Called on init, as early as possible.
   *
   * @since 1.11
   * @uses $wp_properties WP-Property configuration array
   * @access public
   *
   */
  function init_upper() {
    global $wp_properties;

    //** Init action hook */
    do_action( 'wpp_init' );

    //** Load languages */
    load_plugin_textdomain( 'wpp', WPP_Path . false, 'wp-property/langs' );

    /** Making template-functions global but load after the premium features, giving the premium features priority. */
    include_once WPP_Templates . '/template-functions.php';

    //** Load settings into $wp_properties and save settings if nonce exists */
    WPP_F::settings_action();

    //** Set up our custom object and taxonomyies */
    WPP_F::register_post_type_and_taxonomies();

    //** Load all widgets and register widget areas */
    add_action( 'widgets_init', array( 'WPP_F', 'widgets_init' ) );

    //** Add metaboxes hook */
    add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );

  }

  /**
   * Secondary WPP Initialization ran towards the end of init()
   *
   * Loads things that we want make accessible for modification via other plugins.
   *
   * @since 1.31.0
   * @uses $wp_properties WP-Property configuration array
   * @access public
   *
   */
  function init_lower() {
    global $wp_properties;

    /** Ajax functions */
    add_action( 'wp_ajax_wpp_ajax_max_set_property_type', create_function( "", ' die(WPP_F::mass_set_property_type($_REQUEST["property_type"]));' ) );
    add_action( 'wp_ajax_wpp_ajax_property_query', create_function( "", ' $class = WPP_F::get_property(trim($_REQUEST["property_id"])); if($class) { echo "WPP_F::get_property() output: \n\n"; print_r($class); echo "\nAfter prepare_property_for_display() filter:\n\n"; print_r(prepare_property_for_display($class));  } else { echo __("No property found.","wpp"); } die();' ) );
    add_action( 'wp_ajax_wpp_ajax_image_query', create_function( "", ' $class = WPP_F::get_property_image_data($_REQUEST["image_id"]); if($class)  print_r($class); else echo __("No image found.","wpp"); die();' ) );
    add_action( 'wp_ajax_wpp_ajax_check_plugin_updates', create_function( "", '  echo WPP_F::check_plugin_updates(); die();' ) );
    add_action( 'wp_ajax_wpp_ajax_clear_cache', create_function( "", '  echo WPP_F::clear_cache(); die();' ) );
    add_action( 'wp_ajax_wpp_ajax_revalidate_all_addresses', create_function( "", '  echo WPP_F::revalidate_all_addresses(); die();' ) );
    add_action( 'wp_ajax_wpp_ajax_list_table', create_function( "", ' die(WPP_F::list_table());' ) );

    /** Ajax pagination for property_overview */
    add_action( "wp_ajax_wpp_property_overview_pagination", array( $this, "ajax_property_overview" ) );
    add_action( "wp_ajax_nopriv_wpp_property_overview_pagination", array( $this, "ajax_property_overview" ) );

    /** Localization */
    add_action( "wp_ajax_wpp_js_localization", array( __CLASS__, "localize_scripts" ) );
    add_action( "wp_ajax_nopriv_wpp_js_localization", array( __CLASS__, "localize_scripts" ) );

    add_filter( "manage_edit-property_sortable_columns", array( &$this, "sortable_columns" ) );
    add_filter( "manage_edit-property_columns", array( &$this, "edit_columns" ) );

    /** Called in setup_postdata().  We add property values here to make available in global $post variable on frontend */
    add_action( 'the_post', array( 'WPP_F', 'the_post' ) );

    add_action( "the_content", array( &$this, "the_content" ) );

    /** Admin interface init */
    add_action( "admin_init", array( &$this, "admin_init" ) );

    add_action( "admin_menu", array( &$this, 'admin_menu' ) );

    add_action( "post_submitbox_misc_actions", array( &$this, "post_submitbox_misc_actions" ) );
    add_action( 'save_post', array( $this, 'save_property' ) );

    //** Address revalidation @since 1.37.2 @author odokienko@UD */
    add_action( 'save_property', create_function( '$post_id, $postdata, $geo_data', 'WPP_F::revalidate_address($post_id, array("post_data"=>$postdata, "old_geo_data"=>$geo_data)); ' ), 0, 3 );

    add_action( 'before_delete_post', array( 'WPP_F', 'before_delete_post' ) );
    add_filter( 'post_updated_messages', array( 'WPP_Core', 'property_updated_messages' ), 5 );

    /** Fix toggale row actions -> get rid of "Quick Edit" on property rows */
    add_filter( 'page_row_actions', array( 'WPP_Core', 'property_row_actions' ), 0, 2 );

    /** Disables meta cache for property obejcts if enabled */
    add_action( 'pre_get_posts', array( 'WPP_F', 'pre_get_posts' ) );

    /** Fix 404 errors */
    add_filter( "parse_request", array( $this, "parse_request" ) );

    //** Determines if current request is for a child property */
    add_filter( "posts_results", array( 'WPP_F', "posts_results" ) );

    //** Hack. Used to avoid issues of some WPP capabilities */
    add_filter( 'current_screen', array( $this, 'current_screen' ) );

    //** Load admin header scripts */
    add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );

    //** Check premium feature availability */
    add_action( 'wpp_premium_feature_check', array( 'WPP_F', 'feature_check' ) );

    //** Contextual Help */
    add_action( 'wpp_contextual_help', array( $this, 'wpp_contextual_help' ) );

    //** Page loading handlers */
    add_action( 'load-property_page_all_properties', array( 'WPP_F', 'property_page_all_properties_load' ) );
    add_action( 'load-property_page_property_settings', array( 'WPP_F', 'property_page_property_settings_load' ) );

    add_filter( "manage_property_page_all_properties_columns", array( 'WPP_F', 'overview_columns' ) );
    add_filter( "wpp_overview_columns", array( 'WPP_F', 'custom_attribute_columns' ) );

    add_filter( "wpp_attribute_filter", array( 'WPP_F', 'attribute_filter' ), 10, 2 );

    //** Add custom image sizes */
    foreach ( $wp_properties[ 'image_sizes' ] as $image_name => $image_sizes ) {
      add_image_size( $image_name, $image_sizes[ 'width' ], $image_sizes[ 'height' ], true );
    }

    //** Determine if we are secure */
    $scheme = ( is_ssl() && !is_admin() ? 'https' : 'http' );

    //** Load early so plugins can use them as well */
    wp_register_script( 'wpp-localization', get_bloginfo( 'wpurl' ) . '/wp-admin/admin-ajax.php?action=wpp_js_localization', array(), WPP_Version );
    wp_localize_script( 'wpp-localization', 'wpp', array( 'instance' => $this->get_instance() ) );

    wp_register_script( 'wpp-jquery-fancybox', WPP_URL . 'third-party/fancybox/jquery.fancybox-1.3.4.pack.js', array( 'jquery', 'wpp-localization' ), '1.7.3' );
    wp_register_script( 'wpp-jquery-colorpicker', WPP_URL . 'third-party/colorpicker/colorpicker.js', array( 'jquery', 'wpp-localization' ) );
    wp_register_script( 'wpp-jquery-easing', WPP_URL . 'third-party/fancybox/jquery.easing-1.3.pack.js', array( 'jquery', 'wpp-localization' ), '1.7.3' );
    wp_register_script( 'wpp-jquery-ajaxupload', WPP_URL . 'js/fileuploader.js', array( 'jquery', 'wpp-localization' ) );
    wp_register_script( 'wp-property-admin-overview', WPP_URL . 'js/wp-property-admin-overview.js', array( 'jquery', 'wpp-localization' ), WPP_Version );
    wp_register_script( 'wp-property-admin-widgets', WPP_URL . 'js/wp-property-admin-widgets.js', array( 'jquery', 'wpp-localization' ), WPP_Version );
    wp_register_script( 'wp-property-backend-global', WPP_URL . 'js/wp-property-backend-global.js', array( 'jquery', 'wp-property-global', 'wpp-localization' ), WPP_Version );
    wp_register_script( 'wp-property-global', WPP_URL . 'js/wp-property-global.js', array( 'jquery', 'wpp-localization' ), WPP_Version );
    wp_register_script( 'jquery-cookie', WPP_URL . 'js/jquery.smookie.js', array( 'jquery', 'wpp-localization' ), '1.7.3' );

    if ( WPP_F::can_get_script( $scheme . '://maps.google.com/maps/api/js?sensor=true' ) ) {
      wp_register_script( 'google-maps', $scheme . '://maps.google.com/maps/api/js?sensor=true' );
    }

    wp_register_script( 'wpp-md5', WPP_URL . 'third-party/md5.js', array( 'wpp-localization' ), WPP_Version );
    wp_register_script( 'wpp-jquery-gmaps', WPP_URL . 'js/jquery.ui.map.min.js', array( 'google-maps', 'jquery-ui-core', 'jquery-ui-widget', 'wpp-localization' ) );
    wp_register_script( 'wpp-jquery-nivo-slider', WPP_URL . 'third-party/jquery.nivo.slider.pack.js', array( 'jquery', 'wpp-localization' ) );
    wp_register_script( 'wpp-jquery-address', WPP_URL . 'js/jquery.address-1.5.js', array( 'jquery', 'wpp-localization' ) );
    wp_register_script( 'wpp-jquery-scrollTo', WPP_URL . 'js/jquery.scrollTo-min.js', array( 'jquery', 'wpp-localization' ) );
    wp_register_script( 'wpp-jquery-validate', WPP_URL . 'js/jquery.validate.js', array( 'jquery', 'wpp-localization' ) );
    wp_register_script( 'wpp-jquery-number-format', WPP_URL . 'js/jquery.number.format.js', array( 'jquery', 'wpp-localization' ) );
    wp_register_script( 'wpp-jquery-data-tables', WPP_URL . "third-party/dataTables/jquery.dataTables.js", array( 'jquery', 'wpp-localization' ) );
    wp_register_script( 'wp-property-galleria', WPP_URL . 'third-party/galleria/galleria-1.2.5.js', array( 'jquery', 'wpp-localization' ) );

    wp_register_style( 'wpp-jquery-fancybox-css', WPP_URL . 'third-party/fancybox/jquery.fancybox-1.3.4.css' );
    wp_register_style( 'wpp-jquery-colorpicker-css', WPP_URL . 'third-party/colorpicker/colorpicker.css' );
    wp_register_style( 'jquery-ui', WPP_URL . 'css/jquery-ui.css' );
    wp_register_style( 'wpp-jquery-data-tables', WPP_URL . "css/wpp-data-tables.css" );

    /** Find and register stylesheet  */
    if ( file_exists( STYLESHEETPATH . '/wp-properties.css' ) ) {
      wp_register_style( 'wp-property-frontend', get_bloginfo( 'stylesheet_directory' ) . '/wp-properties.css', array(), WPP_Version );
    } elseif ( file_exists( STYLESHEETPATH . '/wp_properties.css' ) ) {
      wp_register_style( 'wp-property-frontend', get_bloginfo( 'stylesheet_directory' ) . '/wp_properties.css', array(), WPP_Version );
    } elseif ( file_exists( TEMPLATEPATH . '/wp-properties.css' ) ) {
      wp_register_style( 'wp-property-frontend', get_bloginfo( 'template_url' ) . '/wp-properties.css', array(), WPP_Version );
    } elseif ( file_exists( TEMPLATEPATH . '/wp_properties.css' ) ) {
      wp_register_style( 'wp-property-frontend', get_bloginfo( 'template_url' ) . '/wp_properties.css', array(), WPP_Version );
    } elseif ( file_exists( WPP_Templates . '/wp_properties.css' ) && $wp_properties[ 'configuration' ][ 'autoload_css' ] == 'true' ) {
      wp_register_style( 'wp-property-frontend', WPP_URL . 'templates/wp_properties.css', array(), WPP_Version );

      //** Find and register theme-specific style if a custom wp_properties.css does not exist in theme */
      if ( $wp_properties[ 'configuration' ][ 'do_not_load_theme_specific_css' ] != 'true' && WPP_F::has_theme_specific_stylesheet() ) {
        wp_register_style( 'wp-property-theme-specific', WPP_URL . "templates/theme-specific/" . get_option( 'template' ) . ".css", array( 'wp-property-frontend' ), WPP_Version );
      }
    }

    //** Find front-end JavaScript and register the script */
    if ( file_exists( STYLESHEETPATH . '/wp_properties.js' ) ) {
      wp_register_script( 'wp-property-frontend', get_bloginfo( 'stylesheet_directory' ) . '/wp_properties.js', array( 'jquery-ui-core', 'wpp-localization' ), WPP_Version, true );
    } elseif ( file_exists( TEMPLATEPATH . '/wp_properties.js' ) ) {
      wp_register_script( 'wp-property-frontend', get_bloginfo( 'template_url' ) . '/wp_properties.js', array( 'jquery-ui-core', 'wpp-localization' ), WPP_Version, true );
    } elseif ( file_exists( WPP_Templates . '/wp_properties.js' ) ) {
      wp_register_script( 'wp-property-frontend', WPP_URL . 'templates/wp_properties.js', array( 'jquery-ui-core', 'wpp-localization' ), WPP_Version, true );
    }

    //** Add troubleshoot log page */
    if ( isset( $wp_properties[ 'configuration' ][ 'show_ud_log' ] ) && $wp_properties[ 'configuration' ][ 'show_ud_log' ] == 'true' ) {
      WPP_F::add_log_page();
    }

    //** Modify admin body class */
    add_filter( 'admin_body_class', array( 'WPP_Core', 'admin_body_class' ), 5 );

    //** Modify Front-end property body class */
    add_filter( 'body_class', array( 'WPP_Core', 'properties_body_class' ) );

    add_filter( 'wp_get_attachment_link', array( 'WPP_F', 'wp_get_attachment_link' ), 10, 6 );

    /** Load all shortcodes */
    add_shortcode( 'property_overview', array( $this, 'shortcode_property_overview' ) );
    add_shortcode( 'property_search', array( $this, 'shortcode_property_search' ) );
    add_shortcode( 'featured_properties', array( $this, 'shortcode_featured_properties' ) );
    add_shortcode( 'property_map', array( $this, 'shortcode_property_map' ) );
    add_shortcode( 'property_attribute', array( $this, 'shortcode_property_attribute' ) );

    if ( !empty( $wp_properties[ 'alternative_shortcodes' ][ 'property_overview' ] ) ) {
      add_shortcode( "{$wp_properties[ 'alternative_shortcodes' ]['property_overview']}", array( $this, 'shortcode_property_overview' ) );
    }

    //** Make Property Featured Via AJAX */
    if ( isset( $_REQUEST[ '_wpnonce' ] ) ) {
      if ( wp_verify_nonce( $_REQUEST[ '_wpnonce' ], "wpp_make_featured_" . $_REQUEST[ 'post_id' ] ) ) {
        add_action( 'wp_ajax_wpp_make_featured', create_function( "", '  $post_id = $_REQUEST[post_id]; echo WPP_F::toggle_featured($post_id); die();' ) );
      }
    }

    //** Post-init action hook */
    do_action( 'wpp_post_init' );

  }

  /**
   * Register metaboxes.
   *
   * @global type $post
   * @global type $wpdb
   */
  function add_meta_boxes() {
    global $post, $wpdb;

    //** Add metabox for child properties */
    if ( $post->post_type == 'property' && $wpdb->get_var( "SELECT COUNT(ID) FROM {$wpdb->posts} WHERE post_parent = '{$post->ID}' AND post_status = 'publish' " ) ) {
      add_meta_box( 'wpp_property_children', __( 'Child Properties', 'wpp' ), array( 'WPP_UI', 'child_properties' ), 'property', 'side', 'high' );
    }
  }

  /**
   * Adds thumbnail feature to WP-Property pages
   *
   *
   * @todo Make sure only ran on property pages
   * @since 0.60
   *
   */
  static function after_setup_theme() {
    add_theme_support( 'post-thumbnails' );
  }

  /**
   * Adds "Settings" link to the plugin overview page
   *
   *
   * @since 0.60
   *
   */
  function plugin_action_links( $links, $file ) {

    if ( $file == 'wp-property/wp-property.php' ) {
      $settings_link = '<a href="' . admin_url( "edit.php?post_type=property&page=property_settings" ) . '">' . __( 'Settings', 'wpp' ) . '</a>';
      array_unshift( $links, $settings_link ); // before other links
    }
    return $links;
  }

  /**
   * Can enqueue scripts on specific pages, and print content into head
   *
   *
   * @uses $current_screen global variable
   * @since 0.53
   *
   */
  function admin_enqueue_scripts( $hook ) {
    global $current_screen, $wp_properties, $wpdb;

    switch ( $current_screen->id ) {

      //** Property Overview Page and Edit Property page */
      case 'property_page_all_properties':
        wp_enqueue_script( 'wp-property-backend-global' );
        wp_enqueue_script( 'wp-property-admin-overview' );
      case 'property':
        wp_enqueue_script( 'wp-property-global' );
        //** Enabldes fancybox js, css and loads overview scripts */
        wp_enqueue_script( 'post' );
        wp_enqueue_script( 'postbox' );
        wp_enqueue_script( 'wpp-jquery-fancybox' );
        wp_enqueue_script( 'wpp-jquery-data-tables' );
        wp_enqueue_style( 'wpp-jquery-fancybox-css' );
        wp_enqueue_style( 'wpp-jquery-data-tables' );

        //** Get width of overview table thumbnail, and set css */
        $thumbnail_attribs = WPP_F::image_sizes( $wp_properties[ 'configuration' ][ 'admin_ui' ][ 'overview_table_thumbnail_size' ] );
        $thumbnail_width = ( !empty( $thumbnail_attribs[ 'width' ] ) ? $thumbnail_attribs[ 'width' ] : false );
        if ( $thumbnail_width ) {
          ?>
          <style typ="text/css">
            #wp-list-table.wp-list-table .column-thumbnail {
              width: <?php echo $thumbnail_width + 20; ?>px;
            }

            #wp-list-table.wp-list-table td.column-thumbnail {
              text-align: right;
            }

            #wp-list-table.wp-list-table .column-type {
              width: 90px;
            }

            #wp-list-table.wp-list-table .column-menu_order {
              width: 50px;
            }

            #wp-list-table.wp-list-table td.column-menu_order {
              text-align: center;
            }

            #wp-list-table.wp-list-table .column-featured {
              width: 100px;
            }

            #wp-list-table.wp-list-table .check-column {
              width: 26px;
            }
          </style>
        <?php
        }

        break;

      //** Settings Page */
      case 'property_page_property_settings':
        wp_enqueue_script( 'wp-property-backend-global' );
        wp_enqueue_script( 'wp-property-global' );

        wp_enqueue_script( 'jquery' );
        wp_enqueue_script( 'jquery-ui-core' );
        wp_enqueue_script( 'jquery-ui-sortable' );
        wp_enqueue_script( 'wpp-jquery-colorpicker' );
        wp_enqueue_style( 'wpp-jquery-colorpicker-css' );
        break;

      //** Widgets Page */
      case 'widgets':
        wp_enqueue_script( 'wp-property-backend-global' );
        wp_enqueue_script( 'wp-property-global' );

        wp_enqueue_script( 'jquery-ui-core' );
        wp_enqueue_script( 'jquery-ui-sortable' );
        wp_enqueue_script( 'jquery-ui-tabs' );
        wp_enqueue_style( 'jquery-ui' );
        wp_enqueue_script( 'wp-property-admin-widgets' );
        break;

    }

    //** Automatically insert styles sheet if one exists with $current_screen->ID name */
    if ( file_exists( WPP_Path . "/css/{$current_screen->id}.css" ) ) {
      wp_enqueue_style( $current_screen->id . '-style', WPP_URL . "/css/{$current_screen->id}.css", array(), WPP_Version, 'screen' );
    }

    //** Automatically insert JS sheet if one exists with $current_screen->ID name */
    if ( file_exists( WPP_Path . "js/{$current_screen->id}.js" ) ) {
      wp_enqueue_script( $current_screen->id . '-js', WPP_URL . "js/{$current_screen->id}.js", array( 'jquery' ), WPP_Version, 'wp-property-backend-global' );
    }

    //** Enqueue CSS styles on all pages */
    if ( file_exists( WPP_Path . 'css/wp_properties_admin.css' ) ) {
      wp_register_style( 'wpp-admin-styles', WPP_URL . 'css/wp_properties_admin.css' );
      wp_enqueue_style( 'wpp-admin-styles' );
    }

  }

  /**
   * Sets up additional pages and loads their scripts
   *
   * @since 0.5
   *
   */
  function admin_menu() {
    global $wp_properties, $submenu;

    // Create property settings page
    $settings_page = add_submenu_page( 'edit.php?post_type=property', __( 'Settings', 'wpp' ), __( 'Settings', 'wpp' ), 'manage_wpp_settings', 'property_settings', create_function( '', 'global $wp_properties; include "ui/page_settings.php";' ) );
    $all_properties = add_submenu_page( 'edit.php?post_type=property', $wp_properties[ 'labels' ][ 'all_items' ], $wp_properties[ 'labels' ][ 'all_items' ], 'edit_wpp_properties', 'all_properties', create_function( '', 'global $wp_properties, $screen_layout_columns; include "ui/page_all_properties.php";' ) );

    /**
     * Next used to add custom submenu page 'All Properties' with Javascript dataTable
     *
     * @author Anton K
     */
    if ( !empty( $submenu[ 'edit.php?post_type=property' ] ) ) {

      //** Comment next line if you want to get back old Property list page. */
      array_shift( $submenu[ 'edit.php?post_type=property' ] );

      foreach ( $submenu[ 'edit.php?post_type=property' ] as $key => $page ) {
        if ( $page[ 2 ] == 'all_properties' ) {
          unset( $submenu[ 'edit.php?post_type=property' ][ $key ] );
          array_unshift( $submenu[ 'edit.php?post_type=property' ], $page );
        } elseif ( $page[ 2 ] == 'post-new.php?post_type=property' ) {
          //** Removes 'Add Property' from menu if user can not edit properties. peshkov@UD */
          if ( !current_user_can( 'edit_wpp_property' ) ) {
            unset( $submenu[ 'edit.php?post_type=property' ][ $key ] );
          }
        }
      }
    }

    do_action( 'wpp_admin_menu' );

    // Load jQuery UI Tabs and Cookie into settings page (settings_page_property_settings)
    add_action( 'admin_print_scripts-' . $settings_page, create_function( '', "wp_enqueue_script('jquery-ui-tabs');wp_enqueue_script('jquery-cookie');" ) );

  }

  /**
   * Modify admin body class on property pages for CSS
   *
   * @since 0.5
   */
  function admin_body_class( $content ) {
    global $current_screen;

    if ( $current_screen->id == 'edit-property' ) {
      return 'wp-list-table ';
    }

    if ( $current_screen->id == 'property' ) {
      return 'wpp_property_edit';
    }

  }

  /**
   * Fixed property pages being seen as 404 pages
   *
   * Ran on parse_request;
   *
   * WP handle_404() function decides if current request should be a 404 page
   * Marking the global variable $wp_query->is_search to true makes the function
   * assume that the request is a search.
   *
   * @param $query
   *
   * @since 0.5
   */
  function parse_request( $query ) {
    global $wp, $wp_query, $wp_properties, $wpdb;

    //** If we don't have permalinks, our base slug is always default */
    if ( get_option( 'permalink_structure' ) == '' ) {
      $wp_properties[ 'configuration' ][ 'base_slug' ] = 'property';
    }

    //** If we are displaying search results, we can assume this is the default property page */
    if ( is_array( $_REQUEST[ 'wpp_search' ] ) ) {

      if ( isset( $_POST[ 'wpp_search' ] ) ) {
        $query = '?' . http_build_query( array( 'wpp_search' => $_REQUEST[ 'wpp_search' ] ), '', '&' );
        wp_redirect( WPP_F::base_url( $wp_properties[ 'configuration' ][ 'base_slug' ] ) . $query );
        die();
      }

      $wp_query->wpp_root_property_page = true;
      $wp_query->wpp_search_page = true;
    }

    //** Determine if this is the Default Property Page */

    if ( isset( $wp_properties[ 'configuration' ][ 'base_slug' ] ) && $wp->request == $wp_properties[ 'configuration' ][ 'base_slug' ] ) {
      $wp_query->wpp_root_property_page = true;
    }

    if ( !empty( $wp_properties[ 'configuration' ][ 'base_slug' ] ) && $wp->query_string == "p=" . $wp_properties[ 'configuration' ][ 'base_slug' ] ) {
      $wp_query->wpp_root_property_page = true;
    }

    if ( isset( $query->query_vars[ 'name' ] ) && $query->query_vars[ 'name' ] == $wp_properties[ 'configuration' ][ 'base_slug' ] ) {
      $wp_query->wpp_root_property_page = true;
    }

    if ( isset( $query->query_vars[ 'pagename' ] ) && $query->query_vars[ 'pagename' ] == $wp_properties[ 'configuration' ][ 'base_slug' ] ) {
      $wp_query->wpp_root_property_page = true;
    }

    if ( isset( $query->query_vars[ 'category_name' ] ) && $query->query_vars[ 'category_name' ] == $wp_properties[ 'configuration' ][ 'base_slug' ] ) {
      $wp_query->wpp_root_property_page = true;
    }

    //** If this is a the root property page, and the Dynamic Default Property page is used */
    if ( $wp_query->wpp_root_property_page && $wp_properties[ 'configuration' ][ 'base_slug' ] == 'property' ) {
      $wp_query->wpp_default_property_page = true;

      WPP_F::console_log( 'Overriding default 404 page status.' );

      /** Set to override the 404 status */
      add_action( 'wp', create_function( '', 'status_header( 200 );' ) );

      //** Prevent is_404() in template files from returning true */
      add_action( 'template_redirect', create_function( '', ' global $wp_query; $wp_query->is_404 = false;' ), 0, 10 );
    }

    if ( $wp_query->wpp_search_page ) {
      $wpp_pages[ ] = 'Search Page';
    }

    if ( $wp_query->wpp_default_property_page ) {
      $wpp_pages[ ] = 'Default Property Page';
    }

    if ( $wp_query->wpp_root_property_page ) {
      $wpp_pages[ ] = 'Root Property Page.';
    }

    if ( is_array( $wpp_pages ) ) {
      WPP_F::console_log( 'WPP_F::parse_request() ran, determined that request is for: ' . implode( ', ', $wpp_pages ) );
    }

  }

  /**
   * Modifies post content
   *
   * @since 1.04
   *
   */
  function the_content( $content ) {
    global $post, $wp_properties, $wp_query;

    if ( !isset( $wp_query->is_property_overview ) ) {
      return $content;
    }

    //** Handle automatic PO inserting for non-search root page */
    if ( !$wp_query->wpp_search_page && $wp_query->wpp_root_property_page && $wp_properties[ 'configuration' ][ 'automatically_insert_overview' ] == 'true' ) {
      WPP_F::console_log( 'Automatically inserted property overview shortcode into page content.' );
      return WPP_Core::shortcode_property_overview();
    }

    //** Handle automatic PO inserting for search pages */
    if ( $wp_query->wpp_search_page && $wp_properties[ 'configuration' ][ 'do_not_override_search_result_page' ] != 'true' ) {
      WPP_F::console_log( 'Automatically inserted property overview shortcode into search page content.' );
      return WPP_Core::shortcode_property_overview();
    }

    return $content;
  }

  /**
   * Hooks into save_post function and saves additional property data
   *
   *
   * @todo Add some sort of custom capability so not only admins can make properties as featured. i.e. Agents can make their own properties featured.
   * @since 1.04
   *
   */
  function save_property( $post_id ) {
    global $wp_properties, $wp_version;

    $_wpnonce = ( version_compare( $wp_version, '3.5', '>=' ) ? 'update-post_' : 'update-property_' ) . $post_id;
    if ( !wp_verify_nonce( $_POST[ '_wpnonce' ], $_wpnonce ) || $_POST[ 'post_type' ] !== 'property' ) {
      return $post_id;
    }

    //* Delete cache files of search values for search widget's form */
    $directory = WPP_Path . 'cache/searchwidget';

    if ( is_dir( $directory ) ) {
      $dir = opendir( $directory );
      while ( ( $cachefile = readdir( $dir ) ) ) {
        if ( is_file( $directory . "/" . $cachefile ) ) {
          unlink( $directory . "/" . $cachefile );
        }
      }
    }

    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
      return $post_id;
    }

    $update_data = $_REQUEST[ 'wpp_data' ][ 'meta' ];

    //** Neccessary meta data which is required by Supermap Premium Feature. Should be always set even the Supermap disabled. peshkov@UD */
    if ( empty( $_REQUEST[ 'exclude_from_supermap' ] ) ) {
      if ( !metadata_exists( 'post', $post_id, 'exclude_from_supermap' ) ) {
        $update_data[ 'exclude_from_supermap' ] = 'false';
      }
    }

    if ( (float) $update_data[ 'latitude' ] == 0 ) $update_data[ 'latitude' ] = '';
    if ( (float) $update_data[ 'longitude' ] == 0 ) $update_data[ 'longitude' ] = '';

    /* get old coordinates and location */
    $old_lat = get_post_meta( $post_id, 'latitude', true );
    $old_lng = get_post_meta( $post_id, 'longitude', true );
    $geo_data = array(
      'old_coordinates' => ( ( empty( $old_lat ) ) || ( empty( $old_lng ) ) ) ? "" : array( 'lat' => $old_lat, 'lng' => $old_lng ),
      'old_location' => ( !empty( $wp_properties[ 'configuration' ][ 'address_attribute' ] ) ) ? get_post_meta( $post_id, $wp_properties[ 'configuration' ][ 'address_attribute' ], true ) : ''
    );

    foreach ( $update_data as $meta_key => $meta_value ) {
      $attribute_data = WPP_F::get_attribute_data( $meta_key );

      //* Cleans the user input */
      $meta_value = WPP_F::encode_mysql_input( $meta_value, $meta_key );

      //* Only admins can mark properties as featured. */
      if ( $meta_key == 'featured' && !current_user_can( 'manage_options' ) ) {
        //** But be sure that meta 'featured' exists at all */
        if ( !metadata_exists( 'post', $post_id, $meta_key ) ) {
          $meta_value = 'false';
        } else {
          continue;
        }
      }

      //* Remove certain characters */

      if ( $attribute_data[ 'currency' ] || $attribute_data[ 'numeric' ] ) {
        $meta_value = str_replace( array( "$", "," ), '', $meta_value );
      }

      //* Overwrite old post meta allowing only one value */
      delete_post_meta( $post_id, $meta_key );
      add_post_meta( $post_id, $meta_key, $meta_value );
    }

    //* Check if property has children */
    $children = get_children( "post_parent=$post_id&post_type=property" );

    //* Write any data to children properties that are supposed to inherit things */
    if ( count( $children ) > 0 ) {
      //* 1) Go through all children */
      foreach ( $children as $child_id => $child_data ) {
        //* Determine child property_type */
        $child_property_type = get_post_meta( $child_id, 'property_type', true );
        //* Check if child's property type has inheritence rules, and if meta_key exists in inheritance array */
        if ( is_array( $wp_properties[ 'property_inheritance' ][ $child_property_type ] ) ) {
          foreach ( $wp_properties[ 'property_inheritance' ][ $child_property_type ] as $i_meta_key ) {
            $parent_meta_value = get_post_meta( $post_id, $i_meta_key, true );
            //* inheritance rule exists for this property_type for this meta_key */
            update_post_meta( $child_id, $i_meta_key, $parent_meta_value );
          }
        }
      }
    }

    WPP_F::maybe_set_gpid( $post_id );

    if ( isset( $_REQUEST[ 'parent_id' ] ) ) {
      $_REQUEST[ 'parent_id' ] = WPP_F::update_parent_id( $_REQUEST[ 'parent_id' ], $post_id );
    }

    do_action( 'save_property', $post_id, $_REQUEST, $geo_data );

    return true;
  }

  /**
   * Inserts content into the "Publish" metabox on property pages
   *
   * @since 1.04
   *
   */
  function post_submitbox_misc_actions() {
    global $post, $wp_properties;

    if ( $post->post_type == 'property' ) {

      ?>
      <div class="misc-pub-section ">

        <ul>
          <li><?php _e( 'Menu Sort Order:', 'wpp' ) ?> <?php echo WPP_F::input( "name=menu_order&special=size=4", $post->menu_order ); ?></li>

          <?php if ( current_user_can( 'manage_options' ) && $wp_properties[ 'configuration' ][ 'do_not_use' ][ 'featured' ] != 'true' ) { ?>
            <li><?php echo WPP_F::checkbox( "name=wpp_data[meta][featured]&label=" . __( 'Display in featured listings.', 'wpp' ), get_post_meta( $post->ID, 'featured', true ) ); ?></li>
          <?php } ?>

          <?php do_action( 'wpp_publish_box_options' ); ?>
        </ul>

      </div>
    <?php

    }

    return;

  }

  /**
   * Removes "quick edit" link on property type objects
   *
   * Called in via page_row_actions filter
   *
   * @since 0.5
   *
   */
  function property_row_actions( $actions, $post ) {
    if ( $post->post_type != 'property' )
      return $actions;

    unset( $actions[ 'inline' ] );

    return $actions;
  }

  /**
   * Adds property-relevant messages to the property post type object
   *
   *
   * @since 0.5
   *
   */
  function property_updated_messages( $messages ) {
    global $post_id, $post;

    $messages[ 'property' ] = array(
      0 => '', // Unused. Messages start at index 1.
      1 => sprintf( __( 'Property updated. <a href="%s">view property</a>', 'wpp' ), esc_url( get_permalink( $post_id ) ) ),
      2 => __( 'Custom field updated.', 'wpp' ),
      3 => __( 'Custom field deleted.', 'wpp' ),
      4 => __( 'Property updated.', 'wpp' ),
      /* translators: %s: date and time of the revision */
      5 => isset( $_GET[ 'revision' ] ) ? sprintf( __( 'Property restored to revision from %s', 'wpp' ), wp_post_revision_title( (int) $_GET[ 'revision' ], false ) ) : false,
      6 => sprintf( __( 'Property published. <a href="%s">View property</a>', 'wpp' ), esc_url( get_permalink( $post_id ) ) ),
      7 => __( 'Property saved.', 'wpp' ),
      8 => sprintf( __( 'Property submitted. <a target="_blank" href="%s">Preview property</a>', 'wpp' ), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_id ) ) ) ),
      9 => sprintf( __( 'Property scheduled for: <strong>%1$s</strong>. <a target="_blank" href="%2$s">Preview property</a>', 'wpp' ),
        // translators: Publish box date format, see http://php.net/date
        date_i18n( __( 'M j, Y @ G:i', 'wpp' ), strtotime( $post->post_date ) ), esc_url( get_permalink( $post_id ) ) ),
      10 => sprintf( __( 'Property draft updated. <a target="_blank" href="%s">Preview property</a>', 'wpp' ), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_id ) ) ) ),
    );

    $messages = apply_filters( 'wpp_updated_messages', $messages );

    return $messages;
  }

  /**
   * Sets up property-type columns
   *
   * @since 0.54
   * @uses $wp_properties WP-Property configuration array
   * @access public
   *
   */
  function edit_columns( $columns ) {
    global $wp_properties;

    unset( $columns );

    $columns[ 'cb' ] = "<input type=\"checkbox\" />";
    $columns[ 'title' ] = __( 'Title', 'wpp' );
    $columns[ 'property_type' ] = __( 'Type', 'wpp' );

    if ( is_array( $wp_properties[ 'property_stats' ] ) ) {
      foreach ( $wp_properties[ 'property_stats' ] as $slug => $title )
        $columns[ $slug ] = $title;
    } else {
      $columns = $columns;
    }

    $columns[ 'city' ] = __( 'City', 'wpp' );
    $columns[ 'overview' ] = __( 'Overview', 'wpp' );
    $columns[ 'featured' ] = __( 'Featured', 'wpp' );
    $columns[ 'menu_order' ] = __( 'Order', 'wpp' );
    $columns[ 'thumbnail' ] = __( 'Thumbnail', 'wpp' );

    $columns = apply_filters( 'wpp_admin_overview_columns', $columns );
    //
    return $columns;
  }

  /**
   * Sets up sortable columns columns
   *
   * @since 1.08
   *
   */
  function sortable_columns( $columns ) {
    global $wp_properties;

    $columns[ 'type' ] = 'type';
    $columns[ 'featured' ] = 'featured';

    if ( is_array( $wp_properties[ 'property_stats' ] ) ) {
      foreach ( $wp_properties[ 'property_stats' ] as $slug => $title )
        $columns[ $slug ] = $slug;
    }

    $columns = apply_filters( 'wpp_admin_sortable_columns', $columns );

    return $columns;
  }

  /**
   * Performs front-end pre-header functionality
   *
   * This function is not called on amdin side
   * Loads conditional CSS styles
   *
   * @since 1.11
   */
  function template_redirect() {
    global $post, $property, $wp_query, $wp_properties, $wp_styles, $wpp_query, $wp_taxonomies;

    //** Load global wp-property script on all frontend pages */
    wp_enqueue_script( 'wp-property-global' );

    //** Load essential styles that are used in widgets */
    wp_enqueue_style( 'wp-property-frontend' );
    wp_enqueue_style( 'wp-property-theme-specific' );

    //** Load non-essential scripts and styles if option is enabled to load them globally */
    if ( $wp_properties[ 'configuration' ][ 'load_scripts_everywhere' ] == 'true' ) {
      WPP_F::console_log( 'Loading WP-Property scripts globally.' );
      WPP_F::load_assets( array( 'single', 'overview' ) );
    }

    if ( $wp_properties[ 'configuration' ][ 'do_not_enable_text_widget_shortcodes' ] != 'true' ) {
      add_filter( 'widget_text', 'do_shortcode' );
    }

    do_action( 'wpp_template_redirect' );

    //** Handle single property page previews */
    if ( !empty( $wp_query->query_vars[ 'preview' ] ) && $post->post_type == "property" && $post->post_status == "publish" ) {
      wp_redirect( get_permalink( $post->ID ) );
      die();
    }

    /*
      (count($wp_query->posts) < 2) added post 1.31.1 release to avoid
      taxonomy archives from being broken by single property pages
    */
    if ( count( $wp_query->posts ) < 2 && ( $post->post_type == "property" || $wp_query->is_child_property ) ) {
      $wp_query->single_property_page = true;

      //** This is a hack and should be done better */
      if ( !$post ) {
        $post = get_post( $wp_query->queried_object_id );
        $wp_query->posts[ 0 ] = $post;
        $wp_query->post = $post;
      }
    }

    //** Monitor taxonomy archive queries */
    if ( is_tax() && in_array( $wp_query->query_vars[ 'taxonomy' ], array_keys( (array) $wp_taxonomies ) ) ) {
      //** Once get_properties(); can accept taxonomy searches, we can inject a search request in here */
    }

    //** If viewing root property page that is the default dynamic page. */
    if ( $wp_query->wpp_default_property_page ) {
      $wp_query->is_property_overview = true;
    }

    //** If this is the root page with a manually inserted shortcode, or any page with a PO shortcode */
    if ( strpos( $post->post_content, "property_overview" ) ) {
      $wp_query->is_property_overview = true;
    }

    //** If this is the root page and the shortcode is automatically inserted */
    if ( $wp_query->wpp_root_property_page && $wp_properties[ 'configuration' ][ 'automatically_insert_overview' ] == 'true' ) {
      $wp_query->is_property_overview = true;
    }

    //** If search result page, and system not explicitly configured to not include PO on search result page automatically */
    if ( $wp_query->wpp_search_page && $wp_properties[ 'configuration' ][ 'do_not_override_search_result_page' ] != 'true' ) {
      $wp_query->is_property_overview = true;
    }

    //** Scripts and styles to load on all overview and signle listing pages */
    if ( $wp_query->single_property_page || $wp_query->is_property_overview ) {

      WPP_F::console_log( 'Including scripts for all single and overview property pages.' );

      WPP_F::load_assets( array( 'single', 'overview' ) );

      // Check for and load conditional browser styles
      $conditional_styles = apply_filters( 'wpp_conditional_style_slugs', array( 'IE', 'IE 7', 'msie' ) );

      foreach ( $conditional_styles as $type ) {

        // Fix slug for URL
        $url_slug = strtolower( str_replace( " ", "_", $type ) );

        if ( file_exists( STYLESHEETPATH . "/wp_properties-{$url_slug}.css" ) ) {
          wp_register_style( 'wp-property-frontend-' . $url_slug, get_bloginfo( 'stylesheet_directory' ) . "/wp_properties-{$url_slug}.css", array( 'wp-property-frontend' ), '1.13' );
        } elseif ( file_exists( TEMPLATEPATH . "/wp_properties-{$url_slug}.css" ) ) {
          wp_register_style( 'wp-property-frontend-' . $url_slug, get_bloginfo( 'template_url' ) . "/wp_properties-{$url_slug}.css", array( 'wp-property-frontend' ), '1.13' );
        } elseif ( file_exists( WPP_Templates . "/wp_properties-{$url_slug}.css" ) && $wp_properties[ 'configuration' ][ 'autoload_css' ] == 'true' ) {
          wp_register_style( 'wp-property-frontend-' . $url_slug, WPP_URL . "templates/wp_properties-{$url_slug}.css", array( 'wp-property-frontend' ), WPP_Version );
        }
        // Mark every style as conditional
        $wp_styles->add_data( 'wp-property-frontend-' . $url_slug, 'conditional', $type );
        wp_enqueue_style( 'wp-property-frontend-' . $url_slug );

      }

    }

    //** Scripts loaded only on single property pages */
    if ( $wp_query->single_property_page && !post_password_required( $post ) ) {

      WPP_F::console_log( 'Including scripts for all single property pages.' );

      WPP_F::load_assets( array( 'single' ) );

      do_action( 'template_redirect_single_property' );

      add_action( 'wp_head', create_function( '', "do_action('wp_head_single_property'); " ) );

      $property = WPP_F::get_property( $post->ID, "load_gallery=true" );

      $property = prepare_property_for_display( $property );

      $type = $property[ 'property_type' ];

      //** Make certain variables available to be used within the single listing page */
      $single_page_vars = apply_filters( 'wpp_property_page_vars', array(
        'property' => $property,
        'wp_properties' => $wp_properties
      ) );

      //** By merging our extra variables into $wp_query->query_vars they will be extracted in load_template() */
      if ( is_array( $single_page_vars ) ) {
        $wp_query->query_vars = array_merge( $wp_query->query_vars, $single_page_vars );
      }

      $template_found = WPP_F::get_template_part( array(
        "property-{$type}",
        "property",
      ), array( WPP_Templates ) );

      //** Load the first found template */
      if ( $template_found ) {
        WPP_F::console_log( 'Found single property page template:' . $template_found );
        load_template( $template_found );
        die();
      }

    }

    //** Current requests includes a property overview.  PO may be via shortcode, search result, or due to this being the Default Dynamic Property page */
    if ( $wp_query->is_property_overview ) {

      WPP_F::console_log( 'Including scripts for all property overview pages.' );

      if ( $wp_query->wpp_default_property_page ) {
        WPP_F::console_log( 'Dynamic Default Property page detected, will load custom template.' );
      } else {
        WPP_F::console_log( 'Custom Default Property page detected, property overview content may be rendered via shortcode.' );
      }

      //** Make certain variables available to be used within the single listing page */
      $overview_page_vars = apply_filters( 'wpp_overview_page_vars', array(
        'wp_properties' => $wp_properties,
        'wpp_query' => $wpp_query
      ) );

      //** By merging our extra variables into $wp_query->query_vars they will be extracted in load_template() */
      if ( is_array( $overview_page_vars ) ) {
        $wp_query->query_vars = array_merge( $wp_query->query_vars, $overview_page_vars );
      }

      do_action( 'template_redirect_property_overview' );

      add_action( 'wp_head', create_function( '', "do_action('wp_head_property_overview'); " ) );

      //** If using Dynamic Property Root page, we must load a template */
      if ( $wp_query->wpp_default_property_page ) {

        //** Unset any post that may have been found based on query */
        $post = false;

        $template_found = WPP_F::get_template_part( array(
          "property-search-result",
          "property-overview-page",
        ), array( WPP_Templates ) );

        //** Load the first found template */
        if ( $template_found ) {
          WPP_F::console_log( 'Found Default property overview page template:' . $template_found );
          load_template( $template_found );
          die();
        }

      }

    }

    do_action( 'wpp_template_redirect_post_scripts' );

  }

  /**
   * Runs pre-header functions on admin-side only
   *
   * Checks if plugin has been updated.
   *
   * @since 1.10
   *
   */
  function admin_init() {
    global $wp_properties, $post;

    WPP_F::fix_screen_options();

    // Plug page actions -> Add Settings Link to plugin overview page
    add_filter( 'plugin_action_links', array( 'WPP_Core', 'plugin_action_links' ), 10, 2 );

    //* Adds metabox 'General Information' to Property Edit Page */
    add_meta_box( 'wpp_property_meta', __( 'General Information', 'wpp' ), array( 'WPP_UI', 'metabox_meta' ), 'property', 'normal', 'high' );
    //* Adds 'Group' metaboxes to Property Edit Page */
    if ( !empty( $wp_properties[ 'property_groups' ] ) ) {
      foreach ( $wp_properties[ 'property_groups' ] as $slug => $group ) {
        //* There is no sense to add metabox if no one attribute assigned to group */
        if ( !in_array( $slug, $wp_properties[ 'property_stats_groups' ] ) ) {
          continue;
        }
        //* Determine if Group name is empty we add 'NO NAME', other way metabox will not be added */
        if ( empty( $group[ 'name' ] ) ) {
          $group[ 'name' ] = __( 'NO NAME', 'wpp' );
        }
        add_meta_box( $slug, __( $group[ 'name' ], 'wpp' ), array( 'WPP_UI', 'metabox_meta' ), 'property', 'normal', 'high', array( 'group' => $slug ) );
      }
    }

    add_meta_box( 'propetry_filter', $wp_properties[ 'labels' ][ 'name' ] . ' ' . __( 'Search', 'wpp' ), array( 'WPP_UI', 'metabox_property_filter' ), 'property_page_all_properties', 'normal' );

    // Add metaboxes
    do_action( 'wpp_metaboxes' );

    WPP_F::manual_activation();

    // Download backup of configuration
    if ( $_REQUEST[ 'page' ] == 'property_settings'
      && $_REQUEST[ 'wpp_action' ] == 'download-wpp-backup'
      && wp_verify_nonce( $_REQUEST[ '_wpnonce' ], 'download-wpp-backup' )
    ) {
      global $wp_properties;

      $sitename = sanitize_key( get_bloginfo( 'name' ) );
      $filename = $sitename . '-wp-property.' . date( 'Y-m-d' ) . '.txt';

      header( "Cache-Control: public" );
      header( "Content-Description: File Transfer" );
      header( "Content-Disposition: attachment; filename=$filename" );
      header( "Content-Transfer-Encoding: binary" );
      header( 'Content-Type: text/plain; charset=' . get_option( 'blog_charset' ), true );

      echo json_encode( $wp_properties );

      die();
    }
  }

  /**
   * Displays featured properties
   *
   * Performs searching/filtering functions, provides template with $properties file
   * Retirms html content to be displayed after location attribute on property edit page
   *
   * @todo Consider making this function depend on shortcode_property_overview() more so pagination and sorting functions work.
   *
   * @since 0.60
   *
   * @param string $listing_id Listing ID must be passed
   *
   * @uses WPP_F::get_properties()
   *
   */
  function shortcode_featured_properties( $atts = false ) {
    global $wp_properties, $wpp_query, $post;

    $default_property_type = WPP_F::get_most_common_property_type();

    if ( !$atts ) {
      $atts = array();
    }

    $defaults = array(
      'property_type' => '',
      'type' => '',
      'class' => 'shortcode_featured_properties',
      'per_page' => '6',
      'sorter_type' => 'none',
      'show_children' => 'false',
      'hide_count' => true,
      'fancybox_preview' => 'false',
      'bottom_pagination_flag' => 'false',
      'pagination' => 'off',
      'stats' => '',
      'thumbnail_size' => 'thumbnail'
    );

    $args = array_merge( $defaults, $atts );

    //** Using "image_type" is obsolete */
    if ( $args[ 'thumbnail_size' ] == $defaults[ 'thumbnail_size' ] && !empty( $args[ 'image_type' ] ) ) {
      $args[ 'thumbnail_size' ] = $args[ 'image_type' ];
    }

    //** Using "type" is obsolete. If property_type is not set, but type is, we set property_type from type */
    if ( !empty( $args[ 'type' ] ) && empty( $args[ 'property_type' ] ) ) {
      $args[ 'property_type' ] = $args[ 'type' ];
    }

    if ( empty( $args[ 'property_type' ] ) ) {
      $args[ 'property_type' ] = $default_property_type;
    }

    // Convert shortcode multi-property-type string to array
    if ( !empty( $args[ 'stats' ] ) ) {

      if ( strpos( $args[ 'stats' ], "," ) ) {
        $args[ 'stats' ] = explode( ",", $args[ 'stats' ] );
      }

      if ( !is_array( $args[ 'stats' ] ) ) {
        $args[ 'stats' ] = array( $args[ 'stats' ] );
      }

      foreach ( $args[ 'stats' ] as $key => $stat ) {
        $args[ 'stats' ][ $key ] = trim( $stat );
      }

    }

    $args[ 'disable_wrapper' ] = 'true';
    $args[ 'featured' ] = 'true';
    $args[ 'template' ] = 'featured-shortcode';

    unset( $args[ 'image_type' ] );
    unset( $args[ 'type' ] );

    $result = WPP_Core::shortcode_property_overview( $args );

    return $result;
  }

  /**
   * Returns the property search widget
   *
   *
   * @since 1.04
   *
   */
  function shortcode_property_search( $atts = "" ) {
    global $post, $wp_properties;

    extract( shortcode_atts( array(
      'searchable_attributes' => '',
      'searchable_property_types' => '',
      'pagination' => 'on',
      'group_attributes' => 'off',
      'per_page' => '10'
    ), $atts ) );

    if ( empty( $searchable_attributes ) ) {

      //** get first 3 attributes to prevent people from accidentally loading them all (long query) */
      $searchable_attributes = array_slice( $wp_properties[ 'searchable_attributes' ], 0, 5 );

    } else {
      $searchable_attributes = explode( ",", $searchable_attributes );
    }

    $searchable_attributes = array_unique( $searchable_attributes );

    if ( empty( $searchable_property_types ) ) {
      $searchable_property_types = $wp_properties[ 'searchable_property_types' ];
    } else {
      $searchable_property_types = explode( ",", $searchable_property_types );
    }

    $widget_id = $post->ID . "_search";

    ob_start();
    echo '<div class="wpp_shortcode_search">';

    $search_args[ 'searchable_attributes' ] = $searchable_attributes;
    $search_args[ 'searchable_property_types' ] = $searchable_property_types;
    $search_args[ 'group_attributes' ] = ( $group_attributes == 'on' || $group_attributes == 'true' ? true : false );
    $search_args[ 'per_page' ] = $per_page;
    $search_args[ 'pagination' ] = $pagination;
    $search_args[ 'instance_id' ] = $widget_id;

    draw_property_search_form( $search_args );

    echo "</div>";
    $content = ob_get_contents();
    ob_end_clean();

    return $content;

  }

  /**
   * Displays property overview
   *
   * Performs searching/filtering functions, provides template with $properties file
   * Retirms html content to be displayed after location attribute on property edit page
   *
   * @since 1.081
   *
   * @param string $listing_id Listing ID must be passed
   *
   * @return string $result
   *
   * @uses WPP_F::get_properties()
   *
   */
  function shortcode_property_overview( $atts = "" ) {
    global $wp_properties, $wpp_query, $property, $post, $wp_query;

    $atts = wp_parse_args( $atts, array(
      'strict_search' => 'false'
    ) );

    WPP_F::force_script_inclusion( 'jquery-ui-widget' );
    WPP_F::force_script_inclusion( 'jquery-ui-mouse' );
    WPP_F::force_script_inclusion( 'jquery-ui-slider' );
    WPP_F::force_script_inclusion( 'wpp-jquery-address' );
    WPP_F::force_script_inclusion( 'wpp-jquery-scrollTo' );
    WPP_F::force_script_inclusion( 'wpp-jquery-fancybox' );
    WPP_F::force_script_inclusion( 'wp-property-frontend' );

    //** Load all queriable attributes **/
    foreach ( WPP_F::get_queryable_keys() as $key ) {
      //** This needs to be done because a key has to exist in the $deafult array for shortcode_atts() to load passed value */
      $queryable_keys[ $key ] = false;
    }

    //** Allow the shorthand of "type" as long as there is not a custom attribute of "type". If "type" does exist as an attribute, then users need to use the full "property_type" query tag. **/
    if ( !array_key_exists( 'type', $queryable_keys ) && ( is_array( $atts ) && array_key_exists( 'type', $atts ) ) ) {
      $atts[ 'property_type' ] = $atts[ 'type' ];
      unset( $atts[ 'type' ] );
    }

    //** Get ALL allowed attributes that may be passed via shortcode (to include property attributes) */
    $defaults[ 'show_children' ] = ( isset( $wp_properties[ 'configuration' ][ 'property_overview' ][ 'show_children' ] ) ? $wp_properties[ 'configuration' ][ 'property_overview' ][ 'show_children' ] : 'true' );
    $defaults[ 'child_properties_title' ] = __( 'Floor plans at location:', 'wpp' );
    $defaults[ 'fancybox_preview' ] = $wp_properties[ 'configuration' ][ 'property_overview' ][ 'fancybox_preview' ];
    $defaults[ 'bottom_pagination_flag' ] = ( $wp_properties[ 'configuration' ][ 'bottom_insert_pagenation' ] == 'true' ? true : false );
    $defaults[ 'thumbnail_size' ] = $wp_properties[ 'configuration' ][ 'property_overview' ][ 'thumbnail_size' ];
    $defaults[ 'sort_by_text' ] = __( 'Sort By:', 'wpp' );
    $defaults[ 'sort_by' ] = 'post_date';
    $defaults[ 'sort_order' ] = 'DESC';
    $defaults[ 'template' ] = false;
    $defaults[ 'ajax_call' ] = false;
    $defaults[ 'disable_wrapper' ] = false;
    $defaults[ 'sorter_type' ] = 'buttons';
    $defaults[ 'pagination' ] = 'on';
    $defaults[ 'hide_count' ] = false;
    $defaults[ 'per_page' ] = 10;
    $defaults[ 'starting_row' ] = 0;
    $defaults[ 'unique_hash' ] = rand( 10000, 99900 );
    $defaults[ 'detail_button' ] = false;
    $defaults[ 'stats' ] = '';
    $defaults[ 'class' ] = 'wpp_property_overview_shortcode';
    $defaults[ 'in_new_window' ] = false;

    $defaults = apply_filters( 'shortcode_property_overview_allowed_args', $defaults, $atts );

    //** We add # to value which says that we don't want to use LIKE in SQL query for searching this value. */
    if ( $atts[ 'strict_search' ] == 'true' ) {
      foreach ( $atts as $key => $val ) {
        if ( isset( $wp_properties[ 'property_stats' ][ $key ] ) && !key_exists( $key, $defaults ) && $key != 'property_type' ) {
          if ( substr_count( $val, ',' ) || substr_count( $val, '&ndash;' ) || substr_count( $val, '--' ) ) {
            continue;
          }
          $atts[ $key ] = '#' . $val . '#';
        }
      }
    }

    if ( !empty( $atts[ 'ajax_call' ] ) ) {
      //** If AJAX call then the passed args have all the data we need */
      $wpp_query = $atts;

      //* Fix ajax data. Boolean value false is returned as string 'false'. */
      foreach ( $wpp_query as $key => $value ) {
        if ( $value == 'false' ) {
          $wpp_query[ $key ] = false;
        }
      }

      $wpp_query[ 'ajax_call' ] = true;

      //** Everything stays the same except for sort order and page */
      $wpp_query[ 'starting_row' ] = ( ( $wpp_query[ 'requested_page' ] - 1 ) * $wpp_query[ 'per_page' ] );

      //** Figure out current page */
      $wpp_query[ 'current_page' ] = $wpp_query[ 'requested_page' ];

    } else {
      /** Determine if fancybox style is included */
      WPP_F::force_style_inclusion( 'wpp-jquery-fancybox-css' );

      //** Merge defaults with passed arguments */
      $wpp_query = shortcode_atts( $defaults, $atts );
      $wpp_query[ 'query' ] = shortcode_atts( $queryable_keys, $atts );

      //** Handle search */
      if ( $wpp_search = $_REQUEST[ 'wpp_search' ] ) {
        $wpp_query[ 'query' ] = shortcode_atts( $wpp_query[ 'query' ], $wpp_search );
        $wpp_query[ 'query' ] = WPP_F::prepare_search_attributes( $wpp_query[ 'query' ] );

        if ( isset( $_REQUEST[ 'wpp_search' ][ 'sort_by' ] ) ) {
          $wpp_query[ 'sort_by' ] = $_REQUEST[ 'wpp_search' ][ 'sort_by' ];
        }

        if ( isset( $_REQUEST[ 'wpp_search' ][ 'sort_order' ] ) ) {
          $wpp_query[ 'sort_order' ] = $_REQUEST[ 'wpp_search' ][ 'sort_order' ];
        }

        if ( isset( $_REQUEST[ 'wpp_search' ][ 'pagination' ] ) ) {
          $wpp_query[ 'pagination' ] = $_REQUEST[ 'wpp_search' ][ 'pagination' ];
        }

        if ( isset( $_REQUEST[ 'wpp_search' ][ 'per_page' ] ) ) {
          $wpp_query[ 'per_page' ] = $_REQUEST[ 'wpp_search' ][ 'per_page' ];
        }
      }

    }

    //** Load certain settings into query for get_properties() to use */
    $wpp_query[ 'query' ][ 'sort_by' ] = $wpp_query[ 'sort_by' ];
    $wpp_query[ 'query' ][ 'sort_order' ] = $wpp_query[ 'sort_order' ];

    $wpp_query[ 'query' ][ 'pagi' ] = $wpp_query[ 'starting_row' ] . '--' . $wpp_query[ 'per_page' ];

    if ( !isset( $wpp_query[ 'current_page' ] ) ) {
      $wpp_query[ 'current_page' ] = ( $wpp_query[ 'starting_row' ] / $wpp_query[ 'per_page' ] ) + 1;
    }

    //** Load settings that are not passed via shortcode atts */
    $wpp_query[ 'sortable_attrs' ] = WPP_F::get_sortable_keys();

    //** Replace dynamic field values */

    //** Detect currently property for conditional in-shortcode usage that will be replaced from values */
    if ( isset( $post ) ) {

      $dynamic_fields[ 'post_id' ] = $post->ID;
      $dynamic_fields[ 'post_parent' ] = $post->parent_id;
      $dynamic_fields[ 'property_type' ] = $post->property_type;

      $dynamic_fields = apply_filters( 'shortcode_property_overview_dynamic_fields', $dynamic_fields );

      if ( is_array( $dynamic_fields ) ) {
        foreach ( $wpp_query[ 'query' ] as $query_key => $query_value ) {
          if ( !empty( $dynamic_fields[ $query_value ] ) ) {
            $wpp_query[ 'query' ][ $query_key ] = $dynamic_fields[ $query_value ];
          }
        }
      }
    }

    //** Remove all blank values */
    $wpp_query[ 'query' ] = array_filter( $wpp_query[ 'query' ] );

    //** Unset this because it gets passed with query (for back-button support) but not used by get_properties() */
    unset( $wpp_query[ 'query' ][ 'per_page' ] );
    unset( $wpp_query[ 'query' ][ 'pagination' ] );
    unset( $wpp_query[ 'query' ][ 'requested_page' ] );

    //** Load the results */
    $wpp_query[ 'properties' ] = WPP_F::get_properties( $wpp_query[ 'query' ], true );

    //** Calculate number of pages */
    if ( $wpp_query[ 'pagination' ] == 'on' ) {
      $wpp_query[ 'pages' ] = ceil( $wpp_query[ 'properties' ][ 'total' ] / $wpp_query[ 'per_page' ] );
    }

    //** Set for quick access (for templates */
    $property_type = $wpp_query[ 'query' ][ 'property_type' ];

    if ( !empty( $property_type ) ) {
      foreach ( (array) $wp_properties[ 'hidden_attributes' ][ $property_type ] as $attr_key ) {
        unset( $wpp_query[ 'sortable_attrs' ][ $attr_key ] );
      }
    }

    //** Legacy Support - include variables so old templates still work */
    $properties = $wpp_query[ 'properties' ][ 'results' ];
    $thumbnail_sizes = WPP_F::image_sizes( $wpp_query[ 'thumbnail_size' ] );
    $child_properties_title = $wpp_query[ 'child_properties_title' ];
    $unique = $wpp_query[ 'unique_hash' ];
    $thumbnail_size = $wpp_query[ 'thumbnail_size' ];

    //* Debugger */
    if ( $wp_properties[ 'configuration' ][ 'developer_mode' ] == 'true' && !$wpp_query[ 'ajax_call' ] ) {
      echo '<script type="text/javascript">console.log( ' . json_encode( $wpp_query ) . ' ); </script>';
    }

    ob_start();

    //** Make certain variables available to be used within the single listing page */
    $wpp_overview_shortcode_vars = apply_filters( 'wpp_overview_shortcode_vars', array(
      'wp_properties' => $wp_properties,
      'wpp_query' => $wpp_query
    ) );

    //** By merging our extra variables into $wp_query->query_vars they will be extracted in load_template() */
    if ( is_array( $wpp_overview_shortcode_vars ) ) {
      $wp_query->query_vars = array_merge( $wp_query->query_vars, $wpp_overview_shortcode_vars );
    }

    $template = $wpp_query[ 'template' ];
    $fancybox_preview = $wpp_query[ 'fancybox_preview' ];
    $show_children = $wpp_query[ 'show_children' ];
    $class = $wpp_query[ 'class' ];
    $stats = $wpp_query[ 'stats' ];
    $in_new_window = ( !empty( $wpp_query[ 'in_new_window' ] ) ? " target=\"_blank\" " : "" );

    //** Make query_vars available to emulate WP template loading */
    extract( $wp_query->query_vars, EXTR_SKIP );

    //** Try find custom template */
    $template_found = WPP_F::get_template_part( array(
      "property-overview-{$template}",
      "property-overview-{$property_type}",
      "property-{$template}",
      "property-overview",
    ), array( WPP_Templates ) );

    if ( $template_found ) {
      include $template_found;
    }

    $ob_get_contents = ob_get_contents();
    ob_end_clean();

    $ob_get_contents = apply_filters( 'shortcode_property_overview_content', $ob_get_contents, $wpp_query );

    // Initialize result (content which will be shown) and open wrap (div) with unique id
    if ( $wpp_query[ 'disable_wrapper' ] != 'true' ) {
      $result[ 'top' ] = '<div id="wpp_shortcode_' . $defaults[ 'unique_hash' ] . '" class="wpp_ui ' . $wpp_query[ 'class' ] . '">';
    }

    $result[ 'top_pagination' ] = wpi_draw_pagination( array(
      'class' => 'wpp_top_pagination',
      'sorter_type' => $wpp_query[ 'sorter_type' ],
      'hide_count' => $hide_count,
      'sort_by_text' => $wpp_query[ 'sort_by_text' ],
    ) );
    $result[ 'result' ] = $ob_get_contents;

    if ( $wpp_query[ 'bottom_pagination_flag' ] == 'true' ) {
      $result[ 'bottom_pagination' ] = wpi_draw_pagination( array(
        'class' => 'wpp_bottom_pagination',
        'sorter_type' => $wpp_query[ 'sorter_type' ],
        'hide_count' => $hide_count,
        'sort_by_text' => $wpp_query[ 'sort_by_text' ],
        'javascript' => false
      ) );
    }

    if ( $wpp_query[ 'disable_wrapper' ] != 'true' ) {
      $result[ 'bottom' ] = '</div>';
    }

    $result = apply_filters( 'wpp_property_overview_render', $result );

    if ( $wpp_query[ 'ajax_call' ] ) {
      return json_encode( array( 'wpp_query' => $wpp_query, 'display' => implode( '', $result ) ) );
    } else {
      return implode( '', $result );
    }
  }

  /**
   * Retrevie property attribute using shortcode.
   *
   *
   * @since 1.26.0
   *
   */
  function shortcode_property_attribute( $atts = false ) {
    global $post, $property;

    $this_property = $property;

    if ( empty( $this_property ) && $post->post_type == 'property' ) {
      $this_property = $post;
    }

    $this_property = (array) $this_property;

    if ( !$atts ) {
      $atts = array();
    }

    $defaults = array(
      'property_id' => $this_property[ 'ID' ],
      'attribute' => '',
      'before' => '',
      'after' => '',
      'if_empty' => '',
      'do_not_format' => '',
      'make_terms_links' => 'false',
      'separator' => ' ',
      'strip_tags' => ''
    );

    $args = array_merge( $defaults, $atts );

    if ( empty( $args[ 'attribute' ] ) ) {
      return false;
    }

    $attribute = $args[ 'attribute' ];

    if ( $args[ 'property_id' ] != $this_property[ 'ID' ] ) {

      $this_property = WPP_F::get_property( $args[ 'property_id' ] );

      if ( $args[ 'do_not_format' ] != "true" ) {
        $this_property = prepare_property_for_display( $this_property );
      }

    } else {
      $this_property = $this_property;
    }

    if ( is_taxonomy( $attribute ) && is_object_in_taxonomy( 'property', $attribute ) ) {
      foreach ( wp_get_object_terms( $this_property[ 'ID' ], $attribute ) as $term_data ) {

        if ( $args[ 'make_terms_links' ] == 'true' ) {
          $terms[ ] = '<a class="wpp_term_link" href="' . get_term_link( $term_data, $attribute ) . '"><span class="wpp_term">' . $term_data->name . '</span></a>';
        } else {
          $terms[ ] = '<span class="wpp_term">' . $term_data->name . '</span>';
        }
      }

      if ( is_array( $terms ) && !empty( $terms ) ) {
        $value = implode( $args[ 'separator' ], $terms );
      }

    }

    //** Try to get value using get get_attribute() function */
    if ( !$value && function_exists( 'get_attribute' ) ) {
      $value = get_attribute( $attribute, array(
        'return' => 'true',
        'property_object' => $this_property
      ) );
    }

    if ( !empty( $args[ 'before' ] ) ) {
      $return[ 'before' ] = html_entity_decode( $args[ 'before' ] );
    }

    $return[ 'value' ] = apply_filters( 'wpp_property_attribute_shortcode', $value, $this_property );

    if ( $args[ 'strip_tags' ] == "true" && !empty( $return[ 'value' ] ) ) {
      $return[ 'value' ] = strip_tags( $return[ 'value' ] );
    }

    if ( !empty( $args[ 'after' ] ) ) {
      $return[ 'after' ] = html_entity_decode( $args[ 'after' ] );
    }

    //** When no value is found */
    if ( empty( $return[ 'value' ] ) ) {

      if ( !empty( $args[ 'if_empty' ] ) ) {
        return $args[ 'if_empty' ];
      } else {
        return false;
      }
    }

    if ( is_array( $return ) ) {
      return implode( '', $return );
    }

    return false;

  }

  /**
   * Displays a map for the current property.
   *
   * Must be used on a property page, or within a property loop where the global $post or $property variable is for a property object.
   *
   * @since 1.26.0
   *
   */
  function shortcode_property_map( $atts = false ) {
    global $post, $property;

    if ( !$atts ) {
      $atts = array();
    }

    $defaults = array(
      'width' => '100%',
      'height' => '450px',
      'zoom_level' => '13',
      'hide_infobox' => 'false',
      'property_id' => false
    );

    $args = array_merge( $defaults, $atts );

    //** Try to get property if an ID is passed */
    if ( is_numeric( $args[ 'property_id' ] ) ) {
      $property = WPP_F::get_property( $args[ 'property_id' ] );
    }

    //** Load into $property object */
    if ( !isset( $property ) ) {
      $property = $post;
    }

    //** Convert to array */
    $property = (array) $property;

    //** Force map to be enabled here */
    $skip_default_google_map_check = true;

    $map_width = $args[ 'width' ];
    $map_height = $args[ 'height' ];
    $hide_infobox = ( $args[ 'hide_infobox' ] == 'true' ? true : false );

    //** Find most appropriate template */
    $template_found = WPP_F::get_template_part( array( "content-single-property-map", "property-map" ), array( WPP_Templates ) );
    if ( !$template_found ) {
      return false;
    }
    ob_start();
    include $template_found;
    $html = ob_get_contents();
    ob_end_clean();

    $html = apply_filters( 'shortcode_property_map_content', $html, $args );

    return $html;
  }

  /**
   * Return property overview data for AJAX calls
   *
   * @since 0.723
   *
   * @uses WPP_Core::shortcode_property_overview()
   *
   */
  function ajax_property_overview() {

    $params = $_REQUEST[ 'wpp_ajax_query' ];

    if ( !empty( $params[ 'action' ] ) ) {
      unset( $params[ 'action' ] );
    }

    $params[ 'ajax_call' ] = true;

    $data = WPP_Core::shortcode_property_overview( $params );

    die( $data );
  }

  /**
   * Adds wp-property-listing class in search results and property_overview pages
   *
   * @since 0.7260
   */
  function properties_body_class( $classes ) {
    global $post, $wp_properties;

    if ( strpos( $post->post_content, "property_overview" ) || ( is_search() && isset( $_REQUEST[ 'wpp_search' ] ) ) || ( $wp_properties[ 'configuration' ][ 'base_slug' ] == $post->post_name ) ) {
      $classes[ ] = 'wp-property-listing';
    }
    return $classes;
  }

  /**
   * Checks settings data on accord with existing wp_properties data ( before option updates )
   *
   * @param array $wpp_settings New wpp settings data
   * @param array $wp_properties Old wpp settings data
   *
   * @return array $wpp_settings
   */
  function check_wp_settings_data( $wpp_settings, $wp_properties ) {
    if ( is_array( $wpp_settings ) && is_array( $wp_properties ) ) {
      foreach ( $wp_properties as $key => $value ) {
        if ( !isset( $wpp_settings[ $key ] ) ) {
          switch ( $key ) {
            case 'hidden_attributes':
            case 'property_inheritance':
              $wpp_settings[ $key ] = array();
              break;
          }
        }
      }
    }

    return $wpp_settings;
  }

  /**
   * Hack to avoid issues with capabilities and views.
   *
   */
  function current_screen( $screen ) {

    switch ( $screen->id ) {
      case "edit-property":
        wp_redirect( 'edit.php?post_type=property&page=all_properties' );
        exit();
        break;
    }

    return $screen;
  }

  /**
   * Adds all WPP custom capabilities to administrator role.
   * Premium feature capabilities are added by filter in this function, see below.
   *
   * @author peshkov@UD
   */
  function set_capabilities() {
    global $wpp_capabilities;

    //* Get Administrator role for adding custom capabilities */
    $role =& get_role( 'administrator' );

    //* General WPP capabilities */
    $wpp_capabilities = array(
      //* Manage WPP Properties Capabilities */
      'edit_wpp_properties' => __( 'View Properties', 'wpp' ),
      'edit_wpp_property' => __( 'Add/Edit Properties', 'wpp' ),
      'edit_others_wpp_properties' => __( 'Edit Other Properties', 'wpp' ),
      //'read_wpp_property' => __( 'Read Property', 'wpp' ),
      'delete_wpp_property' => __( 'Delete Properties', 'wpp' ),
      'publish_wpp_properties' => __( 'Publish Properties', 'wpp' ),
      //'read_private_wpp_properties' => __( 'Read Private Properties', 'wpp' ),
      //* WPP Settings capability */
      'manage_wpp_settings' => __( 'Manage Settings', 'wpp' ),
      //* WPP Taxonomies capability */
      'manage_wpp_categories' => __( 'Manage Taxonomies', 'wpp' )
    );

    //* Adds Premium Feature Capabilities */
    $wpp_capabilities = apply_filters( 'wpp_capabilities', $wpp_capabilities );

    if ( !is_object( $role ) ) {
      return;
    }

    foreach ( $wpp_capabilities as $cap => $value ) {
      if ( empty( $role->capabilities[ $cap ] ) ) {
        $role->add_cap( $cap );
      }
    }
  }

  /**
   * Generates javascript file with localization.
   * Adds localization support to all WP-Property scripts.
   *
   * @since 1.37.3.2
   * @author peshkov@UD
   */
  static function localize_scripts() {

    $l10n = array();

    //** Include the list of translations */
    include_once WPP_Path . 'l10n.php';

    /** All additional localizations must be added using the filter below. */
    $l10n = apply_filters( 'wpp::js::localization', $l10n );

    foreach ( (array) $l10n as $key => $value ) {
      if ( !is_scalar( $value ) ) {
        continue;
      }
      $l10n[ $key ] = html_entity_decode( (string) $value, ENT_QUOTES, 'UTF-8' );
    }

    header( 'Content-type: application/x-javascript' );

    die( "var wpp = ( typeof wpp === 'object' ) ? wpp : {}; wpp.strings = " . json_encode( $l10n ) . '; wpp.home_url = "' . home_url() . '";' );

  }

  /**
   * WPP Contextual Help
   *
   * @global $current_screen
   *
   * @param $args
   *
   * @author korotkov@ud
   */
  function wpp_contextual_help( $args = array() ) {
    global $contextual_help;

    $defaults = array(
      'contextual_help' => array()
    );

    extract( wp_parse_args( $args, $defaults ) );

    //** If method exists add_help_tab in WP_Screen */
    if ( is_callable( array( 'WP_Screen', 'add_help_tab' ) ) ) {

      //** Loop through help items and build tabs */
      foreach ( (array) $contextual_help as $help_tab_title => $help ) {

        //** Add tab with current info */
        get_current_screen()->add_help_tab(
          array(
            'id' => sanitize_title( $help_tab_title ),
            'title' => __( $help_tab_title, 'wpp' ),
            'content' => implode( "\n", (array) $contextual_help[ $help_tab_title ] ),
          )
        );

      }

      //** Add help sidebar with More Links */
      get_current_screen()->set_help_sidebar(
        '<p><strong>' . __( 'For more information:', 'wpp' ) . '</strong></p>' .
        '<p>' . __( '<a href="https://usabilitydynamics.com/products/wp-property/" target="_blank">WP-Property Product Page</a>', 'wpp' ) . '</p>' .
        '<p>' . __( '<a href="https://usabilitydynamics.com/products/wp-property/forum/" target="_blank">WP-Property Forums</a>', 'wpp' ) . '</p>' .
        '<p>' . __( '<a href="https://usabilitydynamics.com/help/" target="_blank">WP-Property Tutorials</a>', 'wpp' ) . '</p>'
      );

    } else {
      global $current_screen;
      add_contextual_help( $current_screen->id, '<p>' . __( 'Please upgrade Wordpress to the latest version for detailed help.', 'wpp' ) . '</p><p>' . __( 'Or visit <a href="https://usabilitydynamics.com/tutorials/wp-property-help/" target="_blank">WP-Property Help Page</a> on UsabilityDynamics.com', 'wpp' ) . '</p>' );
    }
  }

  /**
   * Returns specific instance data which is used by javascript
   * Javascript Reference: window.wpp.instance
   *
   * @author peshkov@UD
   * @since 1.38
   * @return array
   */
  function get_instance() {
    global $wp_properties;

    $data = array(
      'request' => $_REQUEST,
      'get' => $_GET,
      'post' => $_POST,
      'iframe_enabled' => false,
      'settings' => $wp_properties,
    );

    if ( isset( $data[ 'request' ][ 'wp_customize' ] ) && $data[ 'request' ][ 'wp_customize' ] == 'on' ) {
      $data[ 'iframe_enabled' ] = true;
    }

    return apply_filters( 'wpp::get_instance', $data );
  }

}