/** * Interface processor for the product list manager * * @author Jonathan Davis * @return void **/ public function screen($workflow = false) { if (!current_user_can('shopp_categories')) { wp_die(__('You do not have sufficient permissions to access this page.')); } $defaults = array('pagenum' => 1, 'per_page' => 500, 'id' => 0, 's' => ''); $args = array_merge($defaults, $_GET); extract($args, EXTR_SKIP); $pagenum = absint($pagenum); if (empty($pagenum)) { $pagenum = 1; } if (!$per_page || $per_page < 0) { $per_page = 20; } $start = $per_page * ($pagenum - 1); $CategoryProducts = new ProductCategory($id); $CategoryProducts->load(array('order' => 'recommended', 'pagination' => false)); $num_pages = ceil($CategoryProducts->total / $per_page); $page_links = paginate_links(array('base' => add_query_arg(array('edit' => null, 'pagenum' => '%#%')), 'format' => '', 'total' => $num_pages, 'current' => $pagenum)); $action = esc_url(add_query_arg(array_merge(stripslashes_deep($_GET), array('page' => ShoppAdmin::pagename('categories'))), admin_url('admin.php'))); include $this->ui('products.php'); }
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']) . ' — ' . 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']) . ' — ' . 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']) . ' — ' . 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 } }
/** * Get a ShoppProductCategory object * * @api * @since 1.2 * * @param int $cat the category id * @param array $options (optional) loading options * @return bool|ProductCategory returns false on error, ProductCategory on success **/ function shopp_product_category($cat = false, $options = array()) { if (!$cat) { shopp_debug(__FUNCTION__ . " failed: Category id required."); return false; } $Cat = new ProductCategory((int) $cat); if (!$Cat->id) { return false; } $defaults = array('pagination' => false); $options = array_merge($defaults, $options); $Cat->load($options); return $Cat; }