Exemple #1
0
 /**
  * Initializes the Shopp runtime environment
  *
  * @author Jonathan Davis
  * @since 1.0
  *
  * @return void
  **/
 public function init()
 {
     $this->Collections = array();
     $this->Locale = new ShoppBaseLocale();
     $this->Order = new ShoppOrder();
     $this->Gateways = new GatewayModules();
     $this->Shipping = new ShippingModules();
     $this->Storage = new StorageEngines();
     $this->APIs = new ShoppAPIModules();
     // Start the shopping session
     $this->Shopping = ShoppShopping();
     new ShoppLogin();
     do_action('shopp_init');
 }
 /**
  * Handles shopping cart requests
  *
  * @author Jonathan Davis
  * @since 1.1
  *
  * @return void
  **/
 public function cart()
 {
     if (isset($_REQUEST['shopping']) && 'reset' == strtolower($_REQUEST['shopping'])) {
         ShoppShopping()->reset();
         Shopp::redirect(Shopp::url());
     }
     if (empty($_REQUEST['cart'])) {
         return true;
     }
     do_action('shopp_cart_request');
     if (isset($_REQUEST['checkout'])) {
         Shopp::redirect(Shopp::url(false, 'checkout', $this->security()));
     }
     if (isset($_REQUEST['ajax'])) {
         $Cart = ShoppOrder()->Cart;
         $Cart->totals();
         $Cart->ajax();
     }
     $redirect = false;
     if (isset($_REQUEST['redirect'])) {
         $redirect = $_REQUEST['redirect'];
     }
     switch ($redirect) {
         case 'checkout':
             Shopp::redirect(Shopp::url(false, $redirect, ShoppOrder()->security()));
             break;
         default:
             if (!empty($_REQUEST['redirect'])) {
                 Shopp::safe_redirect($_REQUEST['redirect']);
             } else {
                 Shopp::redirect(Shopp::url(false, 'cart'));
             }
     }
     exit;
 }
Exemple #3
0
 /**
  * Setup the module for runtime
  *
  * Auto-loads settings for the module and setups defaults
  *
  * @author Jonathan Davis
  * @since 1.1
  *
  * @return void
  **/
 public function __construct()
 {
     $this->module = get_class($this);
     $this->session = ShoppShopping()->session;
     $this->Order = ShoppOrder();
     if ('ShoppFreeOrder' != $this->module) {
         // There are no settings for ShoppFreeOrder
         $this->settings = shopp_setting($this->module);
         // @todo Remove legacy gateway settings migrations
         // Attempt to copy old settings if this is a new prefixed gateway class
         if (empty($this->settings) && false !== strpos($this->module, 'Shopp')) {
             $legacy = substr($this->module, 5);
             $this->settings = shopp_setting($legacy);
             if (!empty($this->settings)) {
                 shopp_set_setting($this->module, $this->settings);
             }
         }
     }
     if (!isset($this->settings['label']) && $this->cards) {
         $this->settings['label'] = __('Credit Card', 'Shopp');
     }
     $this->baseop = ShoppBaseLocale()->settings();
     $this->currency = ShoppBaseCurrency()->code();
     $this->precision = ShoppBaseCurrency()->precision();
     $this->_loadcards();
     $gateway = GatewayModules::hookname($this->module);
     add_action('shopp_init', array($this, 'myactions'), 30);
     add_action('shopp_' . $gateway . '_refunded', array($this, 'cancelorder'));
     if ($this->authonly) {
         add_filter('shopp_purchase_order_' . $gateway . '_processing', create_function('', 'return "auth";'));
     } elseif ($this->saleonly) {
         add_filter('shopp_purchase_order_' . $gateway . '_processing', create_function('', 'return "sale";'));
     }
 }
Exemple #4
0
 /**
  * Provides the URL for the referring page
  *
  * The referrer is the page the shopper was visiting before being
  * sent to the cart page. If no referring page is available, the
  * catalog page URL is given instead.
  *
  * @api `shopp('cart.referrer')`
  * @since 1.1
  *
  * @param string    $result  The output
  * @param array     $options The options
  * @param ShoppCart $O       The working object
  * @return string The referring page's URL
  **/
 public static function referrer($result, $options, $O)
 {
     $Shopping = ShoppShopping();
     $referrer = $Shopping->data->referrer;
     if (!$referrer) {
         $referrer = shopp('catalog', 'url', 'return=1');
     }
     return $referrer;
 }
