示例#1
0
 /**
  * Performs front-end pre-header functionality
  *
  * - This function is not called on admin side.
  * - Loads conditional CSS styles.
  * - Determines if page is single property or property overview.
  *
  * @since 1.11
  */
 public function template_redirect()
 {
     global $post, $property, $wp_query, $wp_properties, $wp_styles, $wpp_query;
     /**
      * HACK.
      * @see self::parse_request();
      * @author peshkov@UD
      */
     if (get_query_var('_fix_to_page_template')) {
         $wp_query->is_single = false;
         $wp_query->is_page = true;
     }
     wp_localize_script('wpp-localization', 'wpp', array('instance' => $this->get_instance()));
     //** Load global wp-property script on all frontend pages */
     wp_enqueue_script('wp-property-global');
     if (apply_filters('wpp::custom_styles', false) === false) {
         //** Possibly load essential styles that are used in widgets */
         wp_enqueue_style('wp-property-frontend');
         //** Possibly load theme specific styles */
         wp_enqueue_style('wp-property-theme-specific');
     }
     if (!isset($wp_properties['configuration']['do_not_enable_text_widget_shortcodes']) || $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 (isset($post) && count($wp_query->posts) < 2 && ($post->post_type == "property" || isset($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;
         }
     }
     //** If viewing root property page that is the default dynamic page. */
     if (isset($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 (isset($post) && 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 (isset($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 (isset($wp_query->wpp_search_page) && (!isset($wp_properties['configuration']['do_not_override_search_result_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 single listing pages */
     if (isset($wp_query->single_property_page) || isset($wp_query->is_property_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_URL . "styles/wp_properties-{$url_slug}.css") && $wp_properties['configuration']['autoload_css'] == 'true') {
                 wp_register_style('wp-property-frontend-' . $url_slug, WPP_URL . "styles/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 (isset($wp_query->single_property_page)) {
         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 = (array) WPP_F::get_property($post->ID, "load_gallery=true");
         $property_type = !empty($property['property_type']) ? $property['property_type'] : false;
         // Redirect to parent if property type is non-public.
         if (isset($wp_properties['redirect_to_parent']) && is_array($wp_properties['redirect_to_parent']) && in_array($property_type, $wp_properties['redirect_to_parent']) && $property['post_parent']) {
             die(wp_redirect(get_permalink($property['post_parent'])));
         }
         $property = prepare_property_for_display($property);
         //** 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);
         }
     }
     //** Current requests includes a property overview.  PO may be via shortcode, search result, or due to this being the Default Dynamic Property page */
     if (isset($wp_query->is_property_overview)) {
         WPP_F::console_log('Including scripts for all property overview pages.');
         WPP_F::load_assets(array('overview'));
         if (isset($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'); "));
     }
     do_action('wpp_template_redirect_post_scripts');
 }
 /**
  * Primary static function for queries properties  based on type and attributes
  *
  * @todo There is a limitation when doing a search such as 4,5+ then mixture of specific and open ended search is not supported.
  * @since 1.08
  *
  * @param string $args / $args
  *
  * @param bool   $total
  *
  * @return bool|mixed|void
  */
 public static function get_properties($args = "", $total = false)
 {
     global $wpdb, $wp_properties, $wpp_query;
     //** Cleanup (fix) ID argument if it's passed */
     $args = wp_parse_args($args);
     if (isset($args['id'])) {
         $args['ID'] = $args['id'];
         unset($args['id']);
     }
     //** property_id is replaced with ID only if Property Attribute with slug 'property_id' does not exist */
     if (isset($args['property_id']) && !key_exists('property_id', $wp_properties['property_stats'])) {
         $args['ID'] = $args['property_id'];
         unset($args['property_id']);
     }
     //** Prints args to firebug if debug mode is enabled */
     $log = is_array($args) ? urldecode(http_build_query($args)) : $args;
     WPP_F::console_log("get_properties() args: {$log}");
     //** The function can be overwritten using the filter below. */
     $response = apply_filters('wpp::get_properties::custom', null, $args, $total);
     if ($response !== null) {
         return $response;
     }
     $_query_keys = array();
     /* Define keys that should not be used to query data */
     $_system_keys = array('pagi', 'pagination', 'limit_query', 'starting_row', 'sort_by', 'sort_order');
     // Non post_meta fields
     $non_post_meta = array('post_title' => 'like', 'post_status' => 'equal', 'post_author' => 'equal', 'ID' => 'or', 'post_parent' => 'equal', 'post_date' => 'date');
     /**
      * Specific meta data can contain value with commas. E.g. location field ( address_attribute )
      * The current list contains meta slugs which will be ignored for comma parsing. peshkov@UD
      */
     $commas_ignore = apply_filters('wpp::get_properties::commas_ignore', array_filter(array($wp_properties['configuration']['address_attribute'])));
     $capture_sql_args = array('limit_query');
     //** added to avoid range and "LIKE" searches on single numeric values *
     if (is_array($args)) {
         foreach ((array) $args as $thing => $value) {
             if (in_array($thing, (array) $capture_sql_args)) {
                 $sql_args[$thing] = $value;
                 unset($args[$thing]);
                 continue;
             }
             // unset empty filter options
             if (empty($value)) {
                 unset($args[$thing]);
                 continue;
             }
             if (is_array($value)) {
                 $value = implode(',', $value);
             }
             $value = trim($value);
             $original_value = $value;
             $numeric = !empty($wp_properties['numeric_attributes']) && in_array($thing, (array) $wp_properties['numeric_attributes']) ? true : false;
             //** If not CSV and last character is a +, we look for open-ended ranges, i.e. bedrooms: 5+
             if (substr($original_value, -1, 1) == '+' && !strpos($original_value, ',') && $numeric) {
                 //** User requesting an open ended range, we leave it off with a dash, i.e. 500- */
                 $args[$thing] = str_replace('+', '', $value) . '-';
             } elseif (is_numeric($value) && $numeric) {
                 //** If number is numeric, we do a specific search, i.e. 500-500 */
                 if (!array_key_exists($thing, $non_post_meta)) {
                     $args[$thing] = $value . '-' . $value;
                 }
             } elseif (is_string($value)) {
                 $args[$thing] = $value;
             }
         }
     }
     $defaults = array('property_type' => 'all', 'pagi' => false, 'sort_by' => false);
     $query = wp_parse_args($args, $defaults);
     $query = apply_filters('wpp_get_properties_query', $query);
     $query_keys = array_keys((array) $query);
     //** Search by non meta values */
     $additional_sql = '';
     //** Show 'publish' posts if status is not specified */
     if (!array_key_exists('post_status', $query)) {
         $additional_sql .= " AND p.post_status = 'publish' ";
     } else {
         if ($query['post_status'] != 'all') {
             if (strpos($query['post_status'], ',') === false) {
                 $additional_sql .= " AND p.post_status = '{$query['post_status']}' ";
             } else {
                 $post_status = explode(',', $query['post_status']);
                 foreach ($post_status as &$ps) {
                     $ps = trim($ps);
                 }
                 $additional_sql .= " AND p.post_status IN ( '" . implode("','", $post_status) . "') ";
             }
         } else {
             $additional_sql .= " AND p.post_status <> 'auto-draft' ";
         }
         unset($query['post_status']);
     }
     foreach ((array) $non_post_meta as $field => $condition) {
         if (array_key_exists($field, $query)) {
             if ($condition == 'like') {
                 $additional_sql .= " AND p.{$field} LIKE '%{$query[$field]}%' ";
             } else {
                 if ($condition == 'equal') {
                     $additional_sql .= " AND p.{$field} = '{$query[$field]}' ";
                 } else {
                     if ($condition == 'or') {
                         $f = '';
                         $d = !is_array($query[$field]) ? explode(',', $query[$field]) : $query[$field];
                         foreach ($d as $k => $v) {
                             $f .= !empty($f) ? ",'" . trim($v) . "'" : "'" . trim($v) . "'";
                         }
                         $additional_sql .= " AND p.{$field} IN ({$f}) ";
                     } else {
                         if ($condition == 'date') {
                             $additional_sql .= " AND YEAR( p.{$field} ) = " . substr($query[$field], 0, 4) . " AND MONTH( p.{$field} ) = " . substr($query[$field], 4, 2) . " ";
                         }
                     }
                 }
             }
             unset($query[$field]);
         }
     }
     if (!empty($sql_args['limit_query'])) {
         $sql_args['starting_row'] = $sql_args['starting_row'] ? $sql_args['starting_row'] : 0;
         $limit_query = "LIMIT {$sql_args['starting_row']}, {$sql_args['limit_query']};";
     } elseif (substr_count($query['pagi'], '--')) {
         $pagi = explode('--', $query['pagi']);
         if (count($pagi) == 2 && is_numeric($pagi[0]) && is_numeric($pagi[1])) {
             $limit_query = "LIMIT {$pagi['0']}, {$pagi['1']};";
         }
     }
     /** Handles the sort_by parameter in the Short Code */
     if ($query['sort_by']) {
         $sql_sort_by = $query['sort_by'];
         $sql_sort_order = isset($query['sort_order']) ? strtoupper($query['sort_order']) : 'ASC';
     } else {
         $sql_sort_by = 'post_date';
         $sql_sort_order = 'ASC';
     }
     //** Unsert arguments that will conflict with attribute query */
     foreach ((array) $_system_keys as $system_key) {
         unset($query[$system_key]);
     }
     // Go down the array list narrowing down matching properties
     foreach ((array) $query as $meta_key => $criteria) {
         $specific = '';
         // Stop filtering ( loop ) because no IDs left
         if (isset($matching_ids) && empty($matching_ids)) {
             break;
         }
         $numeric = isset($wp_properties['numeric_attributes']) && in_array($meta_key, (array) $wp_properties['numeric_attributes']) ? true : false;
         if (!in_array($meta_key, (array) $commas_ignore) && substr_count($criteria, ',') || substr_count($criteria, '-') && $numeric || substr_count($criteria, '--')) {
             if (substr_count($criteria, '-') && !substr_count($criteria, ',')) {
                 $cr = explode('-', $criteria);
                 // Check pieces of criteria. Array should contains 2 int's elements
                 // In other way, it's just value of meta_key
                 if (count($cr) > 2 || (double) $cr[0] == 0 && (double) $cr[1] == 0) {
                     $specific = $criteria;
                 } else {
                     $hyphen_between = $cr;
                     // If min value doesn't exist, set 1
                     if (empty($hyphen_between[0]) && $hyphen_between[0] != "0") {
                         $hyphen_between[0] = 1;
                     }
                 }
             }
             if (substr_count($criteria, ',')) {
                 $comma_and = explode(',', $criteria);
             }
         } else {
             $specific = $criteria;
         }
         if (!isset($limit_query)) {
             $limit_query = '';
         }
         switch ($meta_key) {
             case 'property_type':
                 // Get all property types
                 if ($specific == 'all') {
                     if (isset($matching_ids)) {
                         $matching_id_filter = implode("' OR ID ='", $matching_ids);
                         $matching_ids = $wpdb->get_col("SELECT ID FROM {$wpdb->posts} WHERE (ID ='{$matching_id_filter}' ) AND post_type = 'property'");
                     } else {
                         $matching_ids = $wpdb->get_col("SELECT ID FROM {$wpdb->posts} WHERE post_type = 'property'");
                     }
                     break;
                 }
                 //** If comma_and is set, $criteria is ignored, otherwise $criteria is used */
                 $property_type_array = isset($comma_and) && is_array($comma_and) ? $comma_and : array($specific);
                 //** Make sure property type is in slug format */
                 foreach ($property_type_array as $key => $this_property_type) {
                     foreach ((array) $wp_properties['property_types'] as $pt_key => $pt_value) {
                         if (strtolower($pt_value) == strtolower($this_property_type)) {
                             $property_type_array[$key] = $pt_key;
                         }
                     }
                 }
                 if (!empty($property_type_array)) {
                     //** Multiple types passed */
                     $where_string = implode("' OR meta_value ='", $property_type_array);
                 } else {
                     //** Only on type passed */
                     $where_string = $property_type_array[0];
                 }
                 // See if mathinc_ids have already been filtered down
                 if (isset($matching_ids)) {
                     $matching_id_filter = implode("' OR post_id ='", $matching_ids);
                     $matching_ids = $wpdb->get_col("SELECT post_id FROM {$wpdb->postmeta} WHERE (post_id ='{$matching_id_filter}' ) AND ( meta_key = 'property_type' AND (meta_value ='{$where_string}' ))");
                 } else {
                     $matching_ids = $wpdb->get_col("SELECT post_id FROM {$wpdb->postmeta} WHERE (meta_key = 'property_type' AND (meta_value ='{$where_string}' ))");
                 }
                 break;
             case apply_filters('wpp::get_properties::custom_case', false, $meta_key):
                 $matching_ids = apply_filters('wpp::get_properties::custom_key', $matching_ids, $meta_key, $criteria);
                 break;
             default:
                 // Get all properties for that meta_key
                 if ($specific == 'all' && empty($comma_and) && empty($hyphen_between)) {
                     if (isset($matching_ids)) {
                         $matching_id_filter = implode("' OR post_id ='", $matching_ids);
                         $matching_ids = $wpdb->get_col("SELECT post_id FROM {$wpdb->postmeta} WHERE (post_id ='{$matching_id_filter}' ) AND ( meta_key = '{$meta_key}' )");
                     } else {
                         $matching_ids = $wpdb->get_col("SELECT post_id FROM {$wpdb->postmeta} WHERE (meta_key = '{$meta_key}' )");
                     }
                     break;
                 } else {
                     if (!empty($comma_and)) {
                         $where_and = "( meta_value ='" . implode("' OR meta_value ='", $comma_and) . "')";
                         $specific = $where_and;
                     }
                     if (!empty($hyphen_between)) {
                         // We are going to see if we are looking at some sort of date, in which case we have a special MySQL modifier
                         $adate = false;
                         if (preg_match('%\\d{1,2}/\\d{1,2}/\\d{4}%i', $hyphen_between[0])) {
                             $adate = true;
                         }
                         if (!empty($hyphen_between[1])) {
                             if (preg_match('%\\d{1,2}/\\d{1,2}/\\d{4}%i', $hyphen_between[1])) {
                                 foreach ($hyphen_between as $key => $value) {
                                     $hyphen_between[$key] = "STR_TO_DATE( '{$value}', '%c/%e/%Y' )";
                                 }
                                 $where_between = "STR_TO_DATE( `meta_value`, '%c/%e/%Y' ) BETWEEN " . implode(" AND ", $hyphen_between) . "";
                             } else {
                                 $where_between = "`meta_value` BETWEEN " . implode(" AND ", $hyphen_between) . "";
                             }
                         } else {
                             if ($adate) {
                                 $where_between = "STR_TO_DATE( `meta_value`, '%c/%e/%Y' ) >= STR_TO_DATE( '{$hyphen_between[0]}', '%c/%e/%Y' )";
                             } else {
                                 $where_between = "`meta_value` >= {$hyphen_between['0']}";
                             }
                         }
                         $specific = $where_between;
                     }
                     if ($specific == 'true') {
                         // If properties data were imported, meta value can be '1' instead of 'true'
                         // So we're trying to find also '1'
                         $specific = "meta_value IN ( 'true', '1' )";
                     } elseif (!substr_count($specific, 'meta_value')) {
                         //** Determine if we don't need to use LIKE in SQL query */
                         preg_match("/^#(.+)#\$/", $specific, $matches);
                         if ($matches) {
                             $specific = " meta_value = '{$matches[1]}'";
                         } else {
                             //** Adds conditions for Searching by partial value */
                             $s = explode(' ', trim($specific));
                             $specific = '';
                             $count = 0;
                             foreach ($s as $p) {
                                 if ($count > 0) {
                                     $specific .= " AND ";
                                 }
                                 $specific .= "meta_value LIKE '%{$p}%'";
                                 $count++;
                             }
                         }
                     }
                     if (isset($matching_ids)) {
                         $matching_id_filter = implode(",", $matching_ids);
                         $sql_query = "SELECT post_id FROM {$wpdb->postmeta} WHERE post_id IN ( {$matching_id_filter} ) AND meta_key = '{$meta_key}' AND {$specific}";
                     } else {
                         $sql_query = "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '{$meta_key}' AND {$specific}";
                     }
                     //** Some specific additional conditions can be set in filters */
                     $sql_query = apply_filters('wpp::get_properties::meta_key::sql_query', $sql_query, array('meta_key' => $meta_key, 'specific' => $specific, 'matching_id_filter' => isset($matching_id_filter) ? $matching_id_filter : false, 'criteria' => $criteria));
                     $matching_ids = $wpdb->get_col($sql_query);
                 }
                 break;
         }
         // END switch
         unset($comma_and);
         unset($hyphen_between);
     }
     // END foreach
     // Return false, if there are any result using filter conditions
     if (empty($matching_ids)) {
         return false;
     }
     // Remove duplicates
     $matching_ids = array_unique($matching_ids);
     $matching_ids = apply_filters('wpp::get_properties::matching_ids', $matching_ids, array_merge((array) $query, array('additional_sql' => $additional_sql, 'total' => $total)));
     $result = apply_filters('wpp::get_properties::custom_sort', false, array('matching_ids' => $matching_ids, 'additional_sql' => $additional_sql, 'sort_by' => $sql_sort_by, 'sort_order' => $sql_sort_order, 'limit_query' => $limit_query));
     if (!$result) {
         // Sorts the returned Properties by the selected sort order
         if ($sql_sort_by && $sql_sort_by != 'menu_order' && $sql_sort_by != 'post_date' && $sql_sort_by != 'post_modified' && $sql_sort_by != 'post_title') {
             //** Sorts properties in random order. */
             if ($sql_sort_by === 'random') {
                 $result = $wpdb->get_col("\n            SELECT ID FROM {$wpdb->posts} AS p\n            WHERE ID IN (" . implode(",", $matching_ids) . ")\n            {$additional_sql}\n            ORDER BY RAND() {$sql_sort_order}\n            {$limit_query}");
             } else {
                 //** Determine if attribute has numeric format or all values of meta_key are numbers we use CAST in SQL query to avoid sort issues */
                 if (isset($wp_properties['numeric_attributes']) && in_array($sql_sort_by, $wp_properties['numeric_attributes']) || self::meta_has_number_data_type($matching_ids, $sql_sort_by)) {
                     $meta_value = "CAST( meta_value AS DECIMAL(20,3 ))";
                 } else {
                     $meta_value = "meta_value";
                 }
                 $result = $wpdb->get_col("\n            SELECT p.ID , (SELECT pm.meta_value FROM {$wpdb->postmeta} AS pm WHERE pm.post_id = p.ID AND pm.meta_key = '{$sql_sort_by}' LIMIT 1 ) as meta_value\n              FROM {$wpdb->posts} AS p\n              WHERE p.ID IN ( " . implode(",", $matching_ids) . ")\n              {$additional_sql}\n              ORDER BY {$meta_value} {$sql_sort_order}\n              {$limit_query}");
             }
         } else {
             $result = $wpdb->get_col("\n          SELECT ID FROM {$wpdb->posts} AS p\n          WHERE ID IN (" . implode(",", $matching_ids) . ")\n          {$additional_sql}\n          ORDER BY {$sql_sort_by} {$sql_sort_order}\n          {$limit_query}");
         }
     }
     // Stores the total Properties returned
     if ($total) {
         $total = count($wpdb->get_col("\n        SELECT p.ID\n          FROM {$wpdb->posts} AS p\n          WHERE p.ID IN (" . implode(",", $matching_ids) . ")\n          {$additional_sql}"));
     }
     WPP_F::console_log("get_properties() total: {$total}");
     if (!empty($result)) {
         $return = array();
         if (!empty($total)) {
             $return['total'] = $total;
             $return['results'] = $result;
         } else {
             $return = $result;
         }
         return apply_filters('wpp::get_properties::result', $return, $args);
     }
     return false;
 }