/**
  * Returns array of searchable attributes and their ranges
  *
  *
  * @param      $search_attributes
  * @param      $searchable_property_types
  * @param bool $cache
  * @param bool $instance_id
  *
  * @return array|$range
  * @since 0.57
  */
 public static function get_search_values($search_attributes, $searchable_property_types, $cache = true, $instance_id = false)
 {
     global $wpdb, $wp_properties;
     // Non post_meta fields
     $non_post_meta = array('ID' => 'equal', 'post_date' => 'date');
     if ($instance_id && $cache) {
         $result = WPP_F::get_cache($instance_id);
     }
     if (empty($result)) {
         $query_attributes = "";
         $query_types = "";
         $range = array();
         //** Use the requested attributes, or all searchable */
         if (!is_array($search_attributes)) {
             $search_attributes = $wp_properties['searchable_attributes'];
         }
         if (!is_array($searchable_property_types)) {
             $searchable_property_types = explode(',', $searchable_property_types);
             foreach ($searchable_property_types as $k => $v) {
                 $searchable_property_types[$k] = trim($v);
             }
         }
         $searchable_property_types_sql = "AND pm2.meta_value IN ('" . implode("','", $searchable_property_types) . "')";
         //** Cycle through requested attributes */
         foreach ($search_attributes as $searchable_attribute) {
             if ($searchable_attribute == 'property_type') {
                 continue;
             }
             //** Load attribute data */
             $attribute_data = UsabilityDynamics\WPP\Attributes::get_attribute_data($searchable_attribute);
             if (isset($attribute_data['numeric']) || isset($attribute_data['currency'])) {
                 $is_numeric = true;
             } else {
                 $is_numeric = false;
             }
             //** Check to see if this attribute has predefined values or if we have to get them from DB */
             //** If the attributes has predefind values, we use them */
             if (!empty($wp_properties['predefined_search_values'][$searchable_attribute])) {
                 $predefined_search_values = $wp_properties['predefined_search_values'][$searchable_attribute];
                 $predefined_search_values = str_replace(array(', ', ' ,'), array(',', ','), trim($predefined_search_values));
                 $predefined_search_values = explode(',', $predefined_search_values);
                 if (is_array($predefined_search_values)) {
                     foreach ($predefined_search_values as $value) {
                         $range[$searchable_attribute][] = $value;
                     }
                 } else {
                     $range[$searchable_attribute][] = $predefined_search_values;
                 }
             } elseif (array_key_exists($searchable_attribute, $non_post_meta)) {
                 $type = $non_post_meta[$searchable_attribute];
                 //** No predefined value exist */
                 $db_values = $wpdb->get_col("\n            SELECT DISTINCT(" . ($type == 'data' ? "DATE_FORMAT(p1.{$searchable_attribute}, '%Y%m')" : "p1.{$searchable_attribute}") . ")\n            FROM {$wpdb->posts} p1\n            LEFT JOIN {$wpdb->postmeta} pm2 ON p1.ID = pm2.post_id\n            WHERE pm2.meta_key = 'property_type' \n              AND p1.post_status = 'publish'\n              {$searchable_property_types_sql}\n            order by p1.{$searchable_attribute}\n          ");
                 //* Get all available values for this attribute for this property_type */
                 $range[$searchable_attribute] = $db_values;
             } else {
                 //** No predefined value exist */
                 $db_values = $wpdb->get_col("\n            SELECT DISTINCT(pm1.meta_value)\n            FROM {$wpdb->posts} p1\n            LEFT JOIN {$wpdb->postmeta} pm1 ON p1.ID = pm1.post_id\n            LEFT JOIN {$wpdb->postmeta} pm2 ON pm1.post_id = pm2.post_id\n            WHERE pm1.meta_key = '{$searchable_attribute}' \n              AND pm2.meta_key = 'property_type'\n              AND pm1.meta_value != ''\n              AND p1.post_status = 'publish'\n              {$searchable_property_types_sql}\n            ORDER BY " . ($is_numeric ? 'ABS(' : '') . "pm1.meta_value" . ($is_numeric ? ')' : '') . " ASC\n          ");
                 //* Get all available values for this attribute for this property_type */
                 $range[$searchable_attribute] = $db_values;
             }
             //** Get unique values*/
             if (is_array($range[$searchable_attribute])) {
                 $range[$searchable_attribute] = array_unique($range[$searchable_attribute]);
             } else {
                 //* This should not happen */
             }
             foreach ($range[$searchable_attribute] as $key => $value) {
                 $original_value = $value;
                 // Clean up values if a conversion exists
                 $value = WPP_F::do_search_conversion($searchable_attribute, trim($value));
                 // Fix value with special chars. Disabled here, should only be done in final templating stage.
                 // $value = htmlspecialchars($value, ENT_QUOTES);
                 //* Remove bad characters signs if attribute is numeric or currency */
                 if ($is_numeric) {
                     $value = str_replace(array(",", "\$"), '', $value);
                 }
                 //** Put cleaned up value back into array */
                 $range[$searchable_attribute][$key] = $value;
             }
             //** Sort values */
             sort($range[$searchable_attribute], SORT_REGULAR);
         }
         //** End single attribute data gather */
         $result = $range;
         if ($instance_id && $cache) {
             WPP_F::set_cache($instance_id, $result);
         }
     }
     return apply_filters('wpp::get_search_values', $result, array('search_attributes' => $search_attributes, 'searchable_property_types' => $searchable_property_types, 'cache' => $cache, 'instance_id' => $instance_id));
 }