Exemple #5
0
 /**
  * Handles product file download requests
  *
  * @author Jonathan Davis
  * @since 1.1
  *
  * @return void
  **/
 public function download()
 {
     $Shopp = Shopp::object();
     $download = $this->request['shopp_download'];
     $Purchase = false;
     $Purchased = false;
     if (defined('WP_ADMIN')) {
         $forbidden = false;
         $Download = new ProductDownload($download);
     } else {
         $Order = ShoppOrder();
         $accounts = 'none' != shopp_setting('account_system');
         $Download = new ProductDownload();
         $Download->loadby_dkey($download);
         $Purchased = $Download->purchased();
         $Purchase = new ShoppPurchase($Purchased->purchase);
         $Purchase->load_events();
         $name = $Purchased->name . (!empty($Purchased->optionlabel) ? ' (' . $Purchased->optionlabel . ')' : '');
         $forbidden = false;
         // Voided orders
         if ($Purchase->isvoid()) {
             shopp_add_error(Shopp::__('"%s" cannot be downloaded because the order has been cancelled.', $name));
             $forbidden = true;
         }
         // Purchase Completion check
         if (!$Purchase->ispaid() && !SHOPP_PREPAYMENT_DOWNLOADS) {
             shopp_add_error(Shopp::__('"%s" cannot be downloaded because payment has not been received yet.', $name));
             $forbidden = true;
         }
         // If accounts are used and this is not a guest account
         if ($accounts && Shopp::__('Guest') != ShoppCustomer()->type) {
             // User must be logged in when accounts are being used
             if (!ShoppCustomer()->loggedin()) {
                 shopp_add_error(Shopp::__('You must login to download purchases.'));
                 $forbidden = true;
             }
             // Logged in account must be the owner of the purchase
             if (ShoppCustomer()->id != $Purchase->customer) {
                 shopp_add_error(Shopp::__('You are not authorized to download the requested file.'));
                 $forbidden = true;
             }
         }
         // Download limit checking
         if (shopp_setting('download_limit') && $Purchased->downloads + 1 > shopp_setting('download_limit')) {
             shopp_add_error(Shopp::__('"%s" is no longer available for download because the download limit has been reached.', $name));
             $forbidden = true;
         }
         // Download expiration checking
         if (shopp_setting('download_timelimit') && $Purchased->created + shopp_setting('download_timelimit') < current_time('timestamp')) {
             shopp_add_error(Shopp::__('&quot;%s&quot; is no longer available for download because it has expired.', 'Shopp', $name));
             $forbidden = true;
         }
         // IP restriction checks
         if ('ip' == shopp_setting('download_restriction') && !empty($Purchase->ip) && $Purchase->ip != $_SERVER['REMOTE_ADDR']) {
             shopp_add_error(Shopp::__('&quot;%s&quot; cannot be downloaded because your computer could not be verified as the system the file was purchased from.', $name));
             $forbidden = true;
         }
         do_action_ref_array('shopp_download_request', array($Purchased));
     }
     if (apply_filters('shopp_download_forbidden', $forbidden, $Purchased)) {
         Shopp::redirect(add_query_arg('downloads', '', Shopp::url(false, 'account')), true, 303);
     }
     // Send the download
     $download = $Download->download();
     if (is_a($download, 'ShoppError')) {
         // If the result is an error redirect to the account downloads page
         Shopp::redirect(add_query_arg('downloads', '', Shopp::url(false, 'account')), true, 303);
     } else {
         do_action_ref_array('shopp_download_success', array($Purchased, $Purchase, $Download));
         // @deprecated use shopp_download_order_event instead
         shopp_add_order_event($Purchase->id, 'download', array('purchased' => $Purchased->id, 'download' => $Download->id, 'ip' => ShoppShopping()->ip, 'customer' => ShoppCustomer()->id));
     }
     exit;
 }
