public function screen() { if (!current_user_can('shopp_promotions')) { wp_die(__('You do not have sufficient permissions to access this page.')); } $table = ShoppDatabaseObject::tablename(ShoppPromo::$table); $defaults = array('page' => false, 'status' => false, 'type' => false, 'paged' => 1, 'per_page' => 20, 's' => ''); $args = array_merge($defaults, $_GET); extract($args, EXTR_SKIP); $url = add_query_arg(array_merge($_GET, array('page' => $this->page)), admin_url('admin.php')); $f = array('action', 'selected', 's'); $url = remove_query_arg($f, $url); $pagenum = absint($paged); $start = $per_page * ($pagenum - 1); $where = array(); if (!empty($s)) { $where[] = "name LIKE '%{$s}%'"; } if ($status) { $datesql = ShoppPromo::activedates(); switch (strtolower($status)) { case 'active': $where[] = "status='enabled' AND {$datesql}"; break; case 'inactive': $where[] = "status='enabled' AND NOT {$datesql}"; break; case 'enabled': $where[] = "status='enabled'"; break; case 'disabled': $where[] = "status='disabled'"; break; } } if ($type) { switch (strtolower($type)) { case 'catalog': $where[] = "target='Catalog'"; break; case 'cart': $where[] = "target='Cart'"; break; case 'cartitem': $where[] = "target='Cart Item'"; break; } } $select = sDB::select(array('table' => $table, 'columns' => 'SQL_CALC_FOUND_ROWS *', 'where' => $where, 'orderby' => 'created DESC', 'limit' => "{$start},{$per_page}")); $Promotions = sDB::query($select, 'array'); $count = sDB::found(); $num_pages = ceil($count / $per_page); $ListTable = ShoppUI::table_set_pagination($this->id, $count, $num_pages, $per_page); $states = array('active' => __('Active', 'Shopp'), 'inactive' => __('Not Active', 'Shopp'), 'enabled' => __('Enabled', 'Shopp'), 'disabled' => __('Disabled', 'Shopp')); $types = array('catalog' => __('Catalog Discounts', 'Shopp'), 'cart' => __('Cart Discounts', 'Shopp'), 'cartitem' => __('Cart Item Discounts', 'Shopp')); $num_pages = ceil($count / $per_page); $page_links = paginate_links(array('base' => add_query_arg('pagenum', '%#%'), 'format' => '', 'total' => $num_pages, 'current' => $pagenum)); include $this->ui('discounts.php'); }
public function delete() { if (empty($this->id)) { return; } $price = $this->id; parent::delete(); // clean up meta entries for deleted price $metatable = ShoppDatabaseObject::tablename('meta'); $query = "DELETE FROM {$metatable} WHERE context='price' and parent={$price}"; sDB::query($query); }
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; }
private function __construct() { $ImageSetting = new ShoppImageSetting(); $table = $ImageSetting->_table; $where = array("type='{$ImageSetting->type}'", "context='{$ImageSetting->context}'"); $options = compact('table', 'where'); $query = sDB::select($options); $this->populate(sDB::query($query, 'array', array($ImageSetting, 'loader'), false, 'name')); $this->found = sDB::found(); }
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; }
/** * Load the binary data of a specified resource * * @author Jonathan Davis * @since 1.1 * * @param string $uri The URI for the resource * @return string Binary data **/ public function load($uri) { if (!$uri) { return false; } $file = sDB::query("SELECT * FROM {$this->_table} WHERE {$this->_key}='{$uri}' LIMIT 1"); if (empty($file)) { shopp_error(Shopp::__('The requested asset could not be loaded from the database.'), SHOPP_ADMIN_ERR); return false; } return $file->data; }
/** * Load the report data * * @author Jonathan Davis * @since 1.3 * * @return void **/ public function load() { extract($this->options); // Map out time period based reports with index matching keys and period values if ($this->periods) { $this->timereport($starts, $ends, $scale); } $this->setup(); $query = $this->query(); if (empty($query)) { return; } $loaded = sDB::query($query, 'array', array($this, 'process')); if ($this->periods && $this->Chart) { foreach ($this->data as $index => &$record) { if (count(get_object_vars($record)) <= 1) { foreach ($this->columns as $column) { $record->{$column} = null; } } foreach ($this->chartseries as $series => $column) { $data = isset($record->{$column}) ? $record->{$column} : 0; $this->chartdata($series, $record->period, $data); } } } else { $this->data = $loaded; $this->total = count($loaded); } }
/** * Load active promotions * * @author Jonathan Davis * @since 1.3 * * @return array List of loaded ShoppOrderPromo objects **/ public function load() { if ($this->loaded) { return; } // Don't load twice in one request $table = ShoppDatabaseObject::tablename(ShoppPromo::$table); $where = array("status='enabled'", ShoppPromo::activedates(), "target IN ('" . join("','", self::$targets) . "')"); $orderby = 'target DESC'; $queryargs = compact('table', 'where', 'orderby'); $query = sDB::select($queryargs); $loaded = sDB::query($query, 'array', array('ShoppPromotions', 'loader')); if (!$loaded || 0 == count($loaded)) { return; } $this->populate($loaded); $this->loaded = true; }
/** * Destroy the entire product search index * * @api * @since 1.3 * * @return void **/ function shopp_empty_search_index() { $index_table = ShoppDatabaseObject::tablename(ContentIndex::$table); if (sDB::query("DELETE FROM {$index_table}")) { return true; } return false; }
/** * Verify the loaded record actually exists in the database * * @author Jonathan Davis * @since 1.1 * * @return boolean **/ public function exists($verify = false) { $key = $this->_key; if (empty($this->{$key})) { return false; } if ($verify) { $id = $this->{$key}; $exists = sDB::query("SELECT id FROM {$this->_table} WHERE {$key}='{$id}' LIMIT 1", 'auto', 'col', 'id'); return !empty($exists); } return true; }
/** * Interface processor for the customer list screen * * Handles processing customer list actions and displaying the * customer list screen * * @author Jonathan Davis * @return void **/ function memeberships() { $Shopp = Shopp::object(); $defaults = array('page' => false, 'deleting' => false, 'delete' => false, 'pagenum' => 1, 'per_page' => 20, 's' => ''); $args = array_merge($defaults, $_GET); extract($args, EXTR_SKIP); if ($page == $this->Admin->pagename('memberships') && !empty($deleting) && !empty($delete) && is_array($delete)) { foreach ($delete as $deletion) { $MemberPlan = new MemberPlan($deletion); $MemberPlan->delete(); } } if (!empty($_POST['save'])) { check_admin_referer('shopp-save-membership'); if ($_POST['id'] != "new") { $MemberPlan = new MemberPlan($_POST['id']); } else { $MemberPlan = new MemberPlan(); } $MemberPlan->updates($_POST); $MemberPlan->save(); $MemberPlan->load_stages(); $stages = array_keys($MemberPlan->stages); // Process updates foreach ($_POST['stages'] as $i => $stage) { if (empty($stage['id'])) { $Stage = new MemberStage($MemberPlan->id); $stage['parent'] = $MemberPlan->id; } else { $Stage = new MemberStage($MemberPlan->id, $stage['id']); } $Stage->updates($stage); $Stage->sortorder = $i; $Stage->save(); $Stage->content = array(); $stage_updates[] = $Stage->id; // If the stage data did not save, go to the next stage record if (empty($Stage->id)) { continue; } foreach ($stage['rules'] as $type => $rules) { foreach ($rules as $rule) { $AccessRule = new MemberAccess($Stage->id, $type, $rule['access']); if (empty($AccessRule->id)) { $AccessRule->save(); } // If access rule applies to all content, skip content cataloging if (strpos($AccessRule->value, '-all') !== false) { continue; } // Catalog content access rules for this access taxonomy foreach ($rule['content'] as $id => $name) { $CatalogEntry = new MemberContent($id, $AccessRule->id, $Stage->id); if (empty($CatalogEntry->id)) { $CatalogEntry->save(); } $Stage->content[$AccessRule->id][$id] = $name; } // endforeach $rule['content'] } // endforeach $rules } // endforeach $stage['rules'] $Stage->save(); // Secondary save for specific content rules } // endforeach $_POST['stages'] } $stageids = array_diff($stages, $stage_updates); if (!empty($stageids)) { $stagelist = join(',', $stageids); // Delete Catalog entries $ContentRemoval = new MemberContent(); sDB::query("DELETE FROM {$ContentRemoval->_table} WHERE 0 < FIND_IN_SET(parent,'{$stagelist}')"); // Delete Access taxonomies $AccessRemoval = new MemberAccess(); sDB::query("DELETE FROM {$AccessRemoval->_table} WHERE 0 < FIND_IN_SET(parent,'{$stagelist}')"); // Remove old stages $StageRemoval = new MemberStage(); sDB::query("DELETE FROM {$StageRemoval->_table} WHERE 0 < FIND_IN_SET(id,'{$stagelist}')"); } $pagenum = absint($pagenum); if (empty($pagenum)) { $pagenum = 1; } if (!$per_page || $per_page < 0) { $per_page = 20; } $index = $per_page * ($pagenum - 1); 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); } $membership_table = ShoppDatabaseObject::tablename(MemberPlan::$table); $MemberPlan = new MemberPlan(); $where = ''; // if (!empty($s)) { // $s = stripslashes($s); // 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 .= ((empty($where))?"WHERE ":" AND ")."c.company LIKE '%$keyword%'"; break; // case "login": $where .= ((empty($where))?"WHERE ":" AND ")."u.user_login LIKE '%$keyword%'"; break; // case "address": $where .= ((empty($where))?"WHERE ":" AND ")."(b.address LIKE '%$keyword%' OR b.xaddress='%$keyword%')"; break; // case "city": $where .= ((empty($where))?"WHERE ":" AND ")."b.city LIKE '%$keyword%'"; break; // case "province": // case "state": $where .= ((empty($where))?"WHERE ":" AND ")."b.state='$keyword'"; break; // case "zip": // case "zipcode": // case "postcode": $where .= ((empty($where))?"WHERE ":" AND ")."b.postcode='$keyword'"; break; // case "country": $where .= ((empty($where))?"WHERE ":" AND ")."b.country='$keyword'"; break; // } // } // } elseif (strpos($s,'@') !== false) { // $where .= ((empty($where))?"WHERE ":" AND ")."c.email='$s'"; // } else $where .= ((empty($where))?"WHERE ":" AND ")." (c.id='$s' OR CONCAT(c.firstname,' ',c.lastname) LIKE '%$s%' OR c.company LIKE '%$s%')"; // // } // if (!empty($starts) && !empty($ends)) $where .= ((empty($where))?"WHERE ":" AND ").' (UNIX_TIMESTAMP(c.created) >= '.$starts.' AND UNIX_TIMESTAMP(c.created) <= '.$ends.')'; $count = sDB::query("SELECT count(*) as total FROM {$MemberPlan->_table} AS c {$where}"); $query = "SELECT *\n\t\t\t\t\tFROM {$MemberPlan->_table}\n\t\t\t\t\tWHERE parent='{$MemberPlan->parent}'\n\t\t\t\t\t\tAND context='{$MemberPlan->context}'\n\t\t\t\t\t\tAND type='{$MemberPlan->type}'\n\t\t\t\t\tLIMIT {$index},{$per_page}"; $MemberPlans = sDB::query($query, 'array'); $num_pages = ceil($count->total / $per_page); $page_links = paginate_links(array('base' => add_query_arg('pagenum', '%#%'), 'format' => '', 'total' => $num_pages, 'current' => $pagenum)); $authentication = shopp_setting('account_system'); include SHOPP_ADMIN_PATH . "/memberships/memberships.php"; }
public function query($request = array()) { if (empty($request)) { $request = $_GET; } if (!empty($request['start'])) { list($month, $day, $year) = explode("/", $request['start']); $starts = mktime(0, 0, 0, $month, $day, $year); } if (!empty($request['end'])) { list($month, $day, $year) = explode("/", $request['end']); $ends = mktime(0, 0, 0, $month, $day, $year); } $where = "WHERE c.id IS NOT NULL "; if (isset($request['s']) && !empty($request['s'])) { $where .= " AND (id='{$request['s']}' OR firstname LIKE '%{$request['s']}%' OR lastname LIKE '%{$request['s']}%' OR CONCAT(firstname,' ',lastname) LIKE '%{$request['s']}%' OR transactionid LIKE '%{$request['s']}%')"; } if (!empty($request['start']) && !empty($request['end'])) { $where .= " AND (UNIX_TIMESTAMP(c.created) >= {$starts} AND UNIX_TIMESTAMP(c.created) <= {$ends})"; } $customer_table = ShoppDatabaseObject::tablename(Customer::$table); $billing_table = ShoppDatabaseObject::tablename(BillingAddress::$table); $shipping_table = ShoppDatabaseObject::tablename(ShippingAddress::$table); $offset = $this->set * $this->limit; $c = 0; $columns = array(); foreach ($this->selected as $column) { $columns[] = "{$column} AS col" . $c++; } $query = "SELECT " . join(",", $columns) . " FROM {$customer_table} AS c LEFT JOIN {$billing_table} AS b ON c.id=b.customer LEFT JOIN {$shipping_table} AS s ON c.id=s.customer {$where} GROUP BY c.id ORDER BY c.created ASC LIMIT {$offset},{$this->limit}"; $this->data = sDB::query($query, 'array'); }
/** * Interface processor for the product editor * * @author Jonathan Davis * @return void **/ public function screen() { $Shopp = Shopp::object(); if (!current_user_can('shopp_products')) { wp_die(__('You do not have sufficient permissions to access this page.')); } if (empty($Shopp->Product)) { $Product = new ShoppProduct(); $Product->status = "publish"; } else { $Product = $Shopp->Product; } $Product->slug = apply_filters('editable_slug', $Product->slug); $permalink = trailingslashit(Shopp::url()); $Price = new ShoppPrice(); $priceTypes = ShoppPrice::types(); $billPeriods = ShoppPrice::periods(); $workflows = array('continue' => Shopp::__('Continue Editing'), 'close' => Shopp::__('Products Manager'), 'new' => Shopp::__('New Product'), 'next' => Shopp::__('Edit Next'), 'previous' => Shopp::__('Edit Previous')); $taglist = array(); foreach ($Product->tags as $tag) { $taglist[] = $tag->name; } if ($Product->id && !empty($Product->images)) { $ids = join(',', array_keys($Product->images)); $CoverImage = reset($Product->images); $image_table = $CoverImage->_table; $Product->cropped = sDB::query("SELECT * FROM {$image_table} WHERE context='image' AND type='image' AND '2'=SUBSTRING_INDEX(SUBSTRING_INDEX(name,'_',4),'_',-1) AND parent IN ({$ids})", 'array', 'index', 'parent'); } $shiprates = shopp_setting('shipping_rates'); if (!empty($shiprates)) { ksort($shiprates); } $uploader = shopp_setting('uploader_pref'); if (!$uploader) { $uploader = 'flash'; } $process = empty($Product->id) ? 'new' : $Product->id; $_POST['action'] = add_query_arg(array_merge($_GET, array('page' => ShoppAdmin::pagename('products'))), admin_url('admin.php')); $post_type = ShoppProduct::posttype(); // Re-index menu options to maintain order in JS #2930 if (isset($Product->options['v']) || isset($Product->options['a'])) { $options = array_keys($Product->options); foreach ($options as $type) { foreach ($Product->options[$type] as $id => $menu) { $Product->options[$type][$type . $id] = $menu; $Product->options[$type][$type . $id]['options'] = array_values($menu['options']); unset($Product->options[$type][$id]); } } } else { foreach ($Product->options as &$menu) { $menu['options'] = array_values($menu['options']); } } do_action('add_meta_boxes', ShoppProduct::$posttype, $Product); do_action('add_meta_boxes_' . ShoppProduct::$posttype, $Product); do_action('do_meta_boxes', ShoppProduct::$posttype, 'normal', $Product); do_action('do_meta_boxes', ShoppProduct::$posttype, 'advanced', $Product); do_action('do_meta_boxes', ShoppProduct::$posttype, 'side', $Product); include $this->ui('editor.php'); }
/** * Provides markup for a unordered list widget of recent shoppers * * @api `shopp('storefront.recent-shoppers')` * @since 1.1 * * @param string $result The output * @param array $options The options * - **abbr**: `firstname` (firstname,lastname) Choose which name to abbreviate to maintain customer privacy * - **city**: `on` (on,off) Include the customer's city name * - **state**: `on` (on,off) Include the customer's state abbreviation * - **avatar**: `on` (on,off) Include the customer's avatar * - **size**: `48` Set the size of the customer avatar shown * - **show**: `5` Set the limit of the number of recent shoppers to show * @param ShoppStorefront $O The working object * @return string The markup for the widget **/ public static function recent_shoppers($result, $options, $O) { $defaults = array('abbr' => 'firstname', 'city' => true, 'state' => true, 'avatar' => true, 'size' => 48, 'show' => 5); $options = array_merge($defaults, $options); extract($options); $pt = ShoppDatabaseObject::tablename(ShoppPurchase::$table); $shoppers = sDB::query("SELECT firstname,lastname,email,city,state FROM {$pt} AS pt GROUP BY customer ORDER BY created DESC LIMIT {$show}", 'array'); if (empty($shoppers)) { return ''; } $_ = array(); $_[] = '<ul>'; foreach ($shoppers as $shopper) { if ('' == $shopper->firstname . $shopper->lastname) { continue; } if ('lastname' == $abbr) { $name = "{$shopper->firstname} " . $shopper->lastname[0] . "."; } else { $name = $shopper->firstname[0] . ". {$shopper->lastname}"; } $img = ''; if ($avatar) { $img = get_avatar($shopper->email, $size, '', $name); } $loc = ''; if ($state || $province) { $loc = $shopper->state; } if ($city) { $loc = "{$shopper->city}, {$loc}"; } $_[] = "<li><div>{$img}</div>{$name} <em>{$loc}</em></li>"; } $_[] = '</ul>'; return join('', $_); }
public function products_order() { check_admin_referer('wp_ajax_shopp_category_products_order'); if (empty($_POST['category']) || empty($_POST['position']) || !is_array($_POST['position'])) { die('0'); } global $wpdb; $updates = $_POST['position']; $category = (int) $_POST['category']; foreach ((array) $updates as $id => $position) { sDB::query("UPDATE {$wpdb->term_relationships} SET term_order='" . (int) $position . "' WHERE object_id='" . (int) $id . "' AND term_taxonomy_id='{$category}'"); } die('1'); }
/** * Load an existing product property index if it exists * * @author Jonathan Davis * @since 1.1 * * @param int $product Id of the indexed product * @param string $type Type of product property indexed * @return void **/ function load($product = false, $type = false) { $this->product = $product; $this->type = $type; if (empty($product) || empty($type)) { return false; } // Nothing to load $r = sDB::query("SELECT id,created FROM {$this->_table} WHERE product='{$product}' AND type='{$type}' LIMIT 1"); if (!empty($r->id)) { $this->id = $r->id; $this->created = mktimestamp($r->created); $this->_loaded = true; } }
public function images() { if (!current_user_can('shopp_settings')) { wp_die(__('You do not have sufficient permissions to access this page.')); } $defaults = array('paged' => 1, 'per_page' => 25, 'action' => false, 'selected' => array()); $args = array_merge($defaults, $_REQUEST); extract($args, EXTR_SKIP); $edit = false; if (isset($_GET['id'])) { $edit = (int) $_GET['id']; if ('new' == $_GET['id']) { $edit = 'new'; } } if (isset($_GET['delete']) || 'delete' == $action) { check_admin_referer('shopp-settings-images'); if (!empty($_GET['delete'])) { $selected[] = (int) $_GET['delete']; } $selected = array_filter($selected); foreach ($selected as $delete) { $Record = new ImageSetting((int) $delete); $Record->delete(); } } if (!empty($_POST['save'])) { check_admin_referer('shopp-settings-images'); $ImageSetting = new ImageSetting($edit); $_POST['name'] = sanitize_title_with_dashes($_POST['name']); $_POST['sharpen'] = floatval(str_replace('%', '', $_POST['sharpen'])); $ImageSetting->updates($_POST); if (!empty($ImageSetting->name)) { $ImageSetting->save(); } } $start = $per_page * ($paged - 1); $ImageSetting = new ImageSetting($edit); $table = $ImageSetting->_table; $columns = 'SQL_CALC_FOUND_ROWS *'; $where = array("type='{$ImageSetting->type}'", "context='{$ImageSetting->context}'"); $limit = "{$start},{$per_page}"; $options = compact('columns', 'useindex', 'table', 'joins', 'where', 'groupby', 'having', 'limit', 'orderby'); $query = sDB::select($options); $settings = sDB::query($query, 'array', array($ImageSetting, 'loader')); $total = sDB::found(); $num_pages = ceil($total / $per_page); $ListTable = ShoppUI::table_set_pagination($this->screen, $total, $num_pages, $per_page); $fit_menu = $ImageSetting->fit_menu(); $quality_menu = $ImageSetting->quality_menu(); $actions_menu = array('delete' => __('Delete', 'Shopp')); $json_settings = array(); $skip = array('created', 'modified', 'numeral', 'context', 'type', 'sortorder', 'parent'); foreach ($settings as &$Setting) { if (method_exists($Setting, 'json')) { $json_settings[$Setting->id] = $Setting->json($skip); } } include $this->ui('images.php'); }
/** * Renders the recent orders dashboard widget * * @author Jonathan Davis * @since 1.0 * * @return void **/ public static function orders_widget($args = false) { $defaults = array('before_widget' => '', 'before_title' => '', 'widget_name' => '', 'after_title' => '', 'after_widget' => ''); $args = array_merge($defaults, (array) $args); extract($args, EXTR_SKIP); $statusLabels = shopp_setting('order_status'); echo $before_widget; echo $before_title; echo $widget_name; echo $after_title; $purchasetable = ShoppDatabaseObject::tablename(ShoppPurchase::$table); $purchasedtable = ShoppDatabaseObject::tablename(Purchased::$table); $txnlabels = Lookup::txnstatus_labels(); if (!($Orders = get_transient('shopp_dashboard_orders'))) { $Orders = sDB::query("SELECT p.*,count(*) as items FROM (SELECT * FROM {$purchasetable} WHERE txnstatus != 'purchased' AND txnstatus != 'invoiced' ORDER BY created DESC LIMIT 6) AS p LEFT JOIN {$purchasedtable} AS i ON i.purchase=p.id GROUP BY p.id ORDER BY p.id DESC", 'array'); set_transient('shopp_dashboard_orders', $Orders, 90); // Keep for the next 1 minute } if (!empty($Orders)) { echo '<table class="widefat">' . '<thead>' . ' <tr>' . ' <th scope="col">' . __('Name', 'Shopp') . '</th>' . ' <th scope="col">' . __('Date', 'Shopp') . '</th>' . ' <th scope="col" class="num">' . Shopp::__('Items') . '</th>' . ' <th scope="col" class="num">' . Shopp::__('Total') . '</th>' . ' <th scope="col" class="num">' . Shopp::__('Status') . '</th>' . ' </tr>' . '</thead>' . ' <tbody id="orders" class="list orders">'; $even = false; foreach ($Orders as $Order) { $classes = array(); if ($even = !$even) { $classes[] = 'alternate'; } $txnstatus = isset($txnlabels[$Order->txnstatus]) ? $txnlabels[$Order->txnstatus] : $Order->txnstatus; $status = isset($statusLabels[$Order->status]) ? $statusLabels[$Order->status] : $Order->status; $contact = '' == $Order->firstname . $Order->lastname ? '(no contact name)' : $Order->firstname . ' ' . $Order->lastname; $url = add_query_arg(array('page' => ShoppAdmin()->pagename('orders'), 'id' => $Order->id), admin_url('admin.php')); $classes[] = strtolower(preg_replace('/[^\\w]/', '_', $Order->txnstatus)); echo '<tr class="' . join(' ', $classes) . '">' . ' <td><a class="row-title" href="' . $url . '" title="View "Order ' . $Order->id . '"">' . (empty($Order->firstname) && empty($Order->lastname) ? '(no contact name)' : $Order->firstname . ' ' . $Order->lastname) . '</a></td>' . ' <td>' . date("Y/m/d", mktimestamp($Order->created)) . '</td>' . ' <td class="num items">' . $Order->items . '</td>' . ' <td class="num total">' . money($Order->total) . '</td>' . ' <td class="num status">' . $statusLabels[$Order->status] . '</td>' . '</tr>'; } echo '</tbody></table>'; } else { echo '<p>' . Shopp::__('No orders, yet.') . '</p>'; } echo $after_widget; }
public function storage() { $Shopp = Shopp::object(); $Storage = $Shopp->Storage; $Storage->settings(); // Load all installed storage engines for settings UIs if (!empty($_POST['save'])) { check_admin_referer('shopp-system-storage'); shopp_set_formsettings(); // Re-initialize Storage Engines with new settings $Storage->settings(); $this->notice(Shopp::__('Shopp system settings saved.')); } elseif (!empty($_POST['rebuild'])) { $assets = ShoppDatabaseObject::tablename(ProductImage::$table); $query = "DELETE FROM {$assets} WHERE context='image' AND type='image'"; if (sDB::query($query)) { $updated = __('All cached images have been cleared.', 'Shopp'); } } // Build the storage options menu $storage = $engines = $storageset = array(); foreach ($Storage->active as $module) { $storage[$module->module] = $module->name; $engines[$module->module] = sanitize_title_with_dashes($module->module); $storageset[$module->module] = $Storage->get($module->module)->settings; } $Storage->ui(); // Setup setting UIs $ImageStorage = false; $DownloadStorage = false; if (isset($_POST['image-settings'])) { $ImageStorage = $Storage->get(shopp_setting('image_storage')); } if (isset($_POST['download-settings'])) { $DownloadStorage = $Storage->get(shopp_setting('product_storage')); } add_action('shopp_storage_engine_settings', array($Storage, 'templates')); include $this->ui('storage.php'); }
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'); }
public function smart(array $options = array()) { $this->name = __('Customers also bought…', 'Shopp'); $this->controls = false; $where = array("true=false"); $scope = array(); $Product = ShoppProduct(); $Order = ShoppOrder(); $Cart = $Order->Cart; // Use the current product is available if (!empty($Product->id)) { $this->product = $Product; } // Or load a product specified if (!empty($options['product'])) { if ('recent-cartitem' == $options['product']) { // Use most recently added item in the cart $this->product = new ShoppProduct($Cart->added()->product); } elseif (preg_match('/^[\\d+]$/', $options['product'])) { // Load by specified id $this->product = new ShoppProduct($options['product']); } else { $this->product = new ShoppProduct($options['product'], 'slug'); // Load by specified slug } } if (empty($this->product->id)) { $loading = compact('where'); $this->loading = array_merge($options, $loading); return; } $this->name = Shopp::__('Customers that bought "%s" also bought…', $this->product->name); $purchased = ShoppDatabaseObject::tablename(Purchased::$table); $query = "SELECT p2,((psum - (sum1 * sum2 / n)) / sqrt((sum1sq - pow(sum1, 2.0) / n) * (sum2sq - pow(sum2, 2.0) / n))) AS r, n\n\t\t\t\t\t\t\t\tFROM (\n\t\t\t\t\t\t\t\t\tSELECT n1.product AS p1,n2.product AS p2,SUM(n1.quantity) AS sum1,SUM(n2.quantity) AS sum2,\n\t\t\t\t\t\t\t\t\t\tSUM(n1.quantity * n1.quantity) AS sum1sq,SUM(n2.quantity * n2.quantity) AS sum2sq,\n\t\t\t\t\t\t\t\t\t\tSUM(n1.quantity * n2.quantity) AS psum,COUNT(*) AS n\n\t\t\t\t\t\t\t\t\tFROM {$purchased} AS n1\n\t\t\t\t\t\t\t\t\tLEFT JOIN {$purchased} AS n2 ON n1.purchase = n2.purchase\n\t\t\t\t\t\t\t\t\tWHERE n1.product != n2.product\n\t\t\t\t\t\t\t\t\tGROUP BY n1.product,n2.product\n\t\t\t\t\t\t\t\t) AS step1\n\t\t\t\t\t\t\t\tORDER BY r DESC, n DESC"; $cachehash = 'alsobought_' . md5($query); $cached = Shopp::cache_get($cachehash, 'shopp_collection_alsobought'); if ($cached) { $matches = $cached; } else { $matches = sDB::query($query, 'array', 'col', 'p2'); Shopp::cache_set($cachehash, $matches, 'shopp_collection_alsobought', 14400); //Expires in 4 hours } if (empty($matches)) { $loading = compact('where'); $this->loading = array_merge($options, $loading); return; } $where = array("p.id IN (" . join(',', $matches) . ")"); $loading = compact('columns', 'joins', 'where', 'groupby', 'order'); $this->loading = array_merge($options, $loading); if (isset($options['controls']) && Shopp::str_true($options['controls'])) { unset($this->controls); } }
/** * Retrieves the number of orders in each customized order status label * * @author Jonathan Davis * @return void **/ public function status_counts() { $table = ShoppDatabaseObject::tablename(ShoppPurchase::$table); $labels = shopp_setting('order_status'); if (empty($labels)) { return false; } $status = array(); $alltotal = sDB::query("SELECT count(*) AS total FROM {$table}", 'auto', 'col', 'total'); $r = sDB::query("SELECT status,COUNT(status) AS total FROM {$table} GROUP BY status ORDER BY status ASC", 'array', 'index', 'status'); $all = array('' => __('All Orders', 'Shopp')); $labels = $all + $labels; foreach ($labels as $id => $label) { $_ = new StdClass(); $_->label = $label; $_->id = $id; $_->total = 0; if (isset($r[$id])) { $_->total = (int) $r[$id]->total; } if ('' === $id) { $_->total = $alltotal; } $status[$id] = $_; } return $status; }
/** * Interface processor for the customer editor * * Handles rendering the interface, processing updated customer details * and handing saving them back to the database * * @author Jonathan Davis * @return void **/ public function screen() { if (!current_user_can('shopp_customers')) { wp_die(__('You do not have sufficient permissions to access this page.')); } $Customer = $this->load(); if ($Customer->exists()) { $purchase_table = ShoppDatabaseObject::tablename(ShoppPurchase::$table); $r = sDB::query("SELECT count(id) AS purchases,SUM(total) AS total FROM {$purchase_table} WHERE customer='{$Customer->id}' LIMIT 1"); $Customer->orders = $r->purchases; $Customer->total = $r->total; } $regions = ShoppLookup::country_zones(); include $this->ui('editor.php'); }
/** * Deletes the entire set of meta entries for the combined record * * @author Jonathan Davis * @since 1.1 * * @return boolean **/ function delete() { if (empty($this->id)) { return; } // @todo Delete all catalog entries related to this // $catalog = ShoppDatabaseObject::tablename(Catalog::$table); // sDB::query("DELETE FROM $this->_table WHERE parent='$id' AND context='membership'"); // Delete all meta data related to this entry sDB::query("DELETE FROM {$this->_table} WHERE parent='{$this->id}' AND context='membership'"); parent::delete(); }
/** * Creates a complete set of variant product options on a specified product, by letting you * specify the set of options types, and corresponding options. This function will create new variant options in the database and * will attach them to the specified product. * * @api * @since 1.2 * * @param int $product (required) The product id of the product that you wish to add the variant options to. * @param array $options (Description...) A two dimensional array describing the options. * The outer array is keyed on the name of the option type (Color, Size, Gender, etc.) * The inner contains the corresponding option values. * Ex. $options = array( 'Color' => array('Red','Blue'), 'Gender' => array('Male', 'Female') ); * @param string $summary (optional) Update product summary * @return array variant Price objects that have been created on the product. * **/ function shopp_product_set_variant_options($product = false, array $options = array(), $summary = 'save') { if (!$product || empty($options)) { shopp_debug(__FUNCTION__ . " failed: Missing required parameters."); return false; } $Product = new ShoppProduct($product); if (empty($Product->id)) { shopp_debug(__FUNCTION__ . " failed: Product not found for product id {$product}."); return false; } $Product->load_data(array('summary')); // Clean up old variations and variation meta $price_table = ShoppDatabaseObject::tablename(ShoppPrice::$table); $meta_table = ShoppDatabaseObject::tablename(MetasetObject::$table); sDB::query("DELETE p,m FROM {$price_table} p LEFT JOIN {$meta_table} m ON m.parent = p.id AND m.context='price' WHERE p.product='{$product}' AND p.context='variation'"); $prices = array(); $combos = _optioncombinations(array(), $options); $mapping = array(); foreach ($combos as $combo) { $Price = new ShoppPrice(); $Price->type = 'Shipped'; $Price->product = $product; $Price->context = 'variation'; list($Price->optionkey, $Price->options, $Price->label, $mapping) = $Product->optionmap($combo, $options); $Price->save(); shopp_set_meta($Price->id, 'price', 'options', $Price->options); $prices[] = $Price; } $metaopts = shopp_product_meta($product, 'options'); $metaopts['v'] = array(); $i = 1; foreach ($options as $optname => $option) { if (!isset($metaopts['v'][$i])) { $metaopts['v'][$i] = array('id' => $i, 'name' => $optname, 'options' => array()); } foreach ($option as $value) { $metaopts['v'][$i]['options'][$mapping[$optname][$value]] = array('id' => $mapping[$optname][$value], 'name' => $value, 'linked' => 'off'); } $i++; } shopp_set_product_meta($product, 'options', $metaopts); $Product->variants = 'on'; if ('save' == $summary) { $Product->sumup(); } return $prices; }
/** * Marks an individual product for summary recalculation * * Recalculating t * * @author Jonathan Davis * @since 1.3 * * @param integer $id The product ID to update * @return boolean True if successful, false otherwise **/ public static function rebuild($id) { $id = intval($id); $table = ShoppDatabaseObject::tablename(ProductSummary::$table); return sDB::query("UPDATE {$table} SET modified='" . self::RECALCULATE . "' WHERE product={$id} LIMIT 1"); }
public function keygen() { $message = ShoppCustomer()->email . serialize($this) . current_time('mysql'); $key = sha1($message); $limit = 25; $c = 0; while ((int) sDB::query("SELECT count(*) AS found FROM {$this->_table} WHERE dkey='{$key}'", 'auto', 'col', 'found') > 0) { $key = sha1($message . rand()); if ($c++ > $limit) { break; } } $this->dkey = $key; do_action_ref_array('shopp_download_keygen', array(&$this)); }
public function prepare_items() { $defaults = array('paged' => 1, 'per_page' => 25, 'action' => false, 'selected' => array()); $args = array_merge($defaults, $_GET); extract($args, EXTR_SKIP); $start = $per_page * ($paged - 1); $edit = false; $ImageSetting = new ShoppImageSetting($edit); $table = $ImageSetting->_table; $columns = 'SQL_CALC_FOUND_ROWS *'; $where = array("type='{$ImageSetting->type}'", "context='{$ImageSetting->context}'"); $limit = "{$start},{$per_page}"; $options = compact('columns', 'useindex', 'table', 'joins', 'where', 'groupby', 'having', 'limit', 'orderby'); $query = sDB::select($options); $this->items = sDB::query($query, 'array', array($ImageSetting, 'loader')); $found = sDB::found(); $json = array(); $skip = array('created', 'modified', 'numeral', 'context', 'type', 'sortorder', 'parent'); foreach ($this->items as &$Item) { if (method_exists($Item, 'json')) { $json[$Item->id] = $Item->json($skip); } } shopp_custom_script('imageset', 'var images = ' . json_encode($json) . ';'); $this->set_pagination_args(array('total_items' => $found, 'total_pages' => $found / $per_page, 'per_page' => $per_page)); }
/** * Loads all categories for the product list manager category filter menu * * @author Jonathan Davis * @return string HTML for a drop-down menu of categories **/ public function category($id) { global $wpdb; $p = "{$wpdb->posts} AS p"; $where = array(); $joins[$wpdb->term_relationships] = "INNER JOIN {$wpdb->term_relationships} AS tr ON (p.ID=tr.object_id)"; $joins[$wpdb->term_taxonomy] = "INNER JOIN {$wpdb->term_taxonomy} AS tt ON (tr.term_taxonomy_id=tt.term_taxonomy_id AND tt.term_id={$id})"; if (-1 == $id) { $joins[$wpdb->term_relationships] = "LEFT JOIN {$wpdb->term_relationships} AS tr ON (p.ID=tr.object_id)"; unset($joins[$wpdb->term_taxonomy]); $where[] = 'tr.object_id IS NULL'; $where[] = "p.post_status='publish'"; $where[] = "p.post_type='shopp_product'"; } $where = empty($where) ? '' : ' WHERE ' . join(' AND ', $where); if ('catalog-products' == $id) { $products = sDB::query("SELECT p.id,p.post_title AS name FROM {$p} {$where} ORDER BY name ASC", 'array', 'col', 'name', 'id'); } else { $products = sDB::query("SELECT p.id,p.post_title AS name FROM {$p} " . join(' ', $joins) . $where . " ORDER BY name ASC", 'array', 'col', 'name', 'id'); } return menuoptions($products, 0, true); }