public function screen() { $Shopp = Shopp::object(); if (!current_user_can('shopp_settings_checkout')) { wp_die(__('You do not have sufficient permissions to access this page.')); } $purchasetable = ShoppDatabaseObject::tablename(ShoppPurchase::$table); $next = sDB::query("SELECT IF ((MAX(id)) > 0,(MAX(id)+1),1) AS id FROM {$purchasetable} LIMIT 1"); $next_setting = shopp_setting('next_order_id'); if ($next->id > $next_setting) { $next_setting = $next->id; } $term_recount = false; if (!empty($_POST['save'])) { check_admin_referer('shopp-setup-management'); $next_order_id = $_POST['settings']['next_order_id'] = intval($_POST['settings']['next_order_id']); if ($next_order_id >= $next->id) { if (sDB::query("ALTER TABLE {$purchasetable} AUTO_INCREMENT=" . sDB::escape($next_order_id))) { $next_setting = $next_order_id; } } $_POST['settings']['order_shipfee'] = Shopp::floatval($_POST['settings']['order_shipfee']); // Recount terms when this setting changes if (isset($_POST['settings']['inventory']) && $_POST['settings']['inventory'] != shopp_setting('inventory')) { $term_recount = true; } shopp_set_formsettings(); $this->notice(Shopp::__('Management settings saved.'), 'notice', 20); } if ($term_recount) { $taxonomy = ProductCategory::$taxon; $terms = get_terms($taxonomy, array('hide_empty' => 0, 'fields' => 'ids')); if (!empty($terms)) { wp_update_term_count_now($terms, $taxonomy); } } $states = array(__('Map the label to an order state:', 'Shopp') => array_merge(array('' => ''), Lookup::txnstatus_labels())); $statusLabels = shopp_setting('order_status'); $statesLabels = shopp_setting('order_states'); $reasonLabels = shopp_setting('cancel_reasons'); if (empty($reasonLabels)) { $reasonLabels = array(__('Not as described or expected', 'Shopp'), __('Wrong size', 'Shopp'), __('Found better prices elsewhere', 'Shopp'), __('Product is missing parts', 'Shopp'), __('Product is defective or damaaged', 'Shopp'), __('Took too long to deliver', 'Shopp'), __('Item out of stock', 'Shopp'), __('Customer request to cancel', 'Shopp'), __('Item discontinued', 'Shopp'), __('Other reason', 'Shopp')); } $promolimit = array('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '15', '20', '25'); $lowstock = shopp_setting('lowstock_level'); if (empty($lowstock)) { $lowstock = 0; } include $this->ui('management.php'); }
/** * shopp_orders - get a list of purchases * * @api * @since 1.2 * * @param mixed $from (optional) mktime or SQL datetime, get purchases after this date/time. * @param mixed $to (optional) mktime or SQL datetime, get purchased before this date/time. * @param bool $items (optional default:true) load purchased items into the records, slightly slower operation * @param array $customers (optional) list of int customer ids to limit the purchases to. All customers by default. * @param int $limit (optional default:false) maximimum number of results to get, false for no limit * @param string $order (optional default:DESC) DESC or ASC, for sorting in ascending or descending order. * @param string $orderby (optional) The column used to sort records * @param bool $paidonly (optional) Restrict to orders where payment has been completed * @param bool $downloads (optional) Restrict to orders that have downloads * @return array of Purchase objects **/ function shopp_orders($from = false, $to = false, $items = true, array $customers = array(), $limit = false, $order = 'DESC', $orderby = 'id', $paidonly = false, $downloads = false) { $pt = ShoppDatabaseObject::tablename(ShoppPurchase::$table); $pd = ShoppDatabaseObject::tablename(ShoppPurchased::$table); $op = '<'; $where = array(); $dateregex = '/^([0-9]{2,4})-([0-1][0-9])-([0-3][0-9]) (?:([0-2][0-9]):([0-5][0-9]):([0-5][0-9]))?$/'; foreach (array($from, $to) as $datetime) { if (!$datetime) { continue; } if (1 == preg_match($dateregex, $datetime)) { $where[] = "'{$datetime}' {$op} p.created"; } else { if (is_int($datetime)) { $where[] = "FROM_UNIXTIME({$datetime}) {$op} p.created"; } } $op = '>='; } if (!empty($customers)) { $set = sDB::escape(implode(',', $customers)); $where[] = "0 < FIND_IN_SET(p.customer,'" . $set . "')"; } if ($paidonly) { $where[] = "p.txnstatus='captured'"; } if ($items && $downloads) { $where[] = " pd.download > 0"; } $where = empty($where) ? '' : 'WHERE ' . implode(' AND ', $where); if ((int) $limit > 0) { $limit = " LIMIT {$limit}"; } else { $limit = ''; } if (!in_array(strtolower($orderby), array('id', 'created', 'modified'))) { $orderby = 'id'; } if ($items) { $query = "SELECT pd.* FROM {$pd} AS pd INNER JOIN {$pt} AS p ON pd.purchase = p.id {$where} " . $limit; $purchased = sDB::query($query, 'array', '_shopp_order_purchased'); $orders = sDB::query("SELECT * FROM {$pt} WHERE FIND_IN_SET(id,'" . join(',', array_keys($purchased)) . "') ORDER BY {$orderby} " . ('DESC' == $order ? 'DESC' : 'ASC'), 'array', '_shopp_order_purchase', $purchased); } else { $query = "SELECT * FROM {$pt} AS p {$where} ORDER BY {$orderby} " . ('DESC' == $order ? 'DESC' : 'ASC') . $limit; $orders = sDB::query($query, 'array', '_shopp_order_purchase'); } return $orders; }
/** * Save an asset to the database * * @author Jonathan Davis * @since 1.1 * * @param Asset $asset Asset object the data is associated with * @param string $data Binary data or path to the file to be saved * @param string $type (optional) Type of data provided - binary (default) or file * @return string|boolean A URI for the resource or false if failed **/ public function save($asset, $data, $type = 'binary') { if (empty($data)) { return false; } if ('binary' != $type) { if (!is_readable($data)) { die("Could not read the file."); } // Die because we can't use ShoppError $data = file_get_contents($data); } $data = sDB::escape($data); if (!$asset->id) { $uri = sDB::query("INSERT {$this->_table} SET data='{$data}'"); } else { sDB::query("UPDATE {$this->_table} SET data='{$data}' WHERE {$this->_key}='{$asset->uri}'"); } if (isset($uri)) { return $uri; } return false; }
/** * Handles orders list loading * * @author Jonathan Davis * @since 1.2.1 * * @return void **/ public function loader() { if (!current_user_can('shopp_orders')) { return; } $defaults = array('page' => false, 'deleting' => false, 'selected' => false, 'update' => false, 'newstatus' => false, 'pagenum' => 1, 'paged' => 1, 'per_page' => 20, 'start' => '', 'end' => '', 'status' => false, 's' => '', 'range' => '', 'startdate' => '', 'enddate' => ''); $args = array_merge($defaults, $_GET); extract($args, EXTR_SKIP); $url = add_query_arg(array_merge($_GET, array('page' => $this->Admin->pagename('orders'))), admin_url('admin.php')); if ($page == "shopp-orders" && !empty($deleting) && !empty($selected) && is_array($selected) && current_user_can('shopp_delete_orders')) { foreach ($selected as $selection) { $Purchase = new ShoppPurchase($selection); $Purchase->load_purchased(); foreach ($Purchase->purchased as $purchased) { $Purchased = new ShoppPurchased($purchased->id); $Purchased->delete(); } $Purchase->delete(); } if (count($selected) == 1) { $this->notice(__('Order deleted.', 'Shopp')); } else { $this->notice(sprintf(__('%d orders deleted.', 'Shopp'), count($selected))); } } $statusLabels = shopp_setting('order_status'); if (empty($statusLabels)) { $statusLabels = array(''); } $txnstatus_labels = Lookup::txnstatus_labels(); if ($update == "order" && !empty($selected) && is_array($selected)) { foreach ($selected as $selection) { $Purchase = new ShoppPurchase($selection); $Purchase->status = $newstatus; $Purchase->save(); } if (count($selected) == 1) { $this->notice(__('Order status updated.', 'Shopp')); } else { $this->notice(sprintf(__('%d orders updated.', 'Shopp'), count($selected))); } } $Purchase = new ShoppPurchase(); $offset = get_option('gmt_offset') * 3600; if (!empty($start)) { $startdate = $start; list($month, $day, $year) = explode("/", $startdate); $starts = mktime(0, 0, 0, $month, $day, $year); } if (!empty($end)) { $enddate = $end; list($month, $day, $year) = explode("/", $enddate); $ends = mktime(23, 59, 59, $month, $day, $year); } $pagenum = absint($paged); $start = $per_page * ($pagenum - 1); $where = array(); $joins = array(); if (!empty($status) || $status === '0') { $where[] = "status='" . sDB::escape($status) . "'"; } if (!empty($s)) { $s = stripslashes($s); $search = array(); if (preg_match_all('/(\\w+?)\\:(?="(.+?)"|(.+?)\\b)/', $s, $props, PREG_SET_ORDER) > 0) { foreach ($props as $query) { $keyword = sDB::escape(!empty($query[2]) ? $query[2] : $query[3]); switch (strtolower($query[1])) { case "txn": $search[] = "txnid='{$keyword}'"; break; case "company": $search[] = "company LIKE '%{$keyword}%'"; break; case "gateway": $search[] = "gateway LIKE '%{$keyword}%'"; break; case "cardtype": $search[] = "cardtype LIKE '%{$keyword}%'"; break; case "address": $search[] = "(address LIKE '%{$keyword}%' OR xaddress='%{$keyword}%')"; break; case "city": $search[] = "city LIKE '%{$keyword}%'"; break; case "province": case "state": $search[] = "state='{$keyword}'"; break; case "zip": case "zipcode": case "postcode": $search[] = "postcode='{$keyword}'"; break; case "country": $search[] = "country='{$keyword}'"; break; case "promo": case "discount": $meta_table = ShoppDatabaseObject::tablename(ShoppMetaObject::$table); $joins[$meta_table] = "INNER JOIN {$meta_table} AS m ON m.parent = o.id AND context='purchase'"; $search[] = "m.value LIKE '%{$keyword}%'"; break; case "product": $purchased = ShoppDatabaseObject::tablename(Purchased::$table); $joins[$purchased] = "INNER JOIN {$purchased} AS p ON p.purchase = o.id"; $search[] = "p.name LIKE '%{$keyword}%' OR p.optionlabel LIKE '%{$keyword}%' OR p.sku LIKE '%{$keyword}%'"; break; } } if (empty($search)) { $search[] = "(id='{$s}' OR CONCAT(firstname,' ',lastname) LIKE '%{$s}%')"; } $where[] = "(" . join(' OR ', $search) . ")"; } elseif (strpos($s, '@') !== false) { $where[] = "email='" . sDB::escape($s) . "'"; } else { $where[] = "(id='{$s}' OR CONCAT(firstname,' ',lastname) LIKE '%" . sDB::escape($s) . "%')"; } } if (!empty($starts) && !empty($ends)) { $where[] = "created BETWEEN '" . sDB::mkdatetime($starts) . "' AND '" . sDB::mkdatetime($ends) . "'"; } if (!empty($customer)) { $where[] = "customer=" . intval($customer); } $where = !empty($where) ? "WHERE " . join(' AND ', $where) : ''; $joins = join(' ', $joins); $countquery = "SELECT count(*) as total,SUM(IF(txnstatus IN ('authed','captured'),total,NULL)) AS sales,AVG(IF(txnstatus IN ('authed','captured'),total,NULL)) AS avgsale FROM {$Purchase->_table} AS o {$joins} {$where} ORDER BY o.created DESC LIMIT 1"; $this->ordercount = sDB::query($countquery, 'object'); $query = "SELECT o.* FROM {$Purchase->_table} AS o {$joins} {$where} ORDER BY created DESC LIMIT {$start},{$per_page}"; $this->orders = sDB::query($query, 'array', 'index', 'id'); $num_pages = ceil($this->ordercount->total / $per_page); if ($paged > 1 && $paged > $num_pages) { Shopp::redirect(add_query_arg('paged', null, $url)); } }
public function query($request = array()) { $defaults = array('status' => false, 's' => false, 'start' => false, 'end' => false); $request = array_merge($defaults, $_GET); extract($request); if (!empty($start)) { list($month, $day, $year) = explode('/', $start); $start = mktime(0, 0, 0, $month, $day, $year); } if (!empty($end)) { list($month, $day, $year) = explode('/', $end); $end = mktime(23, 59, 59, $month, $day, $year); } $where = array(); $joins = array(); if (!empty($status) || $status === '0') { $where[] = "status='" . sDB::escape($status) . "'"; } if (!empty($s)) { $s = stripslashes($s); $search = array(); if (preg_match_all('/(\\w+?)\\:(?="(.+?)"|(.+?)\\b)/', $s, $props, PREG_SET_ORDER) > 0) { foreach ($props as $query) { $keyword = sDB::escape(!empty($query[2]) ? $query[2] : $query[3]); switch (strtolower($query[1])) { case "txn": $search[] = "txnid='{$keyword}'"; break; case "company": $search[] = "company LIKE '%{$keyword}%'"; break; case "gateway": $search[] = "gateway LIKE '%{$keyword}%'"; break; case "cardtype": $search[] = "cardtype LIKE '%{$keyword}%'"; break; case "address": $search[] = "(address LIKE '%{$keyword}%' OR xaddress='%{$keyword}%')"; break; case "city": $search[] = "city LIKE '%{$keyword}%'"; break; case "province": case "state": $search[] = "state='{$keyword}'"; break; case "zip": case "zipcode": case "postcode": $search[] = "postcode='{$keyword}'"; break; case "country": $search[] = "country='{$keyword}'"; break; case "promo": case "discount": $meta_table = ShoppDatabaseObject::tablename(ShoppMetaObject::$table); $joins[$meta_table] = "INNER JOIN {$meta_table} AS discounts ON discounts.parent = o.id AND discounts.name='discounts' AND discounts.context='purchase'"; $search[] = "discounts.value LIKE '%{$keyword}%'"; break; } } if (empty($search)) { $search[] = "(o.id='{$s}' OR CONCAT(firstname,' ',lastname) LIKE '%{$s}%')"; } $where[] = "(" . join(' OR ', $search) . ")"; } elseif (strpos($s, '@') !== false) { $where[] = "email='" . sDB::escape($s) . "'"; } else { $where[] = "(o.id='{$s}' OR CONCAT(firstname,' ',lastname) LIKE '%" . sDB::escape($s) . "%')"; } } if (!empty($start) && !empty($end)) { $where[] = '(UNIX_TIMESTAMP(o.created) >= ' . $start . ' AND UNIX_TIMESTAMP(o.created) <= ' . $end . ')'; } if (!empty($customer)) { $where[] = "customer=" . intval($customer); } $where = !empty($where) ? "WHERE " . join(' AND ', $where) : ''; $purchasetable = ShoppDatabaseObject::tablename(ShoppPurchase::$table); $purchasedtable = ShoppDatabaseObject::tablename(ShoppPurchased::$table); $offset = $this->set * $this->limit; $c = 0; $columns = array(); $purchasedcols = false; $discountcols = false; $addoncols = false; foreach ($this->selected as $column) { $columns[] = "{$column} AS col" . $c++; if (false !== strpos($column, 'p.')) { $purchasedcols = true; } if (false !== strpos($column, 'discounts')) { $discountcols = true; } if (false !== strpos($column, 'addons')) { $addoncols = true; } } if ($purchasedcols) { $FROM = "FROM {$purchasedtable} AS p INNER JOIN {$purchasetable} AS o ON o.id=p.purchase"; } else { $FROM = "FROM {$purchasetable} AS o"; } if ($discountcols) { $meta_table = ShoppDatabaseObject::tablename(ShoppMetaObject::$table); $joins[$meta_table] = "LEFT JOIN {$meta_table} AS discounts ON discounts.parent = o.id AND discounts.name='discounts' AND discounts.context='purchase'"; } if ($addoncols) { $meta_table = ShoppDatabaseObject::tablename(ShoppMetaObject::$table); $joins[$meta_table . '_2'] = "LEFT JOIN {$meta_table} AS addons ON addons.parent = p.id AND addons.type='addon' AND addons.context='purchased'"; } $joins = join(' ', $joins); $query = "SELECT " . join(",", $columns) . " {$FROM} {$joins} {$where} ORDER BY o.created ASC LIMIT {$offset},{$this->limit}"; $this->data = sDB::query($query, 'array'); }
/** * Load a single record by the primary key or a custom query * * @author Jonathan Davis * @since 1.0 * * @param $where - An array of key/values to be built into an SQL where clause * or * @param $id - A string containing the id for db object's predefined primary key * or * @param $id - A string containing the object's id value * @param $key - A string of the name of the db object's primary key **/ public function load() { $args = func_get_args(); if (empty($args[0])) { return false; } $where = ""; if (is_array($args[0])) { foreach ($args[0] as $key => $id) { $where .= ($where == "" ? "" : " AND ") . "{$key}='" . sDB::escape($id) . "'"; } } else { $id = $args[0]; $key = $this->_key; if (!empty($args[1])) { $key = $args[1]; } $where = $key . "='" . sDB::escape($id) . "'"; } $r = sDB::query("SELECT * FROM {$this->_table} WHERE {$where} LIMIT 1", 'object'); $this->populate($r); if (!empty($this->id)) { return true; } return false; }
public function management() { $Shopp = Shopp::object(); if (!current_user_can('shopp_settings_checkout')) { wp_die(__('You do not have sufficient permissions to access this page.')); } $purchasetable = ShoppDatabaseObject::tablename(ShoppPurchase::$table); $next = sDB::query("SELECT IF ((MAX(id)) > 0,(MAX(id)+1),1) AS id FROM {$purchasetable} LIMIT 1"); $next_setting = shopp_setting('next_order_id'); if ($next->id > $next_setting) { $next_setting = $next->id; } if (!empty($_POST['save'])) { check_admin_referer('shopp-setup-management'); $next_order_id = $_POST['settings']['next_order_id'] = intval($_POST['settings']['next_order_id']); if ($next_order_id >= $next->id) { if (sDB::query("ALTER TABLE {$purchasetable} AUTO_INCREMENT=" . sDB::escape($next_order_id))) { $next_setting = $next_order_id; } } shopp_set_formsettings(); $this->notice(Shopp::__('Management settings saved.'), 'notice', 20); } $states = array(__('Map the label to an order state:', 'Shopp') => array_merge(array('' => ''), Lookup::txnstatus_labels())); $statusLabels = shopp_setting('order_status'); $statesLabels = shopp_setting('order_states'); $reasonLabels = shopp_setting('cancel_reasons'); if (empty($reasonLabels)) { $reasonLabels = array(__('Not as described or expected', 'Shopp'), __('Wrong size', 'Shopp'), __('Found better prices elsewhere', 'Shopp'), __('Product is missing parts', 'Shopp'), __('Product is defective or damaaged', 'Shopp'), __('Took too long to deliver', 'Shopp'), __('Item out of stock', 'Shopp'), __('Customer request to cancel', 'Shopp'), __('Item discontinued', 'Shopp'), __('Other reason', 'Shopp')); } include $this->ui('management.php'); }
function load() { $args = func_get_args(); if (empty($args[0])) { return false; } if (!is_array($args[0])) { return false; } $where = ""; foreach ($args[0] as $key => $id) { $where .= ($where == "" ? "" : " AND ") . "{$key}='" . sDB::escape($id) . "'"; } $r = sDB::query("SELECT * FROM {$this->_table} WHERE {$where}", 'array'); foreach ($r as $row) { $meta = new ShoppMetaObject(); $meta->populate($row, '', array()); $this->meta[$meta->id] = $meta; $this->named[$meta->name] =& $this->meta[$meta->id]; } if (isset($row) && count($row) == 0) { $this->_loaded = false; } $this->_loaded = true; return $this->_loaded; }
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 } }
public function select_customer() { check_admin_referer('wp_ajax_shopp_select_customer'); $defaults = array('page' => false, 'paged' => 1, 'per_page' => 7, 'status' => false, 's' => ''); $args = wp_parse_args($_REQUEST, $defaults); extract($args, EXTR_SKIP); if (!empty($s)) { $s = stripslashes($s); $search = sDB::escape($s); $where = array(); if (preg_match_all('/(\\w+?)\\:(?="(.+?)"|(.+?)\\b)/', $s, $props, PREG_SET_ORDER)) { foreach ($props as $search) { $keyword = !empty($search[2]) ? $search[2] : $search[3]; switch (strtolower($search[1])) { case "company": $where[] = "c.company LIKE '%{$keyword}%'"; break; case "login": $where[] = "u.user_login LIKE '%{$keyword}%'"; break; case "address": $where[] = "(b.address LIKE '%{$keyword}%' OR b.xaddress='%{$keyword}%')"; break; case "city": $where[] = "b.city LIKE '%{$keyword}%'"; break; case "province": case "state": $where[] = "b.state='{$keyword}'"; break; case "zip": case "zipcode": case "postcode": $where[] = "b.postcode='{$keyword}'"; break; case "country": $where[] = "b.country='{$keyword}'"; break; } } } elseif (strpos($s, '@') !== false) { $where[] = "c.email LIKE '%{$search}%'"; } elseif (is_numeric($s)) { $where[] = "c.phone='{$search}'"; } else { $where[] = "(CONCAT(c.firstname,' ',c.lastname) LIKE '%{$search}%' OR c.company LIKE '%{$s}%' OR u.user_login LIKE '%{$s}%')"; } $pagenum = absint($paged); if (empty($pagenum)) { $pagenum = 1; } $index = $per_page * ($pagenum - 1); $customer_table = ShoppDatabaseObject::tablename(Customer::$table); $billing_table = ShoppDatabaseObject::tablename(BillingAddress::$table); $purchase_table = ShoppDatabaseObject::tablename(ShoppPurchase::$table); global $wpdb; $users_table = $wpdb->users; $select = array('columns' => 'SQL_CALC_FOUND_ROWS c.*,city,state,country,user_login', 'table' => "{$customer_table} as c", 'joins' => array($billing_table => "LEFT JOIN {$billing_table} AS b ON b.customer=c.id AND b.type='billing'", $users_table => "LEFT JOIN {$users_table} AS u ON u.ID=c.wpuser AND (c.wpuser IS NULL OR c.wpuser != 0)"), 'where' => $where, 'groupby' => "c.id", 'orderby' => "c.created DESC", 'limit' => "{$index},{$per_page}"); $query = sDB::select($select); } // if (!empty($starts) && !empty($ends)) $where[] = ' (UNIX_TIMESTAMP(c.created) >= '.$starts.' AND UNIX_TIMESTAMP(c.created) <= '.$ends.')'; $list = sDB::query($query, 'array', 'index', 'id'); $results = array(); foreach ($list as $entry) { $results[] = array('id' => $entry->id, 'user' => $entry->user, 'gravatar' => get_avatar($entry->email, 32), 'firstname' => $entry->firstname, 'lastname' => $entry->lastname, 'company' => $entry->company, 'email' => $entry->email, 'lastname' => $entry->lastname, 'phone' => $entry->phone); } header('Content-Type: application/json; charset=utf-8'); echo json_encode($results); exit; $url = admin_url('admin-ajax.php'); ?> <html> <head> <link rel="stylesheet" id="wp-admin" href="<?php echo admin_url('css/wp-admin.css'); ?> " type="text/css" media="all" /> <link rel="stylesheet" id="shopp-admin" href="<?php echo SHOPP_ADMIN_URI . '/styles/admin.css'; ?> " type="text/css" media="all" /> </head> <body id="customer-select"> <?php if (!empty($Customers)) { ?> <ul> <?php foreach ($Customers as $Customer) { ?> <li><a href="<?php echo add_query_arg(array('order-action' => 'change-customer', 'page' => $_GET['page'], 'id' => (int) $_GET['id'], 'customerid' => $Customer->id), admin_url('admin.php')); ?> " target="_parent"> <?php $wp_user = get_userdata($Customer->wpuser); $userlink = add_query_arg('user_id', $Customer->wpuser, admin_url('user-edit.php')); echo get_avatar($Customer->wpuser, 48); ?> <?php echo "<strong>{$Customer->firstname} {$Customer->lastname}</strong>"; if (!empty($Customer->company)) { echo ", {$Customer->company}"; } ?> <?php if (!empty($Customer->email)) { echo "<br />{$Customer->email}"; } ?> <?php if (!empty($Customer->phone)) { echo "<br />{$Customer->phone}"; } ?> </a> </li> <?php } ?> </ul> <?php } else { ?> <?php _e('No customers found.', 'Shopp'); ?> <?php } ?> </body> </html> <?php exit; }
public function prepare_items() { $defaults = array('page' => false, 'deleting' => false, 'selected' => false, 'update' => false, 'newstatus' => false, 'pagenum' => 1, 'paged' => 1, 'per_page' => 20, 'start' => '', 'end' => '', 'status' => false, 's' => '', 'range' => '', 'startdate' => '', 'enddate' => ''); $args = array_merge($defaults, $this->request()); extract($args, EXTR_SKIP); // $url = $this->url($_GET); $statusLabels = shopp_setting('order_status'); if (empty($statusLabels)) { $statusLabels = array(''); } $txnstatus_labels = Lookup::txnstatus_labels(); $Purchase = new ShoppPurchase(); $offset = get_option('gmt_offset') * 3600; if ($this->request('start')) { list($month, $day, $year) = explode("/", $this->request('start')); $starts = mktime(0, 0, 0, $month, $day, $year); } if ($this->request('end')) { list($month, $day, $year) = explode("/", $this->request('end')); $ends = mktime(23, 59, 59, $month, $day, $year); } $pagenum = absint($paged); $start = $per_page * ($pagenum - 1); $where = array(); $joins = array(); if (!empty($status) || '0' === $status) { $where[] = "status='" . sDB::escape($status) . "'"; } if (!empty($s)) { $s = stripslashes($s); $search = array(); if (preg_match_all('/(\\w+?)\\:(?="(.+?)"|(.+?)\\b)/', $s, $props, PREG_SET_ORDER) > 0) { foreach ($props as $query) { $keyword = sDB::escape(!empty($query[2]) ? $query[2] : $query[3]); switch (strtolower($query[1])) { case "txn": $search[] = "txnid='{$keyword}'"; break; case "company": $search[] = "company LIKE '%{$keyword}%'"; break; case "gateway": $search[] = "gateway LIKE '%{$keyword}%'"; break; case "cardtype": $search[] = "cardtype LIKE '%{$keyword}%'"; break; case "address": $search[] = "(address LIKE '%{$keyword}%' OR xaddress='%{$keyword}%')"; break; case "city": $search[] = "city LIKE '%{$keyword}%'"; break; case "province": case "state": $search[] = "state='{$keyword}'"; break; case "zip": case "zipcode": case "postcode": $search[] = "postcode='{$keyword}'"; break; case "country": $search[] = "country='{$keyword}'"; break; case "promo": case "discount": $meta_table = ShoppDatabaseObject::tablename(ShoppMetaObject::$table); $joins[$meta_table] = "INNER JOIN {$meta_table} AS m ON m.parent = o.id AND context='purchase'"; $search[] = "m.value LIKE '%{$keyword}%'"; break; case "product": $purchased = ShoppDatabaseObject::tablename(Purchased::$table); $joins[$purchased] = "INNER JOIN {$purchased} AS p ON p.purchase = o.id"; $search[] = "p.name LIKE '%{$keyword}%' OR p.optionlabel LIKE '%{$keyword}%' OR p.sku LIKE '%{$keyword}%'"; break; } } if (empty($search)) { $search[] = "(id='{$s}' OR CONCAT(firstname,' ',lastname) LIKE '%{$s}%')"; } $where[] = "(" . join(' OR ', $search) . ")"; } elseif (strpos($s, '@') !== false) { $where[] = "email='" . sDB::escape($s) . "'"; } else { $where[] = "(id='{$s}' OR CONCAT(firstname,' ',lastname) LIKE '%" . sDB::escape($s) . "%')"; } } if (!empty($starts) && !empty($ends)) { $where[] = "created BETWEEN '" . sDB::mkdatetime($starts) . "' AND '" . sDB::mkdatetime($ends) . "'"; } if (!empty($customer)) { $where[] = "customer=" . intval($customer); } $where = !empty($where) ? "WHERE " . join(' AND ', $where) : ''; $joins = join(' ', $joins); $countquery = "SELECT count(*) as total,SUM(IF(txnstatus IN ('authed','captured'),total,NULL)) AS sales,AVG(IF(txnstatus IN ('authed','captured'),total,NULL)) AS avgsale FROM {$Purchase->_table} AS o {$joins} {$where} ORDER BY o.created DESC LIMIT 1"; $this->ordercount = sDB::query($countquery, 'object'); $query = "SELECT o.* FROM {$Purchase->_table} AS o {$joins} {$where} ORDER BY created DESC LIMIT {$start},{$per_page}"; $this->items = sDB::query($query, 'array', 'index', 'id'); $num_pages = ceil($this->ordercount->total / $per_page); if ($paged > 1 && $paged > $num_pages) { Shopp::redirect(add_query_arg('paged', null, $url)); } $Gateways = Shopp::object()->Gateways; $this->gateways = array_merge($Gateways->modules, array('ShoppFreeOrder' => $Gateways->freeorder)); $this->statuses = (array) shopp_setting('order_status'); $this->txnstatuses = ShoppLookup::txnstatus_labels(); // Convert other date formats to numeric but preserve the order of the month/day/year or day/month/year $date_format = get_option('date_format'); $date_format = preg_replace("/[^A-Za-z0-9]/", '', $date_format); // Force month display to numeric with leading zeros $date_format = str_replace(array('n', 'F', 'M'), 'm/', $date_format); // Force day display to numeric with leading zeros $date_format = str_replace(array('j'), 'd/', $date_format); // Force year display to 4-digits $date_format = str_replace('y', 'Y/', $date_format); $this->dates = trim($date_format, '/'); $this->set_pagination_args(array('total_items' => $this->ordercount->total, 'total_pages' => $this->ordercount->total / $per_page, 'per_page' => $per_page)); }
public function upgrade_120() { // 1.2 schema changes $db_version = ShoppSettings::dbversion(); if ($db_version < 1120) { $this->upschema('schema-120.sql'); } global $wpdb; // Clear the shopping session table $shopping_table = ShoppDatabaseObject::tablename('shopping'); sDB::query("DELETE FROM {$shopping_table}"); if ($db_version <= 1140) { $summary_table = ShoppDatabaseObject::tablename('summary'); // Force summaries to rebuild sDB::query("UPDATE {$summary_table} SET modified='0000-00-00 00:00:01'"); } $purchase_table = ShoppDatabaseObject::tablename('purchase'); sDB::query("UPDATE {$purchase_table} SET txnstatus='captured' WHERE txnstatus='CHARGED'"); sDB::query("UPDATE {$purchase_table} SET txnstatus='voided' WHERE txnstatus='VOID'"); if ($db_version <= 1130) { // Move settings to meta table $meta_table = ShoppDatabaseObject::tablename('meta'); $setting_table = ShoppDatabaseObject::tablename('setting'); sDB::query("INSERT INTO {$meta_table} (context, type, name, value, created, modified) SELECT 'shopp', 'setting', name, value, created, modified FROM {$setting_table}"); // Clean up unnecessary duplicate settings shopp_rmv_setting('data_model'); shopp_rmv_setting('updates'); shopp_rmv_setting('shopp_setup'); shopp_rmv_setting('maintenance'); // Re-load the Shopp settings registry ShoppSettings()->load(); shopp_set_setting('maintenance', 'on'); $db_version = intval(shopp_setting('db_version')); // Force inventory in 1.2 on to mimic 1.1 behavior (inventory tracking always on) shopp_set_setting('inventory', 'on'); // Convert Shopp 1.1.x shipping settings to Shopp 1.2-compatible settings $active_shipping = array(); $regions = Lookup::regions(); $countries = Lookup::countries(); $areas = Lookup::country_areas(); $calcnaming = array('FlatRates::order' => 'OrderRates', 'FlatRates::item' => 'ItemRates', 'FreeOption' => 'FreeOption', 'ItemQuantity::range' => 'ItemQuantity', 'OrderAmount::range' => 'OrderAmount', 'OrderWeight::range' => 'OrderWeight'); $shipping_rates = shopp_setting('shipping_rates'); foreach ((array) $shipping_rates as $id => $old) { if (isset($calcnaming[$old['method']])) { // Add to active setting registry for that calculator class $calcname = $calcnaming[$old['method']]; if (!isset(${$calcname}) && !is_array(${$calcname})) { ${$calcname} = array(); } ${$calcname}[] = true; $active_shipping[$calcname] = ${$calcname}; // Define the setting name $settingid = end(array_keys(${$calcname})); $setting_name = $calcname . '-' . $settingid; } else { // Not a calculator, must be a shipping rate provider module, add it to the active roster $active_shipping[$old['name']] = true; continue; } $new = array(); $new['label'] = $old['name']; list($new['mindelivery'], $new['maxdelivery']) = explode('-', $old['delivery']); $new['fallback'] = 'off'; // Not used in legacy settings $oldkeys = array_keys($old); $old_destinations = array_diff($oldkeys, array('name', 'delivery', 'method', 'max')); $table = array(); foreach ($old_destinations as $old_dest) { $_ = array(); if ('Worldwide' == $old_dest) { $d = '*'; } $region = array_search($old_dest, $regions); if (false !== $region) { $d = "{$region}"; } if (isset($countries[$old_dest])) { $country = $countries[$old_dest]; $region = $country['region']; $d = "{$region}, {$old_dest}"; } foreach ($areas as $countrykey => $countryarea) { $areakeys = array_keys($countryarea); $area = array_search($old_dest, $areakeys); if (false !== $area) { $country = $countrykey; $region = $countries[$countrykey]['region']; $area = $areakeys[$area]; $d = "{$region}, {$country}, {$area}"; break; } } $_['destination'] = $d; $_['postcode'] = '*'; // Postcodes are new in 1.2, hardcode to wildcard if (isset($old['max']) && !empty($old['max'])) { // Capture tiered rates $_['tiers'] = array(); $prior = 1; foreach ($old['max'] as $index => $oldthreshold) { $tier = array('threshold' => 0, 'rate' => 0); if (in_array($oldthreshold, array('+', '>'))) { $tier['threshold'] = $prior + 1; } elseif (1 == $oldthreshold) { $tier['threshold'] = 1; } else { $tier['threshold'] = $prior + 1; } $prior = $oldthreshold; $tier['rate'] = $old[$old_dest][$index]; $_['tiers'][] = $tier; } } else { $_['rate'] = $old[$old_dest][0]; } // Capture flat rates $table[] = $_; } $new['table'] = $table; shopp_set_setting($setting_name, $new); // Save the converted settings } // End foreach($shipping_rates) to convert old shipping calculator setting format shopp_set_setting('active_shipping', $active_shipping); // Save the active shipping options } if ($db_version <= 1121) { $address_table = ShoppDatabaseObject::tablename('address'); $billing_table = ShoppDatabaseObject::tablename('billing'); $shipping_table = ShoppDatabaseObject::tablename('shipping'); // Move billing address data to the address table sDB::query("INSERT INTO {$address_table} (customer, type, address, xaddress, city, state, country, postcode, created, modified)\n\t\t\t\t\t\tSELECT customer, 'billing', address, xaddress, city, state, country, postcode, created, modified FROM {$billing_table}"); sDB::query("INSERT INTO {$address_table} (customer, type, address, xaddress, city, state, country, postcode, created, modified)\n\t\t\t\t\t\tSELECT customer, 'shipping', address, xaddress, city, state, country, postcode, created, modified FROM {$shipping_table}"); } // Migrate to WP custom posts & taxonomies if ($db_version <= 1131) { // Copy products to posts $catalog_table = ShoppDatabaseObject::tablename('catalog'); $product_table = ShoppDatabaseObject::tablename('product'); $price_table = ShoppDatabaseObject::tablename('price'); $summary_table = ShoppDatabaseObject::tablename('summary'); $meta_table = ShoppDatabaseObject::tablename('meta'); $category_table = ShoppDatabaseObject::tablename('category'); $tag_table = ShoppDatabaseObject::tablename('tag'); $purchased_table = ShoppDatabaseObject::tablename('purchased'); $index_table = ShoppDatabaseObject::tablename('index'); $post_type = 'shopp_product'; // Create custom post types from products, temporarily use post_parent for link to original product entry sDB::query("INSERT INTO {$wpdb->posts} (post_type, post_name, post_title, post_excerpt, post_content, post_status, post_date, post_date_gmt, post_modified, post_modified_gmt, post_parent)\n\t\t\t\t\t\t\tSELECT '{$post_type}', slug, name, summary, description, status, created, created, modified, modified, id FROM {$product_table}"); // Update purchased table product column with new Post ID so sold counts can be updated sDB::query("UPDATE {$purchased_table} AS pd JOIN {$wpdb->posts} AS wp ON wp.post_parent=pd.product AND wp.post_type='{$post_type}' SET pd.product=wp.ID"); // Update product links for prices and meta sDB::query("UPDATE {$price_table} AS price JOIN {$wpdb->posts} AS wp ON price.product=wp.post_parent SET price.product=wp.ID WHERE wp.post_type='{$post_type}'"); sDB::query("UPDATE {$meta_table} AS meta JOIN {$wpdb->posts} AS wp ON meta.parent=wp.post_parent AND wp.post_type='{$post_type}' AND meta.context='product' SET meta.parent=wp.ID"); sDB::query("UPDATE {$index_table} AS i JOIN {$wpdb->posts} AS wp ON i.product=wp.post_parent AND wp.post_type='{$post_type}' SET i.product=wp.ID"); // Preliminary summary data sDB::query("INSERT INTO {$summary_table} (product, featured, variants, addons, modified)\n\t\t\t\t\t\t SELECT wp.ID, p.featured, p.variations, p.addons, '0000-00-00 00:00:01'\n\t\t\t\t\t\t FROM {$product_table} AS p\n\t\t\t\t\t\t JOIN {$wpdb->posts} as wp ON p.id=wp.post_parent AND wp.post_type='{$post_type}'"); // Move product options column to meta setting sDB::query("INSERT INTO {$meta_table} (parent, context, type, name, value)\n\t\t\t\t\t\tSELECT wp.ID, 'product', 'meta', 'options', options\n\t\t\t\t\t\tFROM {$product_table} AS p\n\t\t\t\t\t\tJOIN {$wpdb->posts} AS wp ON p.id=wp.post_parent AND wp.post_type='{$post_type}'"); // Migrate Shopp categories and tags to WP taxonomies // Are there tag entries in the meta table? Old dev data present use meta table tags. No? use tags table. $dev_migration = $db_version >= 1120; // Copy categories and tags to WP taxonomies $tag_current_table = $dev_migration ? "{$meta_table} WHERE context='catalog' AND type='tag'" : $tag_table; $terms = sDB::query("(SELECT id, 'shopp_category' AS taxonomy, name, parent, description, slug FROM {$category_table})\n\t\t\t\t\t\t\t\t\t\t\tUNION\n\t\t\t\t\t\t\t\t\t\t(SELECT id, 'shopp_tag' AS taxonomy, name, 0 AS parent, '' AS description, name AS slug FROM {$tag_current_table}) ORDER BY id", 'array'); // Prep category images for the move $category_image_offset = 65535; sDB::query("UPDATE {$meta_table} set parent=parent+{$category_image_offset} WHERE context='category' AND type='image'"); $mapping = array(); $children = array(); $tt_ids = array(); foreach ($terms as $term) { $term_id = (int) $term->id; $taxonomy = $term->taxonomy; if (!isset($mapping[$taxonomy])) { $mapping[$taxonomy] = array(); } if (!isset($children[$taxonomy])) { $children[$taxonomy] = array(); } $name = $term->name; $parent = $term->parent; $description = $term->description; $slug = strpos($term->slug, ' ') === false ? $term->slug : sanitize_title_with_dashes($term->slug); $term_group = 0; if ($exists = sDB::query("SELECT term_id, term_group FROM {$wpdb->terms} WHERE slug = '{$slug}'", 'array')) { $term_group = $exists[0]->term_group; $id = $exists[0]->term_id; $num = 2; do { $alternate = sDB::escape($slug . "-" . $num++); $alternate_used = sDB::query("SELECT slug FROM {$wpdb->terms} WHERE slug='{$alternate}'"); } while ($alternate_used); $slug = $alternate; if (empty($term_group)) { $term_group = sDB::query("SELECT MAX(term_group) AS term_group FROM {$wpdb->terms} GROUP BY term_group", 'auto', 'col', 'term_group'); sDB::query("UPDATE {$wpdb->terms} SET term_group='{$term_group}' WHERE term_id='{$id}'"); } } // Move the term into the terms table $wpdb->query($wpdb->prepare("INSERT INTO {$wpdb->terms} (name, slug, term_group) VALUES (%s, %s, %d)", $name, $slug, $term_group)); $mapping[$taxonomy][$term_id] = (int) $wpdb->insert_id; // Map the old id to the new id $term_id = $mapping[$taxonomy][$term_id]; // Update the working id to the new id if (!isset($tt_ids[$taxonomy])) { $tt_ids[$taxonomy] = array(); } if ('shopp_category' == $taxonomy) { // If the parent term has already been added to the terms table, set the new parent id if (isset($mapping[$taxonomy][$parent])) { $parent = $mapping[$taxonomy][$parent]; } else { // Parent hasn't been created, keep track of children for the parent to do a mass update when the parent term record is created if (!isset($children[$taxonomy][$parent])) { $children[$taxonomy][$parent] = array(); } $children[$taxonomy][$parent][] = $term_id; } if (!empty($children[$taxonomy][$term->id])) { // If there are children already created for this term, update their parent to our new id $wpdb->query("UPDATE {$wpdb->term_taxonomy} SET parent={$term_id} WHERE term_id IN (" . join(', ', $children[$taxonomy][$term->id]) . ")"); } // Associate the term to the proper taxonomy and parent terms $wpdb->query($wpdb->prepare("INSERT INTO {$wpdb->term_taxonomy} (term_id, taxonomy, description, parent, count) VALUES ( %d, %s, %s, %d, %d)", $term_id, $taxonomy, $description, $parent, 0)); $tt_ids[$taxonomy][$term_id] = (int) $wpdb->insert_id; if (!empty($term_id)) { // Move category settings to meta $metafields = array('spectemplate', 'facetedmenus', 'variations', 'pricerange', 'priceranges', 'specs', 'options', 'prices'); foreach ($metafields as $field) { sDB::query("INSERT INTO {$meta_table} (parent, context, type, name, value)\n\t\t\t\t\t\t\t\t\t\t\tSELECT {$term_id}, 'category', 'meta', '{$field}', {$field}\n\t\t\t\t\t\t\t\t\t\t\tFROM {$category_table}\n\t\t\t\t\t\t\t\t\t\t\tWHERE id={$term->id}"); } // Update category images to new term ids sDB::query("UPDATE {$meta_table} set parent='{$term_id}' WHERE parent='" . ((int) $term->id + $category_image_offset) . "' AND context='category' AND type='image'"); } } if ('shopp_tag' == $taxonomy) { $wpdb->query($wpdb->prepare("INSERT INTO {$wpdb->term_taxonomy} (term_id, taxonomy, description, parent, count) VALUES ( %d, %s, %s, %d, %d)", $term_id, $taxonomy, $description, $parent, 0)); $tt_ids[$taxonomy][$term_id] = (int) $wpdb->insert_id; } } update_option('shopp_category_children', ''); // Re-catalog custom post type_products term relationships (new taxonomical catalog) from old Shopp catalog table $wp_taxonomies = array(0 => 'shopp_category', 1 => 'shopp_tag', 'category' => 'shopp_category', 'tag' => 'shopp_tag'); $cols = 'wp.ID AS product, c.parent, c.type'; $where = "type='category' OR type='tag'"; if ($db_version >= 1125) { $cols = 'wp.ID AS product, c.parent, c.taxonomy, c.type'; $where = "taxonomy=0 OR taxonomy=1"; } $rels = sDB::query("SELECT {$cols} FROM {$catalog_table} AS c LEFT JOIN {$wpdb->posts} AS wp ON c.product=wp.post_parent AND wp.post_type='{$post_type}' WHERE {$where}", 'array'); foreach ((array) $rels as $r) { $object_id = $r->product; $taxonomy = $wp_taxonomies[$db_version >= 1125 ? $r->taxonomy : $r->type]; $term_id = $mapping[$taxonomy][$r->parent]; if (!isset($tt_ids[$taxonomy])) { continue; } if (!isset($tt_ids[$taxonomy][$term_id])) { continue; } $tt_id = $tt_ids[$taxonomy][$term_id]; if (empty($tt_id)) { continue; } sDB::query("INSERT {$wpdb->term_relationships} (object_id, term_taxonomy_id) VALUES ({$object_id}, {$tt_id})"); } if (isset($tt_ids['shopp_category'])) { wp_update_term_count_now($tt_ids['shopp_category'], 'shopp_category'); } if (isset($tt_ids['shopp_tag'])) { wp_update_term_count_now($tt_ids['shopp_tag'], 'shopp_tag'); } // Clear custom post type parents sDB::query("UPDATE {$wpdb->posts} SET post_parent=0 WHERE post_type='{$post_type}'"); } // END if ($db_version <= 1131) if ($db_version <= 1133) { // Ditch old WP pages for pseudorific new ones $search = array(); $shortcodes = array('[catalog]', '[cart]', '[checkout]', '[account]'); foreach ($shortcodes as $string) { $search[] = "post_content LIKE '%{$string}%'"; } $results = sDB::query("SELECT ID, post_title AS title, post_name AS slug, post_content FROM {$wpdb->posts} WHERE post_type='page' AND (" . join(" OR ", $search) . ")", 'array'); $pages = $trash = array(); foreach ($results as $post) { $trash[] = $post->ID; foreach ($shortcodes as $code) { if (strpos($post->post_content, $code) === false) { continue; } $pagename = trim($code, '[]'); $pages[$pagename] = array('title' => $post->title, 'slug' => $post->slug); } // end foreach $shortcodes } // end foreach $results shopp_set_setting('storefront_pages', $pages); sDB::query("UPDATE {$wpdb->posts} SET post_name=CONCAT(post_name, '-deprecated'), post_status='trash' where ID IN (" . join(', ', $trash) . ")"); } // Move needed price table columns to price meta records if ($db_version <= 1135) { $meta_table = ShoppDatabaseObject::tablename('meta'); $price_table = ShoppDatabaseObject::tablename('price'); // Move 'options' to meta 'options' record sDB::query("INSERT INTO {$meta_table} (parent, context, type, name, value, created, modified)\n\t\t\t\t\t\tSELECT id, 'price', 'meta', 'options', options, created, modified FROM {$price_table}"); // Merge 'weight', 'dimensions' and 'donation' columns to a price 'settings' record sDB::query("INSERT INTO {$meta_table} (parent, context, type, name, value, created, modified)\n\t\t\t\t\t\t\tSELECT id, 'price', 'meta', 'settings',\n\t\t\t\t\t\t\tCONCAT('a:2:{s:10:\"dimensions\";',\n\t\t\t\t\t\t\t\tIF(weight = 0 AND dimensions = '0', 'a:0:{}',\n\t\t\t\t\t\t\t\t\tIF(dimensions = '0',\n\t\t\t\t\t\t\t\t\t\tCONCAT(\n\t\t\t\t\t\t\t\t\t\t\t'a:1:{s:6:\"weight\";s:', CHAR_LENGTH(weight), ':\"', weight, '\";}'\n\t\t\t\t\t\t\t\t\t\t), dimensions\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t), 's:8:\"donation\";', IF(donation='', 'N;', donation), '}'\n\t\t\t\t\t\t\t), created, modified FROM {$price_table}"); } // END if ($db_version <= 1135) if ($db_version <= 1145) { // Update purchase gateway property to use gateway class names // for proper order event handling on 1.1-generated orders $gateways = array('PayPal Standard' => 'PayPalStandard', 'PayPal Expresss' => 'PayPalExpress', 'PayPal Pro' => 'PayPalPro', '2Checkout.com' => '_2Checkout', 'Authorize.Net' => 'AuthorizeNet', 'Google Checkout' => 'GoogleCheckout', 'HSBC ePayments' => 'HSBCepayments', 'iDeal Mollie' => 'iDealMollie', 'Manual Processing' => 'ManualProcessing', 'Merchant Warrior' => 'MerchantWarrior', 'Offline Payment' => 'OfflinePayment', 'PayPal Payflow Pro' => 'PayflowPro', 'Test Mode' => 'TestMode'); foreach ($gateways as $name => $classname) { sDB::query("UPDATE {$purchase_table} SET gateway='{$classname}' WHERE gateway='{$name}'"); } } // END if ($db_version <= 1145) if ($db_version <= 1148) { $price_table = ShoppDatabaseObject::tablename('price'); sDB::query("UPDATE {$price_table} SET optionkey=(options*7001) WHERE context='addon'"); } if ($db_verison <= 1150) { $meta_table = ShoppDatabaseObject::tablename('meta'); sDB::query("DELETE {$meta_table} FROM {$meta_table} LEFT OUTER JOIN (SELECT MAX(id) AS keepid FROM {$meta_table} WHERE context='category' AND type='meta' GROUP BY parent, name) AS keepRowTable ON {$meta_table}.id = keepRowTable.keepid WHERE keepRowTable.keepid IS NULL AND context='category' AND type='meta'"); } }
/** * Save session data * * Inserts a new session record, or updates an existing record. When the session * needs secured @see ShoppSessionFramework::secured(), the session data is * encrypted first. * * @since 1.0 * * @return bool True if successful, false otherwise **/ public function save() { // Don't update the session for prefetch requests (via <link rel="next" /> tags) currently FF-only if (isset($_SERVER['HTTP_X_MOZ']) && 'prefetch' == $_SERVER['HTTP_X_MOZ']) { return false; } if (empty($this->session)) { return false; } // Do not save if there is no session id if (false === $this->data) { return false; } // Encryption failed because of no SSL, do not save $data = sDB::escape(addslashes(serialize($this->data))); $this->encrypt($data); $now = current_time('mysql'); $query = "UPDATE {$this->_table} SET ip='{$this->ip}',stash='{$this->stash}',data='{$data}',modified='{$now}' WHERE session='{$this->session}'"; $result = sDB::query($query); if (!$result) { trigger_error("Could not save session updates to the database."); } do_action('shopp_session_saved'); return true; }
/** * Reload a stashed session into an active session * * @since 1.3 * * @param string $session The session ID to load from cold storage * @return void */ public function reload($session) { $meta_table = ShoppDatabaseObject::tablename('meta'); $now = current_time('mysql'); $query = "UPDATE {$this->_table} AS s, {$meta_table} AS m\n\t\t\t\t\tSET s.created=m.created,s.modified='{$now}',s.data=m.value\n\t\t\t\t\tWHERE s.session=m.name AND m.context='shopping' AND m.type='session' AND m.name='" . sDB::escape($session) . "'"; if (sDB::query($query)) { $this->load(); } do_action('shopp_reload'); do_action('shopp_resession'); }