Exemple #6
0
 public function load(array $options = array())
 {
     $thisclass = get_class($this);
     $slug = isset($this->slug) ? $this->slug : sanitize_key($thisclass);
     $Storefront = ShoppStorefront();
     $Shopping = ShoppShopping();
     $Processing = new ShoppProduct();
     $summary_table = ShoppDatabaseObject::tablename(ProductSummary::$table);
     $defaults = array('columns' => false, 'useindex' => false, 'joins' => array(), 'where' => array(), 'groupby' => false, 'orderby' => false, 'having' => array(), 'limit' => false, 'order' => false, 'page' => false, 'paged' => false, 'nostock' => null, 'pagination' => true, 'published' => true, 'ids' => false, 'adjacent' => false, 'product' => false, 'load' => array('coverimages'), 'inventory' => false, 'taxquery' => false, 'debug' => false);
     $loading = array_merge($defaults, $options);
     $loading = apply_filters("shopp_collection_load_options", $loading);
     $loading = apply_filters("shopp_{$slug}_collection_load_options", $loading);
     extract($loading);
     // Setup pagination
     $this->paged = false;
     $this->pagination = false === $paged ? shopp_setting('catalog_pagination') : $paged;
     $page = false === $page ? get_query_var('paged') : $page;
     $this->page = (int) $page > 0 || preg_match('/(0\\-9|[A-Z])/', $page) ? $page : 1;
     // Hard product limit per category to keep resources "reasonable"
     $hardlimit = apply_filters('shopp_category_products_hardlimit', 1000);
     // Enforce the where parameter as an array
     if (!is_array($where)) {
         return shopp_debug('The "where" parameter for ' . __METHOD__ . ' must be formatted as an array.');
     }
     // Inventory filtering
     if (shopp_setting_enabled('inventory') && (is_null($nostock) && !shopp_setting_enabled('outofstock_catalog') || !is_null($nostock) && !Shopp::str_true($nostock))) {
         $where[] = "( s.inventory='off' OR (s.inventory='on' AND s.stock > 0) )";
     }
     if (Shopp::str_true($published)) {
         $where[] = "p.post_status='publish'";
     }
     // Multiple taxonomy queries
     if (is_array($taxquery)) {
         $tqdefaults = array('relation' => 'AND', 'include_children' => true);
         $taxquery = array_merge($tqdefaults, $taxquery);
         $TQ = new WP_Tax_Query($taxquery);
         $sql = $TQ->get_sql($Processing->_table, 'ID');
         unset($TQ);
         $joins['taxquery'] = self::taxquery($sql['join']);
         $where[] = self::taxquery($sql['where']);
     }
     // Sort Order
     if (!$orderby) {
         $titlesort = "p.post_title ASC";
         $defaultsort = empty($order) ? $titlesort : $order;
         // Define filterable built-in sort methods (you're welcome)
         $sortmethods = apply_filters('shopp_collection_sort_methods', array('bestselling' => "s.sold DESC,{$titlesort}", 'highprice' => "maxprice DESC,{$titlesort}", 'lowprice' => "minprice ASC,{$titlesort}", 'newest' => "p.post_date DESC,{$titlesort}", 'oldest' => "p.post_date ASC,{$titlesort}", 'random' => "RAND(" . crc32($Shopping->session) . ")", 'chaos' => "RAND(" . time() . ")", 'reverse' => "p.post_title DESC", 'title' => $titlesort, 'custom' => is_subclass_of($this, 'ProductTaxonomy') ? "tr.term_order ASC,{$titlesort}" : $defaultsort, 'recommended' => is_subclass_of($this, 'ProductTaxonomy') ? "tr.term_order ASC,{$titlesort}" : $defaultsort, 'default' => $defaultsort));
         // Handle valid user browsing sort change requests
         if (isset($_REQUEST['sort']) && !empty($_REQUEST['sort']) && array_key_exists(strtolower($_REQUEST['sort']), $sortmethods)) {
             $Storefront->browsing['sortorder'] = strtolower($_REQUEST['sort']);
         }
         // Collect sort setting sources (Shopp admin setting, User browsing setting, programmer specified setting)
         $sortsettings = array(shopp_setting('default_product_order'), isset($Storefront->browsing['sortorder']) ? $Storefront->browsing['sortorder'] : false, !empty($order) ? $order : false);
         // Go through setting sources to determine most applicable setting
         $sorting = 'title';
         foreach ($sortsettings as $setting) {
             if (!empty($setting) && isset($sortmethods[strtolower($setting)])) {
                 $sorting = strtolower($setting);
             }
         }
         $orderby = $sortmethods[$sorting];
     }
     if (empty($orderby)) {
         $orderby = 'p.post_title ASC';
     }
     // Pagination
     if (empty($limit)) {
         if ($this->pagination > 0 && is_numeric($this->page) && Shopp::str_true($pagination)) {
             if (!$this->pagination || $this->pagination < 0) {
                 $this->pagination = $hardlimit;
             }
             $start = $this->pagination * ($this->page - 1);
             $limit = "{$start},{$this->pagination}";
         } else {
             $limit = $hardlimit;
         }
         $limited = false;
         // Flag that the result set does not have forced limits
     } else {
         $limited = true;
     }
     // The result set has forced limits
     // Core query components
     // Load core product data and product summary columns
     $cols = array('p.ID', 'p.post_title', 'p.post_name', 'p.post_excerpt', 'p.post_status', 'p.post_date', 'p.post_modified', 's.modified AS summed', 's.sold', 's.grossed', 's.maxprice', 's.minprice', 's.ranges', 's.taxed', 's.stock', 's.lowstock', 's.inventory', 's.featured', 's.variants', 's.addons', 's.sale');
     if ($ids) {
         $cols = array('p.ID');
     }
     $columns = "SQL_CALC_FOUND_ROWS " . join(',', $cols) . ($columns !== false ? ',' . $columns : '');
     $table = "{$Processing->_table} AS p";
     $where[] = "p.post_type='" . ShoppProduct::posttype() . "'";
     $joins[$summary_table] = "LEFT OUTER JOIN {$summary_table} AS s ON s.product=p.ID";
     $options = compact('columns', 'useindex', 'table', 'joins', 'where', 'groupby', 'having', 'limit', 'orderby');
     // Alphabetic pagination
     if ('alpha' === $pagination || preg_match('/(0\\-9|[A-Z])/', $page)) {
         // Setup Roman alphabet navigation
         $alphanav = array_merge(array('0-9'), range('A', 'Z'));
         $this->alpha = array_combine($alphanav, array_fill(0, count($alphanav), 0));
         // Setup alphabetized index query
         $a = $options;
         $a['columns'] = "count(DISTINCT p.ID) AS total,IF(LEFT(p.post_title,1) REGEXP '[0-9]',LEFT(p.post_title,1),LEFT(SOUNDEX(p.post_title),1)) AS letter";
         $a['groupby'] = "letter";
         $alphaquery = sDB::select($a);
         $cachehash = 'collection_alphanav_' . md5($alphaquery);
         $cached = Shopp::cache_get($cachehash, 'shopp_collection_alphanav');
         if ($cached) {
             // Load from object cache,  if available
             $this->alpha = $cached;
             $cached = false;
         } else {
             // Run query and cache results
             $expire = apply_filters('shopp_collection_cache_expire', 43200);
             $alpha = sDB::query($alphaquery, 'array', array($this, 'alphatable'));
             Shopp::cache_set($cachehash, $alpha, 'shopp_collection_alphanav', $expire);
         }
         $this->paged = true;
         if ($this->page == 1) {
             $this->page = '0-9';
         }
         $alphafilter = $this->page == "0-9" ? "(LEFT(p.post_title,1) REGEXP '[0-9]') = 1" : "IF(LEFT(p.post_title,1) REGEXP '[0-9]',LEFT(p.post_title,1),LEFT(SOUNDEX(p.post_title),1))='{$this->page}'";
         $options['where'][] = $alphafilter;
     }
     $query = sDB::select(apply_filters('shopp_collection_query', $options));
     if ($debug) {
         echo $query . BR . BR;
     }
     // Load from cached results if available, or run the query and cache the results
     $cachehash = 'collection_' . md5($query);
     $cached = Shopp::cache_get($cachehash, 'shopp_collection');
     if ($cached) {
         $this->products = $cached->products;
         $this->total = $cached->total;
     } else {
         $expire = apply_filters('shopp_collection_cache_expire', 43200);
         $cache = new stdClass();
         if ($ids) {
             $cache->products = $this->products = sDB::query($query, 'array', 'col', 'ID');
         } else {
             $cache->products = $this->products = sDB::query($query, 'array', array($Processing, 'loader'));
         }
         $cache->total = $this->total = sDB::found();
         // If running a limited set, the reported total found should not exceed the limit (but can because of SQL_CALC_FOUND_ROWS)
         // Don't use the limit if it is offset
         if ($limited && false === strpos($limit, ',')) {
             $cache->total = $this->total = min($limit, $this->total);
         }
         Shopp::cache_set($cachehash, $cache, 'shopp_collection', $expire);
     }
     if (false === $this->products) {
         $this->products = array();
     }
     if ($ids) {
         return $this->size() > 0;
     }
     // Finish up pagination construction
     if ($this->pagination > 0 && $this->total > $this->pagination) {
         $this->pages = ceil($this->total / $this->pagination);
         if ($this->pages > 1) {
             $this->paged = true;
         }
     }
     // Load all requested product meta from other data sources
     $Processing->load_data($load, $this->products);
     // If products are missing summary data, resum them
     if (isset($Processing->resum) && !empty($Processing->resum)) {
         $Processing->load_data(array('prices'), $Processing->resum);
     }
     unset($Processing);
     // Free memory
     $this->loaded = true;
     return $this->size() > 0;
 }
