Пример #1
0
 function query()
 {
     $this->options = array_merge(array('orderby' => '(pr.stock/pr.stocked)', 'order' => 'ASC'), $this->options);
     extract($this->options, EXTR_SKIP);
     $where = array();
     $where[] = "pr.inventory='on'";
     $where = join(" AND ", $where);
     if (!in_array(strtoupper($order), array('ASC', 'DESC'))) {
         $order = 'DESC';
     }
     if (!in_array(strtolower($orderby), array('inventory'))) {
         $orderby = '(pr.stock/pr.stocked)';
     }
     $ordercols = "{$orderby} {$order}";
     $id = "pr.product,' ',pr.id";
     $product_table = WPDatabaseObject::tablename(ShoppProduct::$table);
     $summary_table = ShoppDatabaseObject::tablename(ProductSummary::$table);
     $price_table = ShoppDatabaseObject::tablename('price');
     $query = "SELECT CONCAT({$id}) AS id,\n\t\t\t\t\t\t\tCONCAT(p.post_title,' ',pr.label) AS product,\n\t\t\t\t\t\t\tpr.stock AS inventory,\n\t\t\t\t\t\t\tpr.stocked AS stocked,\n\t\t\t\t\t\t\t(pr.stock/pr.stocked)*100 AS level\n\t\t\t\t\tFROM {$price_table} AS pr\n\t\t\t\t\tJOIN {$product_table} AS p ON p.ID=pr.product\n\t\t\t\t\tWHERE {$where}\n\t\t\t\t\tGROUP BY CONCAT({$id}) ORDER BY {$ordercols}";
     return $query;
 }
Пример #2
0
 public function query()
 {
     $this->options = array_merge(array('orderby' => 'orders', 'order' => 'desc'), $this->options);
     extract($this->options, EXTR_SKIP);
     $where = array();
     $where[] = "o.created BETWEEN '" . sDB::mkdatetime($starts) . "' AND '" . sDB::mkdatetime($ends) . "'";
     $where[] = "orders.txnstatus IN ('authed','captured')";
     $where = join(" AND ", $where);
     if (!in_array($order, array('asc', 'desc'))) {
         $order = 'desc';
     }
     if (!in_array($orderby, array('orders', 'sold', 'grossed'))) {
         $orderby = 'orders';
     }
     $ordercols = "{$orderby} {$order}";
     $id = "o.product,' ',o.price";
     $purchase_table = ShoppDatabaseObject::tablename('purchase');
     $purchased_table = ShoppDatabaseObject::tablename('purchased');
     $product_table = WPDatabaseObject::tablename(ShoppProduct::$table);
     $price_table = ShoppDatabaseObject::tablename('price');
     $query = "SELECT CONCAT({$id}) AS id,\n\t\t\t\t\t\t\tCONCAT(p.post_title,' ', IF(pr.context != 'product',pr.label,'')) AS product,\n\t\t\t\t\t\t\tpr.sku as sku,\n\t\t\t\t\t\t\tSUM(o.quantity) AS sold,\n\t\t\t\t\t\t\tCOUNT(DISTINCT o.purchase) AS orders,\n\t\t\t\t\t\t\tSUM(o.total) AS grossed\n\t\t\t\t\tFROM {$purchased_table} AS o INNER JOIN {$purchase_table} AS orders ON orders.id=o.purchase\n\t\t\t\t\tJOIN {$product_table} AS p ON p.ID=o.product\n\t\t\t\t\tJOIN {$price_table} AS pr ON pr.id=o.price\n\t\t\t\t\tWHERE {$where}\n\t\t\t\t\tGROUP BY CONCAT({$id}) ORDER BY {$ordercols}";
     return $query;
 }
