示例#1
0
    /**
     * Iterate over the product variants or provide markup for a product variants chooser widget
     *
     * @api `shopp('product.variants')`
     * @since 1.1
     *
     * @param string       $result  The output
     * @param array        $options The options
     * - **mode**: `loop` (loop, single, multiple) Iterate over the variants with `loop` or provide an variant chooser widget using a `single` drop-down menu for all variants or `multiple` menus
     * - **defaults**: Specify a default option that is displayed as the initial selection for the `menu`
     * - **before_menu**: Markup to add before the widget
     * - **after_menu**: Markup to add after the widget
     * - **label**: `on` (on,off) Show or hide the menu name labels from the `menu` widget
     * - **format**: `%l (+%p)` The variant option label format
     *   - **%p**: shows the current variant price including available discounts.
     *   - **%l**: show the option label.
     *   - **%s**: show the stock amount of a product in inventory
     *   - **%d**: show the discount amount of an on sale variant.
     *   - **%r**: show the original price (the non-sale price) of the product variant.
     *   - **%u**: show the SKU for the product variant.
     * - **required**: `You must select the options for this item before you can add it to your shopping cart.` The error message to show when adding to the cart without selecting an variant when the **required** option is `on`
     * - **taxes**: Include or exclude taxes from prices
     * - **class**: The class attribute specifies one or more class-names for the menu elements
     * @param ShoppProduct $O       The working object
     * @return bool|string True if the next variant exists, or false otherwise, or the variant chooser markup
     **/
    public static function variants($result, $options, $O)
    {
        $string = '';
        if (!isset($options['mode'])) {
            if (!isset($O->_prices_loop)) {
                reset($O->prices);
                $O->_prices_loop = true;
            } else {
                next($O->prices);
            }
            $price = current($O->prices);
            while (false !== $price && ('N/A' == $price->type || 'variation' != $price->context)) {
                $price = next($O->prices);
            }
            if (false !== current($O->prices)) {
                return true;
            } else {
                $O->_prices_loop = false;
                return false;
            }
        }
        if (shopp_setting_enabled('inventory') && $O->outofstock) {
            return false;
        }
        // Completely out of stock, hide menus
        if (!isset($options['taxes'])) {
            $options['taxes'] = null;
        }
        $defaults = array('defaults' => '', 'disabled' => 'show', 'pricetags' => 'show', 'before_menu' => '', 'after_menu' => '', 'format' => '%l (%p)', 'label' => 'on', 'mode' => 'multiple', 'taxes' => null, 'required' => __('You must select the options for this item before you can add it to your shopping cart.', 'Shopp'));
        $options = array_merge($defaults, $options);
        extract($options);
        $taxes = isset($taxes) ? Shopp::str_true($taxes) : null;
        $taxrates = self::_taxes($O, 'price');
        $collection_class = ShoppCollection() && isset(ShoppCollection()->slug) ? 'category-' . ShoppCollection()->slug : '';
        if ('single' == $mode) {
            if (!empty($before_menu)) {
                $string .= $before_menu . "\n";
            }
            if (Shopp::str_true($label)) {
                $string .= '<label for="product-options' . (int) $O->id . '">' . Shopp::esc_html__('Options') . ': </label> ' . "\n";
            }
            $string .= '<select name="products[' . (int) $O->id . '][price]" id="product-options' . (int) $O->id . '" class="' . esc_attr($collection_class) . ' product' . (int) $O->id . ' options">';
            if (!empty($defaults)) {
                $string .= '<option value="">' . esc_html($options['defaults']) . '</option>' . "\n";
            }
            foreach ($O->prices as $pricing) {
                if ('variation' != $pricing->context) {
                    continue;
                }
                $currently = Shopp::str_true($pricing->sale) ? $pricing->promoprice : $pricing->price;
                $disable = $pricing->type == 'N/A' || Shopp::str_true($pricing->inventory) && $pricing->stock == 0;
                $currently = self::_taxed((double) $currently, $O, $pricing->tax, $taxes);
                $discount = 0 == $pricing->price ? 0 : 100 - round($pricing->promoprice * 100 / $pricing->price);
                $_ = new StdClass();
                $_->p = 'Donation' != $pricing->type && !$disable ? money($currently) : false;
                $_->l = $pricing->label;
                $_->i = Shopp::str_true($pricing->inventory);
                $_->s = $_->i ? (int) $pricing->stock : false;
                $_->u = $pricing->sku;
                $_->tax = Shopp::str_true($pricing->tax);
                $_->t = $pricing->type;
                $_->r = $pricing->promoprice != $pricing->price ? money($pricing->price) : false;
                $_->d = $discount > 0 ? $discount : false;
                if (!$disable || 'show' == $disabled) {
                    $string .= '<option value="' . $pricing->id . '"' . ($disable ? ' disabled="disabled"' : '') . '>' . esc_html(self::_variant_formatlabel($format, $_)) . '</option>' . "\n";
                }
            }
            $string .= '</select>';
            if (!empty($options['after_menu'])) {
                $string .= $options['after_menu'] . "\n";
            }
        } else {
            if (!isset($O->options)) {
                return;
            }
            $menuoptions = $O->options;
            if (!empty($O->options['v'])) {
                $menuoptions = $O->options['v'];
            }
            $precision = ShoppBaseCurrency()->precision();
            $pricekeys = array();
            foreach ($O->pricekey as $key => $pricing) {
                $currently = Shopp::str_true($pricing->sale) ? $pricing->promoprice : $pricing->price;
                $disable = $pricing->type == 'N/A' || Shopp::str_true($pricing->inventory) && $pricing->stock == 0;
                $currently = self::_taxed((double) $currently, $O, $pricing->tax, $taxes);
                $discount = 100 - round($pricing->promoprice * 100 / $pricing->price);
                $_ = new StdClass();
                $_->p = 'Donation' != $pricing->type && !$disable ? (double) apply_filters('shopp_product_variant_price', Shopp::str_true($pricing->sale) ? $pricing->promoprice : $currently) : false;
                $_->i = Shopp::str_true($pricing->inventory);
                $_->s = $_->i ? (int) $pricing->stock : false;
                $_->u = $pricing->sku;
                $_->tax = Shopp::str_true($pricing->tax);
                $_->t = $pricing->type;
                $_->r = $pricing->promoprice != $pricing->price ? money($pricing->price) : false;
                $_->d = $discount > 0 ? $discount : false;
                $pricekeys[$key] = $_;
            }
            // Output a JSON object for JS manipulation
            if ('json' == $options['mode']) {
                return json_encode($pricekeys);
            }
            $jsoptions = array('prices' => $pricekeys, 'format' => $format);
            if ('hide' == $options['disabled']) {
                $jsoptions['disabled'] = false;
            }
            if ('hide' == $options['pricetags']) {
                $jsoptions['pricetags'] = false;
            }
            if (!empty($taxrate)) {
                $jsoptions['taxrate'] = Shopp::taxrate($O);
            }
            $select_collection = !empty($collection_class) ? '.' . $collection_class : '';
            ob_start();
            if (!empty($options['defaults'])) {
                ?>
$s.opdef = true;
<?php 
            }
            if (!empty($options['required'])) {
                ?>
$s.opreq = "<?php 
                echo $options['required'];
                ?>
";
<?php 
            }
            ?>
new ProductOptionsMenus(<?php 
            printf("'select%s.product%d.options'", $select_collection, $O->id);
            ?>
,<?php 
            echo json_encode($jsoptions);
            ?>
);
<?php 
            $script = ob_get_clean();
            add_storefrontjs($script);
            foreach ($menuoptions as $id => $menu) {
                if (!empty($before_menu)) {
                    $string .= $before_menu . "\n";
                }
                if (Shopp::str_true($label)) {
                    $string .= '<label for="options-' . esc_attr($menu['id']) . '">' . esc_html($menu['name']) . '</label> ' . "\n";
                }
                $string .= '<select name="products[' . (int) $O->id . '][options][]" class="' . esc_attr($collection_class) . ' product' . (int) $O->id . ' options" id="options-' . esc_attr($menu['id']) . '">';
                if (!empty($defaults)) {
                    $string .= '<option value="">' . esc_html($options['defaults']) . '</option>' . "\n";
                }
                foreach ($menu['options'] as $key => $option) {
                    $string .= '<option value="' . esc_attr($option['id']) . '">' . esc_html($option['name']) . '</option>' . "\n";
                }
                $string .= '</select>';
                if (!empty($after_menu)) {
                    $string .= $after_menu . "\n";
                }
            }
        }
        return $string;
    }
示例#2
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";'));
     }
 }
示例#3
0
文件: Tax.php 项目: forthrobot/inuvik
 /**
  * Formats tax rates to a precision beyond the currency format
  *
  * @author Jonathan Davis
  * @since 1.3
  *
  * @param scalar $amount An amount to convert to a float
  * @return float The float amount
  **/
 private static function float($amount)
 {
     $format = ShoppBaseCurrency()->settings();
     $format['precision'] = 6;
     // Override the precision to 6 digits
     return Shopp::floatval($amount, true, $format);
 }