Exemple #7
0
 /**
  * Secures the payment card by truncating it to the last four digits
  *
  * @author Jonathan Davis
  * @since 1.2
  *
  * @return void
  **/
 public function securecard()
 {
     $this->Billing->card = '';
     // Card data is gone, switch the cart to normal mode
     ShoppShopping()->secured(false);
 }
Exemple #8
0
 /**
  * Builds a hidden form to submit the order to PayPal
  *
  * @author Jonathan Davis
  * @since 1.0
  *
  * @param ShoppPurchase $Purchase The order to submit to PayPal
  * @return string PayPal order form contents
  **/
 public function form(ShoppPurchase $Purchase)
 {
     $Shopping = ShoppShopping();
     $Order = ShoppOrder();
     $Cart = $Order->Cart;
     $Customer = $Order->Customer;
     $_ = array();
     $_['cmd'] = '_cart';
     $_['upload'] = 1;
     $_['business'] = $this->settings['account'];
     $_['invoice'] = $Purchase->id;
     $_['custom'] = $Shopping->session;
     // Options
     if (Shopp::str_true($this->settings['pdtverify'])) {
         $_['return'] = apply_filters('shopp_paypalstandard_returnurl', Shopp::url(array('rmtpay' => $this->id(), 'utm_nooverride' => '1'), 'checkout', false));
     } else {
         $_['return'] = Shopp::url(false, 'thanks');
     }
     $_['cancel_return'] = Shopp::url(false, 'cart');
     $_['notify_url'] = $this->ipnurl();
     $_['rm'] = 1;
     // Return with no transaction data
     // Pre-populate PayPal Checkout
     $_['lc'] = $this->baseop['country'];
     $_['charset'] = 'utf-8';
     $_['bn'] = 'shopplugin.net[WPS]';
     $_['first_name'] = $Customer->firstname;
     $_['last_name'] = $Customer->lastname;
     $AddressType = 'Shipping';
     // Disable shipping fields if no shipped items in cart
     if (empty($Order->Cart->shipped)) {
         $AddressType = 'Billing';
         $_['no_shipping'] = 1;
     }
     $Address = $Order->{$AddressType};
     if (!empty($Order->Cart->shipped)) {
         $shipname = explode(' ', $Address->name);
         $_['first_name'] = array_shift($shipname);
         $_['last_name'] = join(' ', $shipname);
     }
     $_['address_override'] = 1;
     $_['address1'] = $Address->address;
     if (!empty($Address->xaddress)) {
         $_['address2'] = $Address->xaddress;
     }
     $_['city'] = $Address->city;
     $_['state'] = $Address->state;
     $_['zip'] = $Address->postcode;
     $_['country'] = $Address->country;
     $_['email'] = $Customer->email;
     $phone = parse_phone($Order->Customer->phone);
     if (!empty($phone) && in_array($Order->Billing->country, array('US', 'CA'))) {
         $_['night_phone_a'] = $phone['area'];
         $_['night_phone_b'] = $phone['prefix'];
         $_['night_phone_c'] = $phone['exchange'];
     } else {
         $_['night_phone_b'] = $phone['raw'];
     }
     // Include page style option, if provided
     if (isset($_GET['pagestyle'])) {
         $_['pagestyle'] = $_GET['pagestyle'];
     }
     // Transaction
     $_['currency_code'] = $this->currency();
     // Recurring Non-Free Item
     $Cart->recurring();
     $Subscription = reset($Cart->recurring);
     if ($Cart->recurring() && $Subscription->unitprice > 0) {
         $tranges = array('D' => array('min' => 1, 'max' => 90), 'W' => array('min' => 1, 'max' => 52), 'M' => array('min' => 1, 'max' => 24), 'Y' => array('min' => 1, 'max' => 5));
         $recurring = $Subscription->recurring();
         $recurring['period'] = strtoupper($recurring['period']);
         //normalize recurring interval
         $recurring['interval'] = min(max($recurring['interval'], $tranges[$recurring['period']]['min']), $tranges[$recurring['period']]['max']);
         $_['cmd'] = '_xclick-subscriptions';
         $_['rm'] = 2;
         // Return with transaction data
         $_['item_number'] = $Subscription->product;
         $_['item_name'] = $Subscription->name . (!empty($Subscription->option->label) ? ' (' . $Subscription->option->label . ')' : '');
         $trial_discounts = apply_filters('shopp_paypalstandard_discount_trials', false);
         // Trial pricing
         if ($Subscription->has_trial()) {
             $trial = $Subscription->trial();
             $trial['period'] = strtoupper($trial['period']);
             $trialprice = $this->amount($trial['price']);
             if ($this->amount('discount') > 0 && $trial_discounts) {
                 $trialprice -= $this->amount('discount');
             }
             // normalize trial interval
             $trial['interval'] = min(max($trial['interval'], $tranges[$trial['period']]['min']), $tranges[$trial['period']]['max']);
             $_['a1'] = $this->amount($trial['price']);
             $_['p1'] = $trial['interval'];
             $_['t1'] = $trial['period'];
         } elseif ($this->amount('discount') > 0 && $trial_discounts) {
             // When no trial discounts are created, add a discount to a trial offer using
             // the interval and period of the normal subscription, but at a discounted price
             $_['a1'] = $this->amount($Subscription->subprice) - $this->amount('discount');
             $_['p1'] = $recurring['interval'];
             $_['t1'] = $recurring['period'];
         }
         $subprice = $this->amount($Subscription->subprice);
         if ($this->amount('discount') > 0 && !$trial_discounts) {
             $subprice -= $this->amount('discount');
         }
         $_['a3'] = $subprice;
         $_['p3'] = $recurring['interval'];
         $_['t3'] = $recurring['period'];
         $_['src'] = 1;
         if ($recurring['cycles']) {
             $_['srt'] = (int) $recurring['cycles'];
         }
     } else {
         // Line Items
         $id = 0;
         foreach ($Order->Cart as $i => $Item) {
             $id++;
             $_['item_number_' . $id] = $id;
             $_['item_name_' . $id] = $Item->name . (!empty($Item->option->label) ? ' ' . $Item->option->label : '');
             $_['amount_' . $id] = $this->amount($Item->unitprice);
             $_['quantity_' . $id] = $Item->quantity;
             // $_['weight_'.$id]			= $Item->quantity;
         }
         // Workaround a PayPal limitation of not correctly handling no subtotals or
         // handling discounts in the amount of the item subtotals by adding the
         // shipping fee to the line items to get included in the subtotal. If no
         // shipping fee is available use 0.01 to satisfy minimum order amount requirements
         // Additionally, this condition should only be possible when using the shopp('cart','paypal')
         // Theme API tag which would circumvent normal checkout and use PayPal even for free orders
         if ((double) $this->amount('order') == 0 || (double) $this->amount('order') - (double) $this->amount('discount') == 0) {
             $id++;
             $_['item_number_' . $id] = $id;
             $_['item_name_' . $id] = apply_filters('paypal_freeorder_handling_label', __('Shipping & Handling', 'Shopp'));
             $_['amount_' . $id] = $this->amount(max((double) $this->amount('shipping'), 0.01));
             $_['quantity_' . $id] = 1;
         } else {
             $_['handling_cart'] = $this->amount('shipping');
         }
         $_['discount_amount_cart'] = $this->amount('discount');
         $_['tax_cart'] = $this->amount('tax');
         $_['amount'] = $this->amount('total');
     }
     $_ = apply_filters('shopp_paypal_standard_form', $_);
     return $this->format($_);
 }