Пример #3
0
 public function load()
 {
     $args = func_get_args();
     if (empty($args[0])) {
         return false;
     }
     if (count($args) == 2) {
         list($id, $key) = $args;
         if (empty($key)) {
             $key = $this->_key;
         }
         $p = array($key => $id);
     }
     if (is_array($args[0])) {
         $p = $args[0];
     }
     $class = get_class($this);
     $p['post_type'] = get_class_property($class, 'posttype');
     parent::load($p);
 }
Пример #4
0
 public function poststub()
 {
     global $wp_query;
     if (!$wp_query->is_main_query()) {
         return;
     }
     $this->filters();
     $stub = new WPDatabaseObject();
     $stub->init('posts');
     $stub->ID = 0;
     $stub->post_name = '';
     $stub->comment_status = 'closed';
     // Force comments closed
     $stub->post_title = $this->title;
     $stub->post_content = '';
     $stub->post_excerpt = ' ';
     // Prevent wp_trim_excerpt from calling the_content filter
     $stub->post_type = ShoppPages::QUERYVAR;
     // Setup labels
     $labels = new stdClass();
     $labels->name = $this->title();
     $stub->labels = $labels;
     $wp_query->queried_object = $stub;
     $wp_query->posts = array($stub);
     return $stub;
 }
