/** * Registers extra conditional reports * * @author Jonathan Davis * @since 1.3 * * @param array $reports The list of registered reports * @return array The modified list of registered reports **/ static function xreports($reports) { if (shopp_setting_enabled('inventory')) { $reports['inventory'] = array('class' => 'InventoryReport', 'name' => __('Inventory Report', 'Shopp'), 'label' => __('Inventory', 'Shopp')); } return $reports; }
/** * Determines if the shipping system is disabled * * @author Jonathan Davis * @since 1.3 * * @return void **/ public function disabled() { // If shipping is disabled if (!shopp_setting_enabled('shipping')) { return true; } return false; }
/** * Initializes the Shopp dashboard widgets * * @author Jonathan Davis * @since 1.0 * * @return void **/ public static function init() { $dashboard = shopp_setting('dashboard'); if (!(current_user_can('shopp_financials') && Shopp::str_true($dashboard))) { return false; } wp_add_dashboard_widget('dashboard_shopp_stats', __('Sales Stats', 'Shopp'), array(__CLASS__, 'stats_widget'), array('all_link' => '', 'feed_link' => '', 'width' => 'half', 'height' => 'single')); wp_add_dashboard_widget('dashboard_shopp_orders', __('Recent Orders', 'Shopp'), array(__CLASS__, 'orders_widget'), array('all_link' => 'admin.php?page=' . ShoppAdmin::pagename('orders'), 'feed_link' => '', 'width' => 'half', 'height' => 'single')); if (shopp_setting_enabled('inventory')) { wp_add_dashboard_widget('dashboard_shopp_inventory', __('Inventory Monitor', 'Shopp'), array(__CLASS__, 'inventory_widget'), array('all_link' => 'admin.php?page=' . ShoppAdmin::pagename('products'), 'feed_link' => '', 'width' => 'half', 'height' => 'single')); } add_action('admin_print_styles-index.php', array(__CLASS__, 'styles')); }
static function recount($terms, $taxonomy) { global $wpdb; $summary_table = ShoppDatabaseObject::tablename(ProductSummary::$table); foreach ((array) $terms as $term) { $where = array("{$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id", "post_status='publish'", "post_type='" . ShoppProduct::$posttype . "'"); if (shopp_setting_enabled('inventory') && !shopp_setting_enabled('outofstock_catalog')) { $where[] = "( s.inventory='off' OR (s.inventory='on' AND s.stock > 0) )"; } $where[] = "term_taxonomy_id=" . (int) $term; $query = "SELECT COUNT(*) AS c FROM {$wpdb->term_relationships}, {$wpdb->posts} LEFT OUTER JOIN {$summary_table} AS s ON s.product={$wpdb->posts}.ID WHERE " . join(' AND ', $where); $count = (int) sDB::query($query, 'auto', 'col', 'c'); do_action('edit_term_taxonomy', $term, $taxonomy); $wpdb->update($wpdb->term_taxonomy, compact('count'), array('term_taxonomy_id' => $term)); do_action('edited_term_taxonomy', $term, $taxonomy); } }
/** * Aggregates product pricing information * * @author Jonathan Davis * @since 1.1 * * @param array $options shopp() tag option list * @return void **/ public function pricing(&$records, &$price, $restat = false) { if (isset($this->products) && !empty($this->products)) { if (!isset($this->products[$price->product])) { return false; } if (!isset($this->_last_product)) { $this->_last_product = false; } if ($this->_last_product != false && $this->_last_product != $price->product && isset($this->products[$this->_last_product])) { $this->products[$this->_last_product]->sumup(); } if ($this->_last_product != $price->product) { $this->products[$price->product]->resum(); } $target =& $this->products[$price->product]; $this->_last_product = $price->product; } else { $target =& $this; } // Skip calulating variant pricing when variants are not enabled for the product if (!(isset($target->variants) && Shopp::str_true($target->variants)) && 'variation' == $price->context) { return; } $target->prices[] = $price; // Force to floats $price->price = (double) $price->price; $price->saleprice = (double) $price->saleprice; $price->shipfee = (double) $price->shipfee; $price->promoprice = (double) Shopp::str_true($price->sale) ? $price->saleprice : $price->price; // Build secondary lookup table using the price id as the key $target->priceid[$price->id] = $price; // Set promoprice before data aggregation if (Shopp::str_true($price->sale)) { $price->promoprice = $price->saleprice; } // Do not count disabled price lines or addon price lines in aggregate summary stats if ('N/A' == $price->type || 'addon' == $price->context) { return; } // Simple product or variant product is on sale if (Shopp::str_true($price->sale)) { $target->sale = $price->sale; } // Build third lookup table using the combined optionkey $target->pricekey[$price->optionkey] = $price; if (Shopp::str_true($price->inventory)) { $target->stock += $price->stock; $target->inventory = $price->inventory; $target->lowstock($price->stock, $price->stocked); } $freeshipping = false; if (!Shopp::str_true($price->shipping) && 'Shipped' == $price->type) { $freeshipping = true; } // Calculate catalog discounts if not already calculated if (!empty($price->discounts)) { $discount = ShoppPromo::pricing($price->promoprice, $price->discounts); if ($discount->freeship) { $freeshipping = true; } $price->promoprice = $discount->pricetag; } $price->_sale = $price->sale; // Keep a copy of the price record "sale" setting {@see issue #2797} if ($price->promoprice < $price->price) { $target->sale = $price->sale = 'on'; } // Grab price and saleprice ranges (minimum - maximum) if (!$price->price) { $price->price = 0; } // Variation range index/properties $varranges = array('price' => 'price', 'saleprice' => 'promoprice'); if (Shopp::str_true($price->inventory)) { $varranges['stock'] = 'stock'; } foreach ($varranges as $name => $prop) { if (!isset($price->{$prop})) { continue; } if (!isset($target->min[$name]) || $target->min[$name] == 0) { $target->min[$name] = $price->{$prop}; } else { $target->min[$name] = min($target->min[$name], $price->{$prop}); } if ($target->min[$name] == $price->{$prop}) { $target->min[$name . '_tax'] = $price->tax == "on"; } if (!isset($target->max[$name])) { $target->max[$name] = $price->{$prop}; } else { $target->max[$name] = max($target->max[$name], $price->{$prop}); } if ($target->max[$name] == $price->{$prop}) { $target->max[$name . '_tax'] = $price->tax == "on"; } } // Determine savings ranges if (Shopp::str_true($target->sale)) { if (!isset($target->min['saved']) || $target->min['saved'] === false) { $target->min['saved'] = $price->price; $target->min['savings'] = 100; $target->max['saved'] = $target->max['savings'] = 0; } $target->min['saved'] = min($target->min['saved'], $price->price - $price->promoprice); $target->max['saved'] = max($target->max['saved'], $price->price - $price->promoprice); // Find lowest savings percentage $delta = $price->price - $price->promoprice; if ($price->price == 0) { // no savings possible $target->min['savings'] = 0; } else { if ($delta <= 0) { // total savings $target->max['savings'] = 100; } else { $savings = $delta / $price->price * 100; $target->min['savings'] = min($target->min['savings'], $savings); $target->max['savings'] = max($target->max['savings'], $savings); } } } if (shopp_setting_enabled('inventory') && Shopp::str_true($target->inventory)) { $target->outofstock = $target->stock <= 0; } if ($freeshipping) { $target->freeship = 'on'; } }
/** * Sets handlers for Shopp shortcodes * * @author Jonathan Davis * @since 1.1 * * @return void **/ public function shortcodes() { $this->shortcodes = array(); // Additional shortcode functionality $this->shortcodes['catalog-product'] = array('ShoppShortcodes', 'product'); $this->shortcodes['catalog-buynow'] = array('ShoppShortcodes', 'buynow'); $this->shortcodes['catalog-collection'] = array('ShoppShortcodes', 'collection'); foreach ($this->shortcodes as $name => &$callback) { if (shopp_setting_enabled('maintenance') || !ShoppSettings()->available() || Shopp::maintenance()) { add_shortcode($name, array('', 'maintenance_shortcode')); } else { add_shortcode($name, $callback); } } }
if (shopp_setting_enabled('inventory')) { echo ' checked="checked"'; } ?> /><label for="inventory-toggle"> <?php _e('Enable inventory tracking', 'Shopp'); ?> </label><br /> <?php _e('Enables inventory tracking. Disable if you are exclusively selling intangible products or not keeping track of product stock.', 'Shopp'); ?> </p> <input type="hidden" name="settings[backorders]" value="off" /><input type="checkbox" name="settings[backorders]" value="on" id="backorders-toggle"<?php if (shopp_setting_enabled('backorders')) { echo ' checked="checked"'; } ?> /><label for="backorders-toggle"> <?php _e('Allow backorders', 'Shopp'); ?> </label><br /> <?php _e('Allows customers to order products that cannot be fulfilled because of a lack of available product in-stock. Disable to prevent customers from ordering more product than is available in-stock.', 'Shopp'); ?> </td> </tr> <tr> <th scope="row" valign="top"><label><?php _e('Shipping Carriers', 'Shopp');
/** * Helper to determine when inclusive taxes apply * * @internal * * @param ShoppCartItem $O The cart item to evaluate * @return bool True if inclusive taxes apply, false otherwise **/ private static function _inclusive_taxes(ShoppCartItem $O) { return shopp_setting_enabled('tax_inclusive') && $O->includetax; }
/** * Displays the welcome screen * * @since 1.3 * * @return boolean **/ public static function welcome() { return defined('WP_ADMIN') && shopp_setting_enabled('display_welcome') && empty($_POST['setup']); }
echo esc_attr(shopp_setting('business_address')); ?> </textarea><br /> <?php _e('Enter the mailing address for your business.', 'Shopp'); ?> </td> </tr> <tr> <th scope="row" valign="top"><label for="maintenance-toggle"><?php _e('Maintenance Mode', 'Shopp'); ?> </label></th> <td><input type="hidden" name="settings[maintenance]" value="off" /><input type="checkbox" name="settings[maintenance]" value="on" id="maintenance-toggle"<?php if (shopp_setting_enabled('maintenance')) { echo ' checked="checked"'; } ?> /><label for="maintenance-toggle"> <?php _e('Enable maintenance mode', 'Shopp'); ?> </label><br /> <?php _e('All storefront pages will display a maintenance mode message.', 'Shopp'); ?> </td> </tr> </table>
/** * Registers the column headers for the product list manager * * @author Jonathan Davis * @return void **/ public function columns() { $headings = array('default' => array('cb' => '<input type="checkbox" />', 'name' => __('Name', 'Shopp'), 'category' => __('Category', 'Shopp'), 'price' => __('Price', 'Shopp'), 'inventory' => __('Inventory', 'Shopp'), 'featured' => __('Featured', 'Shopp'), 'date' => __('Date', 'Shopp')), 'inventory' => array('inventory' => __('Inventory', 'Shopp'), 'sku' => __('SKU', 'Shopp'), 'name' => __('Name', 'Shopp')), 'bestselling' => array('cb' => '<input type="checkbox" />', 'name' => __('Name', 'Shopp'), 'sold' => __('Sold', 'Shopp'), 'gross' => __('Sales', 'Shopp'), 'price' => __('Price', 'Shopp'), 'inventory' => __('Inventory', 'Shopp'), 'featured' => __('Featured', 'Shopp'), 'date' => __('Date', 'Shopp'))); $columns = isset($headings[$this->view]) ? $headings[$this->view] : $headings['default']; // Remove inventory column if inventory tracking is disabled if (!shopp_setting_enabled('inventory')) { unset($columns['inventory']); } // Remove category column from the "trash" view if ('trash' == $this->view) { unset($columns['category']); } ShoppUI::register_column_headers('toplevel_page_shopp-products', apply_filters('shopp_manage_product_columns', $columns)); }
echo esc_url($this->url); ?> " method="post"> <?php wp_nonce_field('shopp-settings-checkout'); ?> <table class="form-table"> <tr> <th scope="row" valign="top"><label for="shopping-cart-toggle"><?php _e('Shopping Cart', 'Shopp'); ?> </label></th> <td><input type="hidden" name="settings[shopping_cart]" value="off" /><input type="checkbox" name="settings[shopping_cart]" value="on" id="shopping-cart-toggle"<?php if (shopp_setting_enabled('shopping_cart')) { echo ' checked="checked"'; } ?> /><label for="shopping-cart-toggle"> <?php _e('Enabled', 'Shopp'); ?> </label><br /> <?php _e('Uncheck this to disable the shopping cart and checkout. Useful for catalog-only sites.', 'Shopp'); ?> </td> </tr> <tr> <th scope="row" valign="top"><label for="confirm_url"><?php
echo ShoppAdminMetabox::help('product-editor-variations'); ?> </label></p> <p><input type="hidden" name="addons" value="off" /><input type="checkbox" name="addons" value="on" id="addons-setting" tabindex="13"<?php if ($Product->addons == "on") { echo ' checked="checked"'; } ?> /><label for="addons-setting"> <?php _e('Add-ons', 'Shopp'); echo ShoppAdminMetabox::help('product-editor-addons'); ?> </label></p> <?php if (shopp_setting_enabled('tax_inclusive')) { ?> <p><input type="hidden" name="meta[excludetax]" value="off" /><input type="checkbox" name="meta[excludetax]" value="on" id="excludetax-setting" tabindex="18" <?php if (isset($Product->meta['excludetax']) && Shopp::str_true($Product->meta['excludetax']->value)) { echo 'checked="checked"'; } ?> /> <label for="excludetax-setting"><?php _e('Exclude Taxes', 'Shopp'); ?> </label></p> <?php } ?> <?php
/** * Detect if the Shopp installation needs maintenance * * @author Jonathan Davis * @since 1.1 * * @return boolean **/ public static function maintenance() { return self::upgradedb() || shopp_setting_enabled('maintenance'); }
/** * shopp_product_variant_set_saleprice - set the sale price of a variant * * @api * @since 1.2 * * @param int/Price $variant (required) The priceline id to set the sale price on, or the Price object to change. If Price object is specified, the object will be returned, but not saved to the database. * @param bool $flag (optional default:false) true for on, false for off. Turns on or off the sale flag on the variant. If false, price is ignored. * @param float $price the price to be set * @param string $context (optional default:variant) enforces the priceline is a 'product','variant', or 'addon' * @return bool/Price false on failure, true if Price saved, else the modified Price object. **/ function shopp_product_variant_set_saleprice($variant = false, $flag = false, $price = 0.0, $context = 'variant') { $context = 'variant' == $context ? 'variation' : $context; $save = true; if (is_object($variant) && is_a($variant, 'ShoppPrice')) { $Price = $variant; $save = false; } else { if (false == $variant) { shopp_debug(__FUNCTION__ . " failed: Variant id required."); return false; } $Price = new ShoppPrice($variant); if (empty($Price->id) || $Price->context != $context) { shopp_debug(__FUNCTION__ . " failed: No such {$context} with id {$variant}."); } } $Price->sale = "off"; if ($flag) { $Price->sale = "on"; if (shopp_setting_enabled('tax_inclusive') && isset($Price->tax) && Shopp::str_true($Price->tax)) { $Product = new ShoppProduct($Price->product); $taxrate = shopp_taxrate(null, true, $Product); $price = Shopp::floatval($price / (1 + $taxrate)); } $Price->saleprice = $price; } if ($save) { return $Price->save(); } return $Price; }
/** * Calculate taxes for a taxable amount using the given tax rates * * @author Jonathan Davis * @since 1.3 * * @param array $rates A list of ShoppItemTax objects * @param float $taxable The amount to calculate taxes on * @return float The total tax amount **/ public static function calculate(array &$rates, $taxable) { $compound = 0; $total = 0; $inclusive = shopp_setting_enabled('tax_inclusive'); foreach ($rates as $label => $taxrate) { if (is_null($taxrate->total)) { continue; } // Skip taxes flagged to be removed from the item $taxrate->amount = 0; // Reset the captured tax amount @see Issue #2430 // Calculate tax amount if ($inclusive) { $tax = $taxable - $taxable / (1 + $taxrate->rate); } else { $tax = $taxable * $taxrate->rate; } if ($taxrate->compound) { if (0 == $compound) { $compound = $taxable; } else { if ($inclusive) { $tax = $compound - $compound / (1 + $taxrate->rate); } else { $tax = $compound * $taxrate->rate; } // Compounded tax amount } $compound += $tax; // Set compound taxable amount for next compound rate } $taxrate->amount = $tax; // Capture the tax amount calculate for this taxrate $total += $tax; // Sum all of the taxes to get the total tax for the item } return $total; }
/** * Calculates the order Totals * * @author Jonathan Davis * @since 1.3 * * @return void **/ public function totals() { // Setup totals counter if (false === $this->Totals) { $this->Totals = new OrderTotals(); } $Totals = $this->Totals; do_action('shopp_cart_totals_init', $Totals); $Shipping = ShoppOrder()->Shiprates; $Discounts = ShoppOrder()->Discounts; // Identify downloadable products $downloads = $this->downloads(); $shipped = $this->shipped(); do_action('shopp_cart_item_totals', $Totals); // Update cart item totals $items = $this->keys(); // Use local array for iterating foreach ($items as $itemid) { // Allow other code to iterate the cart in this loop $Item = $this->get($itemid); $Item->totals(); } $Totals->register(new OrderAmountShipping(array('id' => 'cart', 'amount' => $Shipping->calculate()))); if (apply_filters('shopp_tax_shipping', shopp_setting_enabled('tax_shipping'))) { $Totals->register(new OrderAmountShippingTax($Totals->total('shipping'))); } // Calculate discounts $Totals->register(new OrderAmountDiscount(array('id' => 'cart', 'amount' => $Discounts->amount()))); // Apply credits to discount the order $Discounts->credits(); if ($Discounts->shipping()) { // If shipping discounts changed, recalculate shipping amount $Totals->register(new OrderAmountShipping(array('id' => 'cart', 'amount' => $Shipping->calculate()))); } // Ensure taxes are recalculated $Totals->total('tax'); do_action_ref_array('shopp_cart_retotal', array(&$Totals)); return $Totals; }
/** * Helper function to determine if inclusive taxes apply to a given product * * @internal * @since 1.3 * * @param ShoppProduct $O The Shopp product to compare * @return boolean True if inclusive taxes apply, false otherwise **/ private static function _inclusive_taxes($O) { return shopp_setting_enabled('tax_inclusive') && !Shopp::str_true($O->excludetax); }
/** * Verifies the item is in stock * * @author Jonathan Davis * @since 1.1 * * @return boolean **/ public function instock($qty = false) { if (!shopp_setting_enabled('inventory') || shopp_setting_enabled('backorders')) { return true; } if (!$this->inventory) { // base item doesn't track inventory and no addons if (empty($this->addons)) { return true; } $addon_inventory = false; foreach ($this->addons as $addon) { if (Shopp::str_true($addon->inventory)) { $addon_inventory = true; } } // base item doesn't track inventory, but an addon does if (!$addon_inventory) { return true; } } // need to get the current minimum stock for item + addons $this->option->stock = $this->getstock(); if ($qty) { return $this->option->stock >= $qty; } return $this->option->stock > 0; }
/** * Separate class of order notifications for "successful" orders * * A successful order is conditionally based on the type of order being processed. An order * is successful on the "authed" order event for shipped orders (any order that has any shipped * items including mixed-type orders) or, it will fire on the "captured" order event * for non-tangible orders (downloads, donation, virtual, etc) * * Keeping this behavior behind the success markers (authed/captured) prevents email * servers from getting overloaded if the server is getting hit with bot-triggered order * attempts. * * @author Jonathan Davis * @since 1.2 * * @return void **/ public static function success($Purchase) { $templates = array('email-order.php', 'order.php', 'order.html'); // Generic filter hook for specifying global email messages $messages = apply_filters('shopp_order_success_emails', array('customer' => array("{$Purchase->firstname} {$Purchase->lastname}", $Purchase->email, Shopp::__('Your order with %s', shopp_setting('business_name')), $templates), 'merchant' => array(shopp_setting('business_name'), shopp_setting('merchant_email'), Shopp::__('New Order - %s', $Purchase->id), array_merge(array('email-merchant-order.php'), $templates))), $Purchase); // Remove merchant notification if disabled in receipt copy setting if (!shopp_setting_enabled('receipt_copy')) { unset($messages['merchant']); } foreach ($messages as $message) { list($addressee, $email, $subject, $templates) = $message; // Send email if the specific template is available // and if an email has not already been sent to the recipient $Purchase->email($addressee, $email, $subject, $templates); } }
/** * Zeros out tax amounts when tax inclusive is enabled * * Prevents inclusive-tax unaware payment systems (such as PayPal Standard) * from adding extra taxes to the order * * @author Jonathan Davis * @since 1.3.2 * * @param float $amount The tax amount to filter * @return float The correct amount **/ public function notaxinclusive($amount) { if (shopp_setting_enabled('tax_inclusive')) { return 0.0; } else { return $amount; } }
public function column() { // Do not add inclusive taxes to totals tally if (shopp_setting_enabled('tax_inclusive')) { return null; } return $this->column; }
function settings_meta_box($Product) { $Shopp = Shopp::object(); $Admin =& $Shopp->Flow->Admin; ?> <p><input type="hidden" name="featured" value="off" /><input type="checkbox" name="featured" value="on" id="featured" tabindex="12" <?php if ($Product->featured == "on") { echo ' checked="checked"'; } ?> /><label for="featured"> <?php _e('Featured Product', 'Shopp'); ?> </label></p> <p><input type="hidden" name="variants" value="off" /><input type="checkbox" name="variants" value="on" id="variations-setting" tabindex="13"<?php if ($Product->variants == "on") { echo ' checked="checked"'; } ?> /><label for="variations-setting"> <?php _e('Variants', 'Shopp'); echo $Admin->boxhelp('product-editor-variations'); ?> </label></p> <p><input type="hidden" name="addons" value="off" /><input type="checkbox" name="addons" value="on" id="addons-setting" tabindex="13"<?php if ($Product->addons == "on") { echo ' checked="checked"'; } ?> /><label for="addons-setting"> <?php _e('Add-ons', 'Shopp'); echo $Admin->boxhelp('product-editor-addons'); ?> </label></p> <?php if (shopp_setting_enabled('tax_inclusive')) { ?> <p><input type="hidden" name="meta[excludetax]" value="off" /><input type="checkbox" name="meta[excludetax]" value="on" id="excludetax-setting" tabindex="18" <?php if (isset($Product->meta['excludetax']) && Shopp::str_true($Product->meta['excludetax']->value)) { echo 'checked="checked"'; } ?> /> <label for="excludetax-setting"><?php _e('Exclude Taxes', 'Shopp'); ?> </label></p> <?php } ?> <?php if ($Shopp->Shipping->realtime) { ?> <p><input type="hidden" name="meta[packaging]" value="off" /><input type="checkbox" name="meta[packaging]" value="on" id="packaging-setting" tabindex="18" <?php if (isset($Product->meta['packaging']) && $Product->meta['packaging']->value == "on") { echo 'checked="checked"'; } ?> /> <label for="packaging-setting"><?php _e('Separate Packaging', 'Shopp'); ?> </label></p> <?php } ?> <p><input type="hidden" name="comment_status" value="closed" /><input type="checkbox" name="comment_status" value="open" id="allow-comments" tabindex="18" <?php if (Shopp::str_true($Product->comment_status)) { echo 'checked="checked"'; } ?> /> <label for="allow-comments"><?php _e('Comments', 'Shopp'); ?> </label> <p><input type="hidden" name="ping_status" value="closed" /><input type="checkbox" name="ping_status" value="open" id="allow-trackpings" tabindex="18" <?php if (Shopp::str_true($Product->ping_status)) { echo 'checked="checked"'; } ?> /> <label for="allow-trackpings"><?php _e('Trackbacks & Pingbacks', 'Shopp'); ?> </label> <p><input type="hidden" name="meta[processing]" value="off" /><input type="checkbox" name="meta[processing]" value="on" id="process-time" tabindex="18" <?php if (isset($Product->meta['processing']) && Shopp::str_true($Product->meta['processing']->value)) { echo 'checked="checked"'; } ?> /> <label for="process-time"><?php _e('Processing Time', 'Shopp'); ?> </label> <div id="processing" class="hide-if-js"> <select name="meta[minprocess]"><?php echo menuoptions(Lookup::timeframes_menu(), isset($Product->meta['minprocess']) ? $Product->meta['minprocess']->value : false, true); ?> </select> — <select name="meta[maxprocess]"><?php echo menuoptions(Lookup::timeframes_menu(), isset($Product->meta['maxprocess']) ? $Product->meta['maxprocess']->value : false, true); ?> </select> </div> </p> <?php }
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); } }
/** * Provides the subtotal amount of the cart * * @api `shopp('cart.subtotal')` * @since 1.0 * * @param string $result The output * @param array $options The options * - **wrap**: `on` (on, off) Wrap the amount in DOM-accessible markup * - **money**: `on` (on, off) Format the amount in the current currency format * - **number**: `off` (on, off) Provide the unformatted number (floating point) * - **taxes**: `on` (on, off) Include taxes in the subtotal amount when inclusive taxes are used (or off to exclude them) * @param ShoppCart $O The working object * @return string The subtotal amount **/ public static function subtotal($result, $options, $O) { $defaults = array('taxes' => 'on'); $options = array_merge($defaults, $options); extract($options, EXTR_SKIP); $subtotal = $O->total('order'); // Handle no-tax option for tax inclusive storefronts if (!Shopp::str_true($taxes) && shopp_setting_enabled('tax_inclusive')) { $tax = $O->Totals->entry('tax', 'Tax'); if (is_a($tax, 'OrderAmountItemTax')) { $subtotal -= $tax->amount(); } } return (double) $subtotal; }
/> <?php Shopp::_e('Enabled'); ?> <br /><?php _e('Enable to restrict downloads to the IP address the product is purchased from.', 'Shopp'); ?> </label></td> </tr> <tr> <th scope="row" valign="top"><label for="download-quantity"><?php Shopp::_e('Download Quantity'); ?> </label></th> <td><input type="hidden" name="settings[download_quantity]" value="off" /> <label for="download-quantity"><input type="checkbox" name="settings[download_quantity]" id="download-quantity" value="on" <?php echo shopp_setting_enabled('download_quantity') ? 'checked="checked" ' : ''; ?> /> <?php Shopp::_e('Enabled'); ?> </label><br /> <?php Shopp::_e('Allow shoppers to change the item quantity for downloads.'); ?> </td> </tr> </table> <p class="submit"><input type="submit" class="button-primary" name="save" value="<?php _e('Save Changes', 'Shopp'); ?>
/** * Validate order data before transaction processing * * @author Jonathan Davis * @since 1.1 * * @return boolean Validity of the order **/ public function isvalid($report = true) { $Customer = $this->Customer; $Shipping = $this->Shipping; $Shiprates = $this->Shiprates; $Payments = $this->Payments; $Cart = $this->Cart; $valid = true; $errlevel = $report ? SHOPP_TRXN_ERR : SHOPP_DEBUG_ERR; shopp_debug('Validating order data for processing'); if (0 == $Cart->count()) { $valid = apply_filters('shopp_ordering_empty_cart', false); shopp_add_error(__('There are no items in the cart.', 'Shopp'), $errlevel); } $stock = true; foreach ($Cart as $item) { if (!$item->instock()) { $valid = apply_filters('shopp_ordering_items_outofstock', false); shopp_add_error(sprintf(__('%s does not have sufficient stock to process order.', 'Shopp'), $item->name . (empty($item->option->label) ? '' : '(' . $item->option->label . ')')), $errlevel); $stock = false; } } $valid_customer = true; if (!$Customer) { $valid_customer = apply_filters('shopp_ordering_empty_customer', false); } // No Customer // Always require name and email if (empty($Customer->firstname)) { $valid_customer = apply_filters('shopp_ordering_empty_firstname', false); } if (empty($Customer->lastname)) { $valid_customer = apply_filters('shopp_ordering_empty_lastname', false); } if (empty($Customer->email)) { $valid_customer = apply_filters('shopp_ordering_empty_email', false); } if (!$valid_customer) { $valid = false; shopp_add_error(__('There is not enough customer information to process the order.', 'Shopp'), $errlevel); } // Check for shipped items but no Shipping information $valid_shipping = true; if ($Cart->shipped() && shopp_setting_enabled('shipping')) { if (empty($Shipping->address)) { $valid_shipping = apply_filters('shopp_ordering_empty_shipping_address', false); } if (empty($Shipping->country)) { $valid_shipping = apply_filters('shopp_ordering_empty_shipping_country', false); } if (empty($Shipping->postcode)) { $valid_shipping = apply_filters('shopp_ordering_empty_shipping_postcode', false); } if ($Shiprates->count() == 0 && !$Shiprates->free()) { $valid = apply_filters('shopp_ordering_no_shipping_costs', false); $message = __('The order cannot be processed. No shipping is available to the address you provided. Please return to %scheckout%s and try again.', 'Shopp'); if ($Shiprates->realtime()) { $message = __('The order cannot be processed. The shipping rate service did not provide rates because of a problem and no other shipping is available to the address you provided. Please return to %scheckout%s and try again or contact the store administrator.', 'Shopp'); } if (!$valid) { shopp_add_error(sprintf($message, '<a href="' . Shopp::url(false, 'checkout', $this->security()) . '">', '</a>'), $errlevel); } } } if (!$valid_shipping) { $valid = false; shopp_add_error(__('The shipping address information is incomplete. The order cannot be processed.', 'Shopp'), $errlevel); } // Alert when no gateway is configured (and the order is not free) if ($Payments->count() == 0 && $Cart->total() > 0) { $valid = false; shopp_add_error(Lookup::errors('gateway', 'nogateways'), $errlevel); } return $valid; }
public function taxes_menu() { if (!shopp_setting_enabled('taxes')) { return; } ?> <ul class="subsubsub"> <?php $i = 0; foreach ($this->subscreens as $screen => $label) { $url = add_query_arg(array('sub' => $screen), $this->url); ?> <li><a href="<?php echo esc_url($url); ?> "<?php if ($_GET['sub'] == $screen) { echo ' class="current"'; } ?> ><?php echo $label; ?> </a><?php if (count($this->subscreens) - 1 != $i++) { ?> | <?php } ?> </li> <?php } ?> </ul> <br class="clear" /> <?php }
Shopp::_e('Enabled', 'Shopp'); ?> </label><br /> <?php Shopp::_e('Enables tax calculations. Disable if you are exclusively selling non-taxable items.'); ?> </td> </tr> <tr> <th scope="row" valign="top"><label for="shipping-toggle"><?php Shopp::_e('Track Inventory'); ?> </label></th> <td><input type="hidden" name="settings[inventory]" value="off" /><input type="checkbox" name="settings[inventory]" value="on" id="inventory-toggle"<?php if (shopp_setting_enabled('inventory')) { echo ' checked="checked"'; } ?> /><label for="inventory-toggle"> <?php Shopp::_e('Enable inventory tracking', 'Shopp'); ?> </label><br /> <?php Shopp::_e('Enables inventory tracking. Disable if you are exclusively selling intangible products or not keeping track of product stock.'); ?> </td> </tr> </table> <p class="submit"><input type="submit" class="button-primary" name="save" value="<?php
/** * Determines hidden settings screens * * @since 1.4 * * @param string $slug The tab slug name * @return bool True if the tab should be hidden, false otherwise **/ protected function hiddentab($slug) { $settings = array('shipping' => 'shipping', 'boxes' => 'shipping', 'taxes' => 'taxes', 'orders' => 'shopping_cart', 'payments' => 'shopping_cart', 'downloads' => 'shopping_cart'); if (!isset($settings[$slug])) { return false; } $setting = $settings[$slug]; return !shopp_setting_enabled($setting); }