Exemple #9
0
 /**
  * Redirects the browser to a specified URL
  *
  * A wrapper for the wp_redirect function
  *
  * @author Jonathan Davis
  * @since 1.0
  *
  * @param string $uri The URI to redirect to
  * @param boolean $exit (optional) Exit immediately after the redirect (defaults to true, set to false to override)
  * @return void
  **/
 public static function redirect($uri, $exit = true, $status = 302)
 {
     shopp_debug("Redirecting to: {$uri}");
     remove_action('shutdown', array(ShoppShopping(), 'save'));
     ShoppShopping()->save();
     wp_redirect($uri, $status);
     if ($exit) {
         exit;
     }
 }
Exemple #10
0
 /**
  * Processes payment information changes.
  *
  * @since 1.3
  *
  * @return void
  **/
 public function payment()
 {
     if (!$this->paycard()) {
         return;
     }
     add_filter('shopp_validate_checkout', array('ShoppFormValidation', 'paycard'));
     $Billing = ShoppOrder()->Billing;
     $Payments = ShoppOrder()->Payments;
     $form = $this->form('billing');
     // Change the default cardtype to the selected payment service option label
     $Billing->cardtype = empty($form['cardtype']) ? $Payments->selected()->label : $form['cardtype'];
     // If the card number is provided over a secure connection
     // Change the cart to operate in secure mode
     if (!empty($form['card']) && is_ssl()) {
         ShoppShopping()->secured(true);
     }
     // Sanitize the card number to ensure it only contains numbers
     if (strlen($PAN = self::digitsonly($form['card'])) > 4) {
         $Billing->card = $PAN;
     }
     if (!empty($form['cardexpires-mm']) && !empty($form['cardexpires-yy'])) {
         $exmm = self::digitsonly($form['cardexpires-mm']);
         $exyy = self::digitsonly($form['cardexpires-yy']);
         $Billing->cardexpires = mktime(0, 0, 0, $exmm, 1, $exyy + 2000);
     } else {
         $Billing->cardexpires = 0;
     }
     $Billing->cvv = self::digitsonly($form['cvv']);
     // Extra card security check fields
     if (!empty($form['xcsc'])) {
         $Billing->xcsc = array();
         foreach ((array) $form['xcsc'] as $field => $value) {
             $Billing->Billing->xcsc[] = $field;
             // Add to the XCSC registry of fields
             $Billing->{$field} = $value;
             // Add the property
         }
     }
 }