Пример #5
0
 public function loader($workflow = false)
 {
     if (!current_user_can('shopp_products')) {
         return;
     }
     add_screen_option('per_page', array('label' => __('Products Per Page', 'Shopp'), 'default' => 20, 'option' => 'edit_' . ShoppProduct::$posttype . '_per_page'));
     $per_page_option = get_current_screen()->get_option('per_page');
     $defaults = array('cat' => false, 'paged' => 1, 'per_page' => $per_page_option['default'], 's' => '', 'sl' => '', 'matchcol' => '', 'view' => $this->view, 'is_inventory' => false, 'is_trash' => false, 'is_bestselling' => false, 'categories_menu' => false, 'inventory_menu' => false, 'lowstock' => 0, 'columns' => '', 'orderby' => '', 'order' => '', 'where' => array(), 'joins' => array());
     $args = array_merge($defaults, $_GET);
     if (false !== ($user_per_page = get_user_option($per_page_option['option']))) {
         $args['per_page'] = $user_per_page;
     }
     extract($args, EXTR_SKIP);
     $url = ShoppAdminController::url($_GET);
     $subs = array('all' => array('label' => Shopp::__('All'), 'where' => array("p.post_status!='trash'")), 'published' => array('label' => Shopp::__('Published'), 'where' => array("p.post_status='publish'")), 'drafts' => array('label' => Shopp::__('Drafts'), 'where' => array("p.post_status='draft'")), 'onsale' => array('label' => Shopp::__('On Sale'), 'where' => array("s.sale='on' AND p.post_status != 'trash'")), 'featured' => array('label' => Shopp::__('Featured'), 'where' => array("s.featured='on' AND p.post_status != 'trash'")), 'bestselling' => array('label' => Shopp::__('Bestselling'), 'where' => array("p.post_status!='trash'", BestsellerProducts::threshold() . " < s.sold"), 'order' => 'bestselling'), 'inventory' => array('label' => Shopp::__('Inventory'), 'where' => array("s.inventory='on' AND p.post_status != 'trash'")), 'trash' => array('label' => Shopp::__('Trash'), 'where' => array("p.post_status='trash'")));
     if (!shopp_setting_enabled('inventory')) {
         unset($subs['inventory']);
     }
     switch ($view) {
         case 'inventory':
             if (shopp_setting_enabled('inventory')) {
                 $is_inventory = true;
             } else {
                 Shopp::redirect(add_query_arg('view', null, $url), true);
             }
             break;
         case 'trash':
             $is_trash = true;
             break;
         case 'bestselling':
             $is_bestselling = true;
             break;
     }
     if ($is_inventory) {
         $per_page = 50;
     }
     $pagenum = absint($paged);
     $start = $per_page * ($pagenum - 1);
     $where = $subs[$this->view]['where'];
     if (!empty($s)) {
         $SearchResults = new SearchResults(array('search' => $s, 'nostock' => 'on', 'published' => 'off', 'paged' => -1));
         $SearchResults->load();
         $ids = array_keys($SearchResults->products);
         $where[] = "p.ID IN (" . join(',', $ids) . ")";
     }
     if (!empty($cat)) {
         global $wpdb;
         $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={$cat})";
         if (-1 == $cat) {
             unset($joins[$wpdb->term_taxonomy]);
             $joins[$wpdb->term_relationships] = "LEFT JOIN {$wpdb->term_relationships} AS tr ON (p.ID=tr.object_id)";
             $where[] = 'tr.object_id IS NULL';
         }
     }
     // Detect custom taxonomies
     $taxonomies = array_intersect(get_object_taxonomies(ShoppProduct::$posttype), array_keys($_GET));
     if (!empty($taxonomies)) {
         foreach ($taxonomies as $n => $taxonomy) {
             global $wpdb;
             $term = get_term_by('slug', $_GET[$taxonomy], $taxonomy);
             if (!empty($term->term_id)) {
                 $joins[$wpdb->term_relationships . '_' . $n] = "INNER JOIN {$wpdb->term_relationships} AS tr{$n} ON (p.ID=tr{$n}.object_id)";
                 $joins[$wpdb->term_taxonomy . '_' . $n] = "INNER JOIN {$wpdb->term_taxonomy} AS tt{$n} ON (tr{$n}.term_taxonomy_id=tt{$n}.term_taxonomy_id AND tt{$n}.term_id={$term->term_id})";
             }
         }
     }
     if (!empty($sl) && shopp_setting_enabled('inventory')) {
         switch ($sl) {
             case "ns":
                 foreach ($where as &$w) {
                     $w = str_replace("s.inventory='on'", "s.inventory='off'", $w);
                 }
                 $where[] = "s.inventory='off'";
                 break;
             case "oos":
                 $where[] = "(s.inventory='on' AND s.stock = 0)";
                 break;
             case "ls":
                 $ls = shopp_setting('lowstock_level');
                 if (empty($ls)) {
                     $ls = '0';
                 }
                 $where[] = "(s.inventory='on' AND s.lowstock != 'none')";
                 break;
             case "is":
                 $where[] = "(s.inventory='on' AND s.stock > 0)";
         }
     }
     $lowstock = shopp_setting('lowstock_level');
     // Setup queries
     $pd = WPDatabaseObject::tablename(ShoppProduct::$table);
     $pt = ShoppDatabaseObject::tablename(ShoppPrice::$table);
     $ps = ShoppDatabaseObject::tablename(ProductSummary::$table);
     $orderdirs = array('asc', 'desc');
     if (in_array($order, $orderdirs)) {
         $orderd = strtolower($order);
     } else {
         $orderd = 'asc';
     }
     if (isset($subs[$this->view]['order'])) {
         $order = $subs[$this->view]['order'];
     }
     $ordercols = '';
     switch ($orderby) {
         case 'name':
             $order = 'title';
             if ('desc' == $orderd) {
                 $order = 'reverse';
             }
             break;
         case 'price':
             $order = 'lowprice';
             if ('desc' == $orderd) {
                 $order = 'highprice';
             }
             break;
         case 'date':
             $order = 'newest';
             if ('desc' == $orderd) {
                 $order = 'oldest';
             }
             break;
         case 'sold':
             $ordercols = 's.sold ' . $orderd;
             break;
         case 'gross':
             $ordercols = 's.grossed ' . $orderd;
             break;
         case 'inventory':
             $ordercols = 's.stock ' . $orderd;
             break;
         case 'sku':
             $ordercols = 'pt.sku ' . $orderd;
             break;
     }
     if (in_array($this->view, array('onsale', 'featured', 'inventory'))) {
         $joins[$ps] = "INNER JOIN {$ps} AS s ON p.ID=s.product";
     }
     $loading = array('where' => $where, 'joins' => $joins, 'limit' => "{$start},{$per_page}", 'load' => array('categories', 'coverimages'), 'published' => false, 'order' => $order, 'nostock' => true);
     if (!empty($ordercols)) {
         unset($loading['order']);
         $loading['orderby'] = $ordercols;
     }
     if ($is_inventory) {
         // Override for inventory products
         $where[] = "(pt.context='product' OR pt.context='variation') AND pt.type != 'N/A'";
         $loading = array('columns' => "pt.id AS stockid,IF(pt.context='variation',CONCAT(p.post_title,': ',pt.label),p.post_title) AS post_title,pt.sku AS sku,pt.stock AS stock", 'joins' => array_merge(array($pt => "LEFT JOIN {$pt} AS pt ON p.ID=pt.product"), $joins), 'where' => $where, 'groupby' => 'pt.id', 'orderby' => str_replace('s.', 'pt.', $ordercols), 'limit' => "{$start},{$per_page}", 'nostock' => true, 'published' => false);
     }
     // Override loading product meta and limiting by pagination in the workflow list
     if ($workflow) {
         unset($loading['limit']);
         $loading['ids'] = true;
         $loading['pagination'] = false;
         $loading['load'] = array();
     }
     $this->products = new ProductCollection();
     $this->products->load($loading);
     // Overpagination protection, redirect to page 1 if the requested page doesn't exist
     $num_pages = ceil($this->products->total / $per_page);
     if ($paged > 1 && $paged > $num_pages) {
         Shopp::redirect(add_query_arg('paged', null, $url));
     }
     // Return a list of product keys for workflow list requests
     if ($workflow) {
         return $this->products->worklist();
     }
     // Get sub-screen counts
     $subcounts = Shopp::cache_get('shopp_product_subcounts', 'shopp_admin');
     if ($subcounts) {
         foreach ($subcounts as $name => $total) {
             if (isset($subs[$name])) {
                 $subs[$name]['total'] = $total;
             }
         }
     } else {
         $subcounts = array();
         foreach ($subs as $name => &$subquery) {
             $subquery['total'] = 0;
             $query = array('columns' => "count(*) AS total", 'table' => "{$pd} as p", 'joins' => array(), 'where' => array());
             $query = array_merge($query, $subquery);
             $query['where'][] = "p.post_type='shopp_product'";
             if (in_array($name, array('onsale', 'bestselling', 'featured', 'inventory'))) {
                 $query['joins'][$ps] = "INNER JOIN {$ps} AS s ON p.ID=s.product";
             }
             $query = sDB::select($query);
             $subquery['total'] = sDB::query($query, 'auto', 'col', 'total');
             $subcounts[$name] = $subquery['total'];
         }
         Shopp::cache_set('shopp_product_subcounts', $subcounts, 'shopp_admin');
     }
     $this->subs = $subs;
 }
