Beispiel #1
0
 public function load_facets()
 {
     if ('off' == $this->facetedmenus) {
         return;
     }
     $output = '';
     $this->filters();
     $Storefront = ShoppStorefront();
     if (!$Storefront) {
         return;
     }
     $CategoryFilters =& $Storefront->browsing[$this->slug];
     $Filtered = new ProductCategory($this->id);
     $filtering = array_merge($Filtered->facetsql(array()), array('ids' => true, 'limit' => 1000));
     $Filtered->load($filtering);
     $ids = join(',', $Filtered->worklist());
     // Load price facet filters first
     if ('disabled' != $this->pricerange) {
         $Facet = $this->facets['price'];
         $Facet->link = add_query_arg(array('s_ff' => 'on', urlencode($Facet->slug) => ''), shopp('category', 'get-url'));
         if (!$this->loaded) {
             $this->load();
         }
         if ('auto' == $this->pricerange) {
             $ranges = auto_ranges($this->pricing->average, $this->pricing->max, $this->pricing->min, $this->pricing->uniques);
         } else {
             $ranges = $this->priceranges;
         }
         if (!empty($ranges)) {
             $casewhen = '';
             foreach ($ranges as $index => $r) {
                 $minprice = $r['max'] > 0 ? " AND minprice <= {$r['max']}" : "";
                 $casewhen .= " WHEN (minprice >= {$r['min']}{$minprice}) THEN {$index}";
             }
             $sumtable = ShoppDatabaseObject::tablename(ProductSummary::$table);
             $query = "SELECT count(*) AS total, CASE {$casewhen} END AS rangeid\n\t\t\t\t\tFROM {$sumtable}\n\t\t\t\t\tWHERE product IN ({$ids}) GROUP BY rangeid";
             $counts = sDB::query($query, 'array', 'col', 'total', 'rangeid');
             foreach ($ranges as $id => $range) {
                 if (!isset($counts[$id]) || $counts[$id] < 1) {
                     continue;
                 }
                 $label = money($range['min']) . ' &mdash; ' . money($range['max']);
                 if ($range['min'] == 0) {
                     $label = sprintf(__('Under %s', 'Shopp'), money($range['max']));
                 }
                 if ($range['max'] == 0) {
                     $label = sprintf(__('%s and up', 'Shopp'), money($range['min']));
                 }
                 $FacetFilter = new ProductCategoryFacetFilter();
                 $FacetFilter->label = $label;
                 $FacetFilter->param = urlencode($range['min'] . '-' . $range['max']);
                 $FacetFilter->count = $counts[$id];
                 $Facet->filters[$FacetFilter->param] = $FacetFilter;
             }
         }
         // END !empty($ranges)
     }
     // Identify facet menu types to treat numeric and string contexts properly @bug #2014
     $custom = array();
     foreach ($this->facets as $Facet) {
         if ('custom' == $Facet->type) {
             $custom[] = sDB::escape($Facet->name);
         }
     }
     // Load spec aggregation data
     $spectable = ShoppDatabaseObject::tablename(Spec::$table);
     $query = "SELECT spec.name,spec.value,\n\t\t\tIF(0 >= FIND_IN_SET(spec.name,'" . join(",", $custom) . "'),IF(spec.numeral > 0,spec.name,spec.value),spec.value) AS merge, count(DISTINCT spec.value) AS uniques,\n\t\t\tcount(*) AS count,avg(numeral) AS avg,max(numeral) AS max,min(numeral) AS min\n\t\t\tFROM {$spectable} AS spec\n\t\t\tWHERE spec.parent IN ({$ids}) AND spec.context='product' AND spec.type='spec' AND (spec.value != '' OR spec.numeral > 0) GROUP BY merge";
     $specdata = sDB::query($query, 'array', 'index', 'name', true);
     foreach ($this->specs as $spec) {
         if ('disabled' == $spec['facetedmenu']) {
             continue;
         }
         $slug = sanitize_title_with_dashes($spec['name']);
         if (!isset($this->facets[$slug])) {
             continue;
         }
         $Facet =& $this->facets[$slug];
         $Facet->link = add_query_arg(array('s_ff' => 'on', urlencode($Facet->slug) => ''), shopp('category', 'get-url'));
         // For custom menu presets
         switch ($spec['facetedmenu']) {
             case 'custom':
                 $data = $specdata[$Facet->name];
                 $counts = array();
                 foreach ($data as $d) {
                     $counts[$d->value] = $d->count;
                 }
                 foreach ($spec['options'] as $option) {
                     if (!isset($counts[$option['name']]) || $counts[$option['name']] < 1) {
                         continue;
                     }
                     $FacetFilter = new ProductCategoryFacetFilter();
                     $FacetFilter->label = $option['name'];
                     $FacetFilter->param = urlencode($option['name']);
                     $FacetFilter->count = $counts[$FacetFilter->label];
                     $Facet->filters[$FacetFilter->param] = $FacetFilter;
                 }
                 break;
             case 'ranges':
                 foreach ($spec['options'] as $i => $option) {
                     $matches = array();
                     $format = '%s-%s';
                     $next = 0;
                     if (isset($spec['options'][$i + 1])) {
                         if (preg_match('/(\\d+[\\.\\,\\d]*)/', $spec['options'][$i + 1]['name'], $matches)) {
                             $next = $matches[0];
                         }
                     }
                     $matches = array();
                     $range = array("min" => 0, "max" => 0);
                     if (preg_match('/^(.*?)(\\d+[\\.\\,\\d]*)(.*)$/', $option['name'], $matches)) {
                         $base = $matches[2];
                         $format = $matches[1] . '%s' . $matches[3];
                         if (!isset($spec['options'][$i + 1])) {
                             $range['min'] = $base;
                         } else {
                             $range = array("min" => $base, "max" => $next - 1);
                         }
                     }
                     if ($i == 1) {
                         $href = add_query_arg($slug, urlencode(sprintf($format, '0', $range['min'])), $link);
                         $label = __('Under ', 'Shopp') . sprintf($format, $range['min']);
                         $list .= '<li><a href="' . $href . '">' . $label . '</a></li>';
                     }
                     $href = add_query_arg($slug, urlencode(sprintf($format, $range['min'], $range['max'])), $link);
                     $label = sprintf($format, $range['min']) . ' &mdash; ' . sprintf($format, $range['max']);
                     if ($range['max'] == 0) {
                         $label = sprintf($format, $range['min']) . ' ' . __('and up', 'Shopp');
                     }
                     $list .= '<li><a href="' . $href . '">' . $label . '</a></li>';
                 }
                 break;
             default:
                 if (!isset($specdata[$Facet->name])) {
                     break;
                 }
                 $data = $specdata[$Facet->name];
                 if (!is_array($data)) {
                     $data = array($data);
                 }
                 if ($data[0]->min + $data[0]->max + $data[0]->avg == 0) {
                     // Generate facet filters from text values
                     foreach ($data as $option) {
                         $FacetFilter = new ProductCategoryFacetFilter();
                         $FacetFilter->label = $option->value;
                         $FacetFilter->param = urlencode($option->value);
                         $FacetFilter->count = $option->count;
                         $Facet->filters[$FacetFilter->param] = $FacetFilter;
                     }
                 } else {
                     $data = reset($data);
                     $format = '%s';
                     if (preg_match('/^(.*?)(\\d+[\\.\\,\\d]*)(.*)$/', $data->value, $matches)) {
                         $format = $matches[1] . '%s' . $matches[3];
                     }
                     $ranges = auto_ranges($data->avg, $data->max, $data->min, $data->uniques);
                     if (!empty($ranges)) {
                         $casewhen = '';
                         foreach ($ranges as $index => $r) {
                             $max = $r['max'] > 0 ? " AND spec.numeral <= {$r['max']}" : "";
                             $casewhen .= " WHEN (spec.numeral >= {$r['min']}{$max}) THEN {$index}";
                         }
                         $query = "SELECT count(*) AS total, CASE {$casewhen} END AS rangeid\n\t\t\t\t\t\t\t\tFROM {$spectable} AS spec\n\t\t\t\t\t\t\t\tWHERE spec.parent IN ({$ids}) AND spec.name='{$Facet->name}' AND spec.context='product' AND spec.type='spec' AND spec.numeral > 0 GROUP BY rangeid";
                         $counts = sDB::query($query, 'array', 'col', 'total', 'rangeid');
                         foreach ($ranges as $id => $range) {
                             if (!isset($counts[$id]) || $counts[$id] < 1) {
                                 continue;
                             }
                             $label = sprintf($format, $range['min']) . ' &mdash; ' . sprintf($format, $range['max']);
                             if ($range['min'] == 0) {
                                 $label = __('Under ', 'Shopp') . sprintf($format, $range['max']);
                             } elseif ($range['max'] == 0) {
                                 $label = sprintf($format, $range['min']) . ' ' . __('and up', 'Shopp');
                             }
                             $FacetFilter = new ProductCategoryFacetFilter();
                             $FacetFilter->label = $label;
                             $FacetFilter->param = urlencode($range['min'] . '-' . $range['max']);
                             $FacetFilter->count = $counts[$id];
                             $Facet->filters[$FacetFilter->param] = $FacetFilter;
                         }
                     }
                     // END !empty($ranges)
                 }
         }
         // END switch
     }
 }