Exemple #11
0
 /**
  * Clear the Customer-related session data
  *
  * @author Jonathan Davis
  * @since 1.0
  *
  * @return void
  **/
 public function logout()
 {
     $Shopp = Shopp::object();
     $Order = ShoppOrder();
     $Shopping = ShoppShopping();
     $this->Customer->clear();
     $this->Billing->clear();
     $this->Shipping->clear();
     $this->Shipping->locate();
     do_action('shopp_logged_out', $this->Customer);
 }
Exemple #12
0
 public function upgrade_130()
 {
     global $wpdb;
     $db_version = ShoppSettings::dbversion();
     if ($db_version < 1201) {
         // 1.3 schema changes
         $this->upschema();
         // All existing sessions must be cleared and restarted, 1.3 & 1.3.6 sessions are not compatible with any prior version of Shopp
         ShoppShopping()->reset();
         $sessions_table = ShoppDatabaseObject::tablename('shopping');
         sDB::query("DELETE FROM {$sessions_table}");
         // Remove all the temporary PHP native session data from the options table
         sDB::query("DELETE FROM from {$wpdb->options} WHERE option_name LIKE '__php_session_*'");
     }
     if ($db_version < 1200) {
         $meta_table = ShoppDatabaseObject::tablename('meta');
         sDB::query("UPDATE {$meta_table} SET value='on' WHERE name='theme_templates' AND (value != '' AND value != 'off')");
         sDB::query("DELETE FROM {$meta_table} WHERE type='image' AND value LIKE '%O:10:\"ShoppError\"%'");
         // clean up garbage from legacy bug
         sDB::query("DELETE FROM {$meta_table} WHERE CONCAT('', name *1) = name AND context = 'category' AND type = 'meta'");
         // clean up bad category meta
         // Update purchase gateway values to match new prefixed class names
         $gateways = array('PayPalStandard' => 'ShoppPayPalStandard', '_2Checkout' => 'Shopp2Checkout', 'OfflinePayment' => 'ShoppOfflinePayment', 'TestMode' => 'ShoppTestMode', 'FreeOrder' => 'ShoppFreeOrder');
         foreach ($gateways as $name => $classname) {
             sDB::query("UPDATE {$purchase_table} SET gateway='{$classname}' WHERE gateway='{$name}'");
         }
         $activegateways = explode(',', shopp_setting('active_gateways'));
         foreach ($activegateways as &$setting) {
             if (false === strpos($setting, 'Shopp')) {
                 $setting = str_replace(array_keys($gateways), $gateways, $setting);
             }
         }
         shopp_set_setting('active_gateways', join(',', $activegateways));
     }
     if ($db_version < 1200 && shopp_setting_enabled('tax_inclusive')) {
         $price_table = ShoppDatabaseObject::tablename('price');
         $taxrates = shopp_setting('taxrates');
         $baseop = shopp_setting('base_operations');
         $taxtaxes = array();
         // Capture taxonomy condition tax rates
         $basetaxes = array();
         // Capture base of operations rate(s)
         foreach ($taxrates as $rate) {
             if (!($baseop['country'] == $rate['country'] || ShoppTax::ALL == $rate['country'])) {
                 continue;
             }
             if (!empty($rate['zone']) && $baseop['zone'] != $rate['zone']) {
                 continue;
             }
             if (!empty($rate['rules']) && $rate['logic'] == 'any') {
                 // Capture taxonomy conditional rates
                 foreach ($rate['rules'] as $raterule) {
                     if ('product-category' == $raterule['p']) {
                         $taxname = ProductCategory::$taxon . '::' . $raterule['v'];
                     } elseif ('product-tags' == $raterule['p']) {
                         $taxname = ProductTag::$taxon . '::' . $raterule['v'];
                     }
                     $taxtaxes[$taxname] = Shopp::floatval($rate['rate']) / 100;
                 }
             } else {
                 $basetaxes[] = Shopp::floatval($rate['rate']) / 100;
             }
         }
         // Find products by in each taxonomy termno
         $done = array();
         // Capture each set into the "done" list
         foreach ($taxtaxes as $taxterm => $taxrate) {
             list($taxonomy, $name) = explode('::', $taxterm);
             $Collection = new ProductCollection();
             $Collection->load(array('ids' => true, 'taxquery' => array(array('taxonomy' => $taxonomy, 'field' => 'name', 'terms' => $name))));
             $query = "UPDATE {$price_table} SET price=price+(price*{$taxrate}) WHERE tax='on' AND product IN (" . join(',', $Collection->products) . ")";
             sDB::query($query);
             $done = array_merge($done, $Collection->products);
         }
         // Update the rest of the prices (skipping those we've already done) with the tax rate that matches the base of operations
         $taxrate = array_sum($basetaxes);
         // Merge all the base taxes into a single rate
         $done = empty($done) ? '' : " AND product NOT IN (" . join(',', $done) . ")";
         $query = "UPDATE {$price_table} SET price=price+(price*{$taxrate}) WHERE tax='on'{$done}";
         sDB::query($query);
     }
 }
Exemple #13
0
 /**
  * Reset the shopping session
  *
  * Controls the cart to allocate a new session ID and transparently
  * move existing session data to the new session ID.
  *
  * @since 1.0
  *
  * @param string $session (optional) Specify a session to load into this one
  * @return bool True on success, false otherwise
  **/
 static function resession($session = false)
 {
     $Shopping = ShoppShopping();
     do_action('shopp_pre_resession', $session);
     // Save the current session
     $Shopping->save();
     if ($session) {
         // loading session
         $Shopping->preload($session);
         do_action('shopp_resession');
         return true;
     } else {
         $Shopping->reprovision();
     }
     do_action('shopp_reset_session');
     // @deprecated do_action('shopp_reset_session')
     do_action('shopp_resession');
     return true;
 }