Пример #6
0
 function catalog()
 {
     $product_table = WPDatabaseObject::tablename(ShoppProduct::$table);
     $price_table = ShoppDatabaseObject::tablename(ShoppPrice::$table);
     // $where_notdiscounted = array("0 = FIND_IN_SET($this->id,discounts)");
     $where = array();
     $excludes = array();
     // Go through each rule to construct an SQL query
     // that gets all applicable product & price ids
     foreach ((array) $this->rules as $rule) {
         if ('price' == ShoppPromo::$values[$rule['property']]) {
             $value = Shopp::floatval($rule['value']);
         } else {
             $value = $rule['value'];
         }
         switch ($rule['logic']) {
             case "Is equal to":
                 $match = "='{$value}'";
                 break;
             case "Is not equal to":
                 $match = "!='{$value}'";
                 break;
             case "Contains":
                 $match = " LIKE '%{$value}%'";
                 break;
             case "Does not contain":
                 $match = " NOT LIKE '%{$value}%'";
                 break;
             case "Begins with":
                 $match = " LIKE '{$value}%'";
                 break;
             case "Ends with":
                 $match = " LIKE '%{$value}'";
                 break;
             case "Is greater than":
                 $match = "> {$value}";
                 break;
             case "Is greater than or equal to":
                 $match = ">= {$value}";
                 break;
             case "Is less than":
                 $match = "< {$value}";
                 break;
             case "Is less than or equal to":
                 $match = "<= {$value}";
                 break;
         }
         switch ($rule['property']) {
             case "Name":
                 $where[] = "p.post_title{$match}";
                 $joins[$product_table] = "INNER JOIN {$product_table} as p ON prc.product=p.id";
                 break;
             case "Category":
                 $where[] = "tm.name{$match}";
                 if ('!' == $match[0]) {
                     $excludes[] = "tm.name" . ltrim($match, '!');
                 }
                 global $wpdb;
                 $joins[$wpdb->term_relationships] = "INNER JOIN {$wpdb->term_relationships} AS tr ON (prc.product=tr.object_id)";
                 $joins[$wpdb->term_taxonomy] = "INNER JOIN {$wpdb->term_taxonomy} AS tt ON (tr.term_taxonomy_id=tt.term_taxonomy_id)";
                 $joins[$wpdb->terms] = "INNER JOIN {$wpdb->terms} AS tm ON (tm.term_id=tt.term_id)";
                 break;
             case "Variation":
                 $where[] = "prc.label{$match}";
                 break;
             case "Price":
                 $where[] = "prc.price{$match}";
                 break;
             case "Sale price":
                 $where[] = "(prc.onsale='on' AND prc.saleprice{$match})";
                 break;
             case "Type":
                 $where[] = "prc.type{$match}";
                 break;
             case "In stock":
                 $where[] = "(prc.inventory='on' AND prc.stock{$match})";
                 break;
         }
     }
     $operator = 'all' == strtolower($this->search) ? ' AND ' : ' OR ';
     if (!empty($where)) {
         $where = "WHERE " . join($operator, $where);
     } else {
         $where = false;
     }
     if (!empty($joins)) {
         $joins = join(' ', $joins);
     } else {
         $joins = false;
     }
     // Find all the pricetags the promotion is *currently assigned* to
     $query = "SELECT id FROM {$price_table} WHERE 0 < FIND_IN_SET({$this->id},discounts)";
     $current = sDB::query($query, 'array', 'col', 'id');
     $exclude = '';
     if (!empty($excludes)) {
         // Find all the pricetags the promotion should exclude
         $subquery = "SELECT prc.id FROM {$price_table} AS prc {$joins} WHERE " . join(' OR ', $excludes);
         $exclude = " AND prc.id NOT IN ({$subquery})";
     }
     // Find all the pricetags the promotion is *going to apply* to
     $query = "SELECT prc.id,prc.product,prc.discounts FROM {$price_table} AS prc\n\t\t\t\t\t{$joins}\n\t\t\t\t\t{$where} {$exclude}";
     $updates = sDB::query($query, 'array', 'col', 'id');
     // Determine which records need promo added to and removed from
     $added = array_diff($updates, $current);
     $removed = array_diff($current, $updates);
     // Add discounts to specific rows
     $query = "UPDATE {$price_table}\n\t\t\t\t\tSET discounts=CONCAT(discounts,IF(discounts='','{$this->id}',',{$this->id}'))\n\t\t\t\t\tWHERE id IN (" . join(',', $added) . ")";
     if (!empty($added)) {
         sDB::query($query);
     }
     // Remove discounts from pricetags that now don't match the conditions
     if (!empty($removed)) {
         $this->uncatalog($removed);
     }
     // Recalculate product stats for products with pricetags that have changed
     $Collection = new PromoProducts(array('id' => $this->id));
     $Collection->load(array('load' => array('prices'), 'pagination' => false));
 }