I actually had a hard time understanding what exactly was going on here even after the above explanations so I’m going to post my success here just in case it helps somebody else that is trying to figure out higher price ranges.
The hardest part for me to understand was that I had to take this part:
and figure out that 1000 / 600 = 1.6666666666 and then in order to figure out that I needed the 3rd 4th and 5th set of 200. Once I got that all figured out I think I could do this in my sleep.
Thanks for the post. I am using it, but I’m concerned that the layered nav is showing 3 items for my price range of 2000-5000, BUT there are no items yet in this range. There will be later, but not yet.
This of course lends itself to further concern that other numbers are off too.
Thanks for the post. I am using it, but I’m concerned that the layered nav is showing 3 items for my price range of 2000-5000, BUT there are no items yet in this range. There will be later, but not yet.
This of course lends itself to further concern that other numbers are off too.
[ this solution is for an old version of magento 1.3 i believe i cant remember, ill update to implement the same in a newer version but the basic difference is that instead $items[] = $this->_createItem would be something like $data[] = array(.... but ive to check it ]
deggertsen have the perfect solution. The only drawback is that is hard to calculate the counts every time you rearrange the price rankss. so i made an algorithm programmed for the analitic solution to generate ranks.
instead to do what deggertsen does, you could just do this:
here is the methods that suport to do something like that and you just have to add to Mage_Catalog_Model_Layer_Filter_Price, and as you can see in the line
if(!$rank_count)continue;
when a rank does not contains a result it will be not showed:
private function amps_to_ranks($amps, $start_price=0){ $ranks = array(); foreach($amps as $amp) $ranks[] = array($start_price, $start_price = $start_price+$amp); return($ranks); } private function boundaryes_to_ranks($boundaryes){ $ranks = array(); $first = array_shift($boundaryes); foreach($boundaryes as $boundary){ $ranks[] = array($first, $first = $boundary); } return($ranks); } private function find_div($min, $div, $fixed_jumps=null){ $orig_div = $div; $prime_numbers = array(2,3,5,7,11,13,17,23);//here you could add a larger amount of prime numbers, depends on how complex will be your ranks, this should be fine while(($min%$div)!==0){ $current_jump = isset($fixed_jumps)&&count;($fixed_jumps)?array_pop($fixed_jumps):0; foreach($prime_numbers as $idx=>$prime_number) if($current_jump<=$idx&&!($div%$prime_number)){ $div = $div / $prime_number; break; } if($div===$orig_div) break; } return($div); } private function best_div($min, $div){ $jumps = array(0,1,2,3,4); $arr_jumps = array(); foreach($jumps as $i) foreach($jumps as $j) if($i || $j) $arr_jumps[] = array($i, $j); $orig_div = $div; $found_divs = array(); $new_div = $this->find_div($min, $div); if($orig_div!=$new_div) $found_divs[] = $new_div; foreach($arr_jumps as $jumps){ $new_div = $this->find_div($min, $div, $jumps); if($new_div!=$orig_div) $found_divs[$jumps[0].','.$jumps[1]] = $new_div; } $best_div = $orig_div; if($found_divs) $best_div = max($found_divs); return($best_div); } private function getItemsByRanks($ranks){ //var_dump($ranks);die(); $interval_counts = array(); $items = array(); foreach($ranks as $rank){ $min = $rank[0]; $max = $rank[1]; $amp = $max - $min; $div = $amp; $div = $this->best_div($min, $div); if($min%$div)//wont be able to find the count without a divisor so stop here continue; if(!isset($interval_counts[$div])){ $interval_counts[$div] = $this->getRankItemCounts($div);//cache results } $rank_count = 0; $istart = $min / $div; $iend = $istart + $amp / $div; for($i=$istart; $i<$iend; $i++){ if(isset($interval_counts[$div][$i+1])) $rank_count += $interval_counts[$div][$i+1]; } if(!$rank_count)continue; $idx = $max / $amp;
you should move the block “catalog/layer_view” located in the /layout/catalog.xml into the “header” block and change the template file.
but i dont really understand if that is what you dont know how to do or if you dont know how to make some javascript/css that make the effect.
I have many different stores all selling a variety of products, some sites needed a price range of $10-20, others needed a price range of $1,200-$1,300. I created an app/code/local/Mage/Catalog/Model/Layer/Filter/Price.php file and copy/pasted the contents from app/code/local/Mage/Catalog/Model/Layer/Filter/Price.php into it. I then re-wrote the getPriceRange function with the following version.
/** * Get price range for building filter steps * * This version finds a price range that is * 1) As small as possible (within constraints) * 2) while producing less than a maximum number of ranges * 3) and avoiding having a separate range for every item * * Configure this function by setting appropriate values for: * $max_ranges, $min_items, $step_sizes and $max_step_increase * * @return int */ public function getPriceRange() { $range = $this->getData('price_range'); if (is_null($range)) {
//Maximum number of price ranges to show: $max_ranges = 7;
//At least one price range must have at least this many items in it: $min_items = 3;
//First try ranges $0-$1,$1-$2... then $0-$10,$10-$20... then $0-$50,$50-$100... $step_sizes = array(1,10,50,100);
//After trying $0-$100,$100-$200... keep incrementing the step size by $100 $max_step_increase = 100;
//End the loop if the step size is bigger than the max price $maxPrice = $this->getMaxPriceInt(); $max_range = pow(10, (strlen(floor($maxPrice))-1));
//How many items are in the price range with the most items? sort($items); $max_count = array_pop($items); } while ($range<$max_range && (count($items)>$max_ranges-1 || $max_count<$min_items) ); //Keep trying bigger price ranges until: //1) The price range is bigger than the most expensive item // OR //2) We have less than $max_ranges price ranges // AND at least one has at least $min_items
Having read this very helpful thread I made some changes to the price filter and now it will break-up into ranges but it will also group ranges together if there are not enough products in the range. You can see how I did this here: http://www.magentocommerce.com/boards/viewthread/65135/#t233626
I am trying to modify an attribute that is set as a price type (Price/Sqft in my case), but the code modifications to Price.php getPriceRange function don’t seem to affect the attributes with a price type, but do appropriate change the groupings for normal Price. What am I missing? Thanks.
I have many different stores all selling a variety of products, some sites needed a price range of $10-20, others needed a price range of $1,200-$1,300. I created an app/code/local/Mage/Catalog/Model/Layer/Filter/Price.php file and copy/pasted the contents from app/code/local/Mage/Catalog/Model/Layer/Filter/Price.php into it. I then re-wrote the getPriceRange function with the following version.
/** * Get price range for building filter steps * * This version finds a price range that is * 1) As small as possible (within constraints) * 2) while producing less than a maximum number of ranges * 3) and avoiding having a separate range for every item * * Configure this function by setting appropriate values for: * $max_ranges, $min_items, $step_sizes and $max_step_increase * * @return int */ public function getPriceRange() { $range = $this->getData('price_range'); if (is_null($range)) {
//Maximum number of price ranges to show: $max_ranges = 7;
//At least one price range must have at least this many items in it: $min_items = 3;
//First try ranges $0-$1,$1-$2... then $0-$10,$10-$20... then $0-$50,$50-$100... $step_sizes = array(1,10,50,100);
//After trying $0-$100,$100-$200... keep incrementing the step size by $100 $max_step_increase = 100;
//End the loop if the step size is bigger than the max price $maxPrice = $this->getMaxPriceInt(); $max_range = pow(10, (strlen(floor($maxPrice))-1));
//How many items are in the price range with the most items? sort($items); $max_count = array_pop($items); } while ($range<$max_range && (count($items)>$max_ranges-1 || $max_count<$min_items) ); //Keep trying bigger price ranges until: //1) The price range is bigger than the most expensive item // OR //2) We have less than $max_ranges price ranges // AND at least one has at least $min_items
I am giving the price ranges in the range of 20$ and it was working fine earlier. but now the price option is disappeared with the category pages and search results . Is it any thing related to the cache issue ? Let me know why the price option disappear without changing any piece of code