function widget($args, $options) { $Shopp = Shopp::object(); extract($args); $title = $before_title . $options['title'] . $after_title; unset($options['title']); if (empty(ShoppCollection()->id)) { return false; } $menu = shopp(ShoppCollection(), 'get-section-list', $options); echo $before_widget . $title . $menu . $after_widget; }
/** * Returns the proper global context object used in a shopp('collection') call * * @internal * @since 1.2 * * @param ShoppOrder $Object The ShoppOrder object to set as the working context * @param string $context The context being worked on by the Theme API * @return ShoppCollection The active object context **/ public static function _setobject($Object, $context) { if (is_object($Object) && is_a($Object, 'ProductCollection')) { return $Object; } switch ($context) { case 'collection': case 'category': return ShoppCollection(); break; case 'subcategory': if (isset(ShoppCollection()->child)) { return ShoppCollection()->child; } break; } return $Object; }
/** * Display the widget content * * @param array $args Display arguments including before_title, after_title, before_widget, and after_widget. * @param array $options The settings for the particular instance of the widget */ function widget($args, $options) { if (!empty($args)) { extract($args); } if (empty($options['title'])) { $options['title'] = __('Product Filters', 'Shopp'); } $title = $before_title . $options['title'] . $after_title; $Collection = ShoppCollection(); if (empty($Collection)) { return; } if ('' != shopp('collection.get-id') && shopp('collection.has-faceted-menu')) { $menu = shopp('collection.get-faceted-menu', $options); echo $before_widget . $title . $menu . $after_widget; } }
/** * Wraps mark-up in a #shopp container, if needed * * @author Jonathan Davis * @since 1.1 * * @param string $string The content markup to be wrapped * @param array $classes CSS classes to add to the container * @return string The wrapped markup **/ static function wrapper($string) { $classes = array('shoppage', 'shopp_page'); $views = array('list', 'grid'); $view = shopp_setting('default_catalog_view'); if (empty($view)) { $view = 'grid'; } // Handle catalog view style cookie preference if (isset($_COOKIE['shopp_catalog_view'])) { $view = $_COOKIE['shopp_catalog_view']; } if (in_array($view, $views)) { $classes[] = $view; } $boxes = shopp_setting('row_products'); if (empty($boxes)) { $boxes = 3; } $classes[] = 'shopp_grid-' . abs($boxes); // Add collection slug $Collection = ShoppCollection(); if (!empty($Collection)) { if ($category = shopp('collection.get-slug')) { $classes[] = $category; } } // Add product id & slug classes $Product = ShoppProduct(); if (!empty($Product)) { if ($productid = shopp('product.get-id')) { $classes[] = 'product-' . $productid; } if ($product = shopp('product.get-slug')) { $classes[] = $product; } } $classes = apply_filters('shopp_content_container_classes', $classes); $classes = esc_attr(join(' ', $classes)); $id = false === strpos($string, 'id="shopp"') ? ' id="shopp" ' : ''; return '<div' . $id . (!empty($classes) ? ' class="' . $classes . '"' : '') . '>' . $string . '</div>'; }
/** * Handles rendering the [catalog-collection] shortcode * * @author Jonathan Davis * @since 1.1 * * @param array $attrs The parsed shortcode attributes * @return string The processed content **/ static function collection(array $atts = array()) { $Shopp = Shopp::object(); $tag = 'category'; if (isset($atts['name'])) { $Collection = new ProductCategory($atts['name'], 'name'); unset($atts['name']); } elseif (isset($atts['slug'])) { foreach ($Shopp->Collections as $SmartCollection) { $slugs = SmartCollection::slugs($SmartCollection); if (in_array($atts['slug'], $slugs)) { $tag = $slugs[0] . "-collection"; unset($atts['slug']); break; } } } elseif (isset($atts['id'])) { $Collection = new ProductCategory($atts['id']); unset($atts['id']); } else { return ''; } ShoppCollection($Collection); $markup = shopp("catalog.get-{$tag}", $atts); ShoppStorefront()->shortcoded[] = get_the_ID(); // @deprecated in favor of the shopp_collection_shortcode $markup = apply_filters('shopp_category_shortcode', $markup); return apply_filters('shopp_collection_shortcode', $markup); }
/** * 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']; } $baseop = shopp_setting('base_operations'); $precision = $baseop['currency']['format']['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; }
/** * Start the element output. * * @see Walker::start_el() * * @since 2.1.0 * * @param string $output Passed by reference. Used to append additional content. * @param object $category Category data object. * @param int $depth Depth of category in reference to parents. Default 0. * @param array $args An array of arguments. @see wp_list_categories() * @param int $id ID of the current category. */ public function start_el(&$output, $category, $depth = 0, $args = array(), $id = 0) { extract($args); $smartcollection = $category->taxonomy == get_class_property('SmartCollection', 'taxon'); $categoryname = $category->name; $href = get_term_link($category); $classes = ''; if ('list' == $args['style']) { $classes = 'cat-item cat-item-' . $category->term_id; $Collection = ShoppCollection(); if (isset($Collection->slug) && $Collection->slug == $category->slug) { $classes .= ' current-cat current'; } if (!empty($Collection->parent) && $Collection->parent == $category->term_id) { $classes .= ' current-cat-parent current-parent'; } } $total = isset($category->count) ? $category->count : false; $title = Shopp::__('View all "%s" products', $categoryname); $filtered = apply_filters('shopp_storefront_categorylist_link', compact('href', 'classes', 'categoryname', 'title', 'total')); extract($filtered, EXTR_OVERWRITE); $link = '<a href="' . esc_url($href) . '" title="' . esc_attr($title) . '" class="' . $classes . '">'; $link .= $categoryname . '</a>'; if (empty($total) && !Shopp::str_true($linkall) && !$smartcollection) { $link = $categoryname; } if (false !== $total && Shopp::str_true($products)) { $link .= ' (' . intval($total) . ')'; } $link = apply_filters('shopp_storefront_categorylist_item', $link, compact('href', 'classes', 'categoryname', 'title', 'total', 'products', 'linkall', 'smartcollection')); if ('list' == $args['style']) { $output .= "\t<li"; if (!empty($classes)) { $output .= ' class="' . $classes . '"'; } $output .= ">{$link}\n"; } else { $output .= "\t{$link}<br />\n"; } }
/** * Handles loading, saving and deleting categories in a workflow context * * @author Jonathan Davis * @since 1.0 * @return void **/ public function workflow() { $defaults = array('action' => false, 'selected' => array(), 'page' => false, 'id' => false, 'save' => false, 'next' => false, '_wpnonce' => false); $args = array_merge($defaults, $_REQUEST); extract($args, EXTR_SKIP); if (!defined('WP_ADMIN') || $page != $this->page()) { return false; } $adminurl = admin_url('admin.php'); add_screen_option('per_page', array('label' => __('Categories Per Page', 'Shopp'), 'default' => 20, 'option' => 'edit_' . ProductCategory::$taxon . '_per_page')); if ('delete' == $action && wp_verify_nonce($_wpnonce, 'shopp_categories_manager')) { if (!empty($id)) { $selected = array($id); } $total = count($selected); foreach ($selected as $selection) { $DeletedCategory = new ProductCategory($selection); $deleted = $DeletedCategory->name; $DeletedCategory->delete(); } if (1 == $total) { $this->notice(Shopp::__('Deleted %s category.', "<strong>{$deleted}</strong>")); } else { $this->notice(Shopp::__('Deleted %s categories.', "<strong>{$total}</strong>")); } $reset = array('selected' => null, 'action' => null, 'id' => null, '_wpnonce' => null); $redirect = add_query_arg(array_merge($_GET, $reset), $adminurl); Shopp::redirect($redirect); exit; } if ($id && 'new' != $id) { $Category = new ProductCategory($id); } else { $Category = new ProductCategory(); } $meta = array('specs', 'priceranges', 'options', 'prices'); foreach ($meta as $prop) { if (!isset($Category->{$prop})) { $Category->{$prop} = array(); } } if ($save) { $this->save($Category); // Workflow handler if (isset($_REQUEST['settings']) && isset($_REQUEST['settings']['workflow'])) { $workflow = $_REQUEST['settings']['workflow']; $working = array_search($id, $this->worklist); switch ($workflow) { case 'close': $next = 'close'; break; case 'new': $next = 'new'; break; case 'next': $key = $working + 1; break; case 'previous': $key = $working - 1; break; } if (isset($key)) { $next = isset($this->worklist[$key]) ? $this->worklist[$key] : 'close'; } } if ($next) { if ('new' == $next) { $Category = new ProductCategory(); } else { $Category = new ProductCategory($next); } } else { if (empty($id)) { $id = $Category->id; } $Category = new ProductCategory($id); } } ShoppCollection($Category); }
/** * Interface processor for the category editor * * @author Jonathan Davis * @since 1.0 * @return void **/ public function editor() { global $CategoryImages; $Shopp = Shopp::object(); if (!current_user_can('shopp_categories')) { wp_die(__('You do not have sufficient permissions to access this page.')); } $Category = ShoppCollection(); if (empty($Category)) { $Category = new ProductCategory(); } $Category->load_meta(); $Category->load_images(); $Price = new ShoppPrice(); $priceTypes = ShoppPrice::types(); $billPeriods = ShoppPrice::periods(); // Build permalink for slug editor $permalink = trailingslashit(Shopp::url()) . "category/"; $Category->slug = apply_filters('editable_slug', $Category->slug); $pricerange_menu = array("disabled" => __('Price ranges disabled', 'Shopp'), "auto" => __('Build price ranges automatically', 'Shopp'), "custom" => __('Use custom price ranges', 'Shopp')); $uploader = shopp_setting('uploader_pref'); if (!$uploader) { $uploader = 'flash'; } $workflows = array("continue" => __('Continue Editing', 'Shopp'), "close" => __('Categories Manager', 'Shopp'), "new" => __('New Category', 'Shopp'), "next" => __('Edit Next', 'Shopp'), "previous" => __('Edit Previous', 'Shopp')); do_action('add_meta_boxes', ProductCategory::$taxon, $Category); do_action('add_meta_boxes_' . ProductCategory::$taxon, $Category); do_action('do_meta_boxes', ProductCategory::$taxon, 'normal', $Category); do_action('do_meta_boxes', ProductCategory::$taxon, 'advanced', $Category); do_action('do_meta_boxes', ProductCategory::$taxon, 'side', $Category); include $this->ui('category.php'); }
</description> <link><?php echo esc_html($rss['link']); ?> </link> <language><?php echo get_option('rss_language'); ?> </language> <copyright><?php echo esc_html("Copyright " . date('Y') . ", " . $rss['sitename']); ?> </copyright> <?php while (false !== ($item = ShoppCollection()->feed())) { ?> <?php if (empty($item)) { continue; } ?> <item> <?php ShoppCollection()->feeditem($item); ?> </item> <?php } ?> </channel> </rss>