/** * Loads or constructs the Item object from product and product pricing parameters * * @author John Dillick, Jonathan Davis * @since 1.2 * * @param object $Product Product object * @param mixed $pricing A list of price IDs; The option key of a price object; or a Price object * @param int $category (optional)The breadcrumb category ID where the product was added from * @param array $data (optional) Custom data associated with the line item * @param array $addons (optional) A set of addon options * @return void **/ public function load($Product, $pricing, $category = false, $data = array(), $addons = array()) { $Product->load_data(); // If option ids are passed, lookup by option key, otherwise by id $Price = false; if (is_array($pricing) && !empty($pricing)) { $optionkey = $Product->optionkey($pricing); if (!isset($Product->pricekey[$optionkey])) { $optionkey = $Product->optionkey($pricing, true); } // deprecated prime if (isset($Product->pricekey[$optionkey])) { $Price = $Product->pricekey[$optionkey]; } } elseif (is_numeric($pricing)) { $Price = $Product->priceid[$pricing]; } elseif (is_a($pricing, 'ShoppPrice')) { $Price = $pricing; } // Find single product priceline if (!$Price && !Shopp::str_true($Product->variants)) { foreach ($Product->prices as &$Price) { $stock = true; if (Shopp::str_true($Price->inventory) && 1 > $Price->stock) { $stock = false; } if ('product' == $Price->context && 'N/A' != $Price->type && $stock) { break; } } } // Find first available variant priceline if (!$Price && Shopp::str_true($Product->variants)) { foreach ($Product->prices as &$Price) { $stock = true; if (Shopp::str_true($Price->inventory) && 1 > $Price->stock) { $stock = false; } if ('variation' == $Price->context && 'N/A' != $Price->type && $stock) { break; } } } if (isset($Product->id)) { $this->product = $Product->id; } if (isset($Price->id)) { $this->priceline = $Price->id; } $this->name = $Product->name; $this->slug = $Product->slug; $this->category = $category; $this->categories = $this->namelist($Product->categories); $this->tags = $this->namelist($Product->tags); $this->image = current($Product->images); $this->description = $Product->summary; if (shopp_setting_enabled('taxes')) { // Must init taxable above addons roll-up #2825 $this->taxable = array(); } // Re-init during ShoppCart::change() loads #2922 // Product has variants if (Shopp::str_true($Product->variants) && empty($this->variants)) { $this->variants($Product->prices); } // Product has Addons if (Shopp::str_true($Product->addons)) { if (!empty($this->addons)) { // Compute addon differences $addons = array_diff($addons, array_keys($this->addons)); } $this->addons($this->addonsum, $addons, $Product->prices); } if (isset($Price->id)) { $this->option = $this->mapprice($Price); } $this->sku = $Price->sku; $this->type = $Price->type; $this->sale = Shopp::str_true($Product->sale); $this->freeshipping = isset($Price->freeshipping) ? $Price->freeshipping : false; $baseprice = roundprice($this->sale ? $Price->promoprice : $Price->price); $this->unitprice = $baseprice + $this->addonsum; if (shopp_setting_enabled('taxes')) { if (Shopp::str_true($Price->tax)) { $this->taxable[] = $baseprice; } $this->istaxed = array_sum($this->taxable) > 0; $this->includetax = shopp_setting_enabled('tax_inclusive'); if (isset($Product->excludetax) && Shopp::str_true($Product->excludetax)) { $this->includetax = false; } } if ('Donation' == $this->type) { $this->donation = $Price->donation; } $this->inventory = Shopp::str_true($Price->inventory) && shopp_setting_enabled('inventory'); $this->data = stripslashes_deep(esc_attrs($data)); // Handle Recurrences if ($this->has_recurring()) { $this->subprice = $this->unitprice; $this->recurrences(); if ($this->is_recurring() && $this->has_trial()) { $trial = $this->trial(); $this->unitprice = $trial['price']; } } // Map out the selected menu name and option if (Shopp::str_true($Product->variants)) { $selected = explode(',', $this->option->options); $s = 0; $variants = isset($Product->options['v']) ? $Product->options['v'] : $Product->options; foreach ((array) $variants as $i => $menu) { foreach ((array) $menu['options'] as $option) { if ($option['id'] == $selected[$s]) { $this->variant[$menu['name']] = $option['name']; break; } } $s++; } } $this->packaging = Shopp::str_true(shopp_product_meta($Product->id, 'packaging')); if (!empty($Price->download)) { $this->download = $Price->download; } $this->shipped = 'Shipped' == $Price->type; if ($this->shipped) { $dimensions = array('weight' => 0, 'length' => 0, 'width' => 0, 'height' => 0); if (Shopp::str_true($Price->shipping)) { $this->shipfee = $Price->shipfee; if (isset($Price->dimensions)) { $dimensions = array_merge($dimensions, $Price->dimensions); } } else { $this->freeshipping = true; } if (isset($Product->addons) && Shopp::str_true($Product->addons)) { $this->addons($dimensions, $addons, $Product->prices, 'dimensions'); $this->addons($this->shipfee, $addons, $Product->prices, 'shipfee'); } foreach ($dimensions as $dimension => $value) { $this->{$dimension} = $value; } if (isset($Product->processing) && Shopp::str_true($Product->processing)) { if (isset($Product->minprocess)) { $this->processing['min'] = $Product->minprocess; } if (isset($Product->maxprocess)) { $this->processing['max'] = $Product->maxprocess; } } } }
/** * shopp_product_set_addon_options - Creates a complete set of addon product options on a specified product, by letting you * specify the set of options types, and corresponding options. This function will create new addon options in the database and * will attach them to the specified product. * * @api * @since 1.2 * * @param int $product (required) The product id of the product that you wish to add the addon options to. * @param array $options (Description...) A two dimensional array describing the addon options. * The outer array is keyed on the name of the option type (Framing, Matting, Glass, etc.) * The inner contains the corresponding option values. * Ex. $options = array( 'Framing' => array('Wood', 'Gold'), 'Glass' => array('Anti-glare', 'UV Protectant') ); * @return array addon Price objects that have been created on the product. * **/ function shopp_product_set_addon_options($product = false, $options = array(), $summary = 'save') { if (!$product || empty($options)) { shopp_debug(__FUNCTION__ . " failed: Missing required parameters."); return false; } $Product = new ShoppProduct($product); if (empty($Product->id)) { shopp_debug(__FUNCTION__ . " failed: Product not found for product id {$product}."); return false; } $Product->load_data(array('summary')); // clean up old variations $table = ShoppDatabaseObject::tablename(ShoppPrice::$table); db::query("DELETE FROM {$table} WHERE product={$product} AND context='addon'"); $prices = array(); $mapping = array(); foreach ($options as $type => $opts) { foreach ($opts as $index => $option) { $addon = array($type => $option); $Price = new ShoppPrice(); $Price->type = 'Shipped'; $Price->product = $product; $Price->context = 'addon'; $Price->sortorder = $index + 2; // default price sort order is 1, start at minimum 2 #2847 list($Price->optionkey, $Price->options, $Price->label, $mapping) = $Product->optionmap($addon, $options, 'addon'); $Price->save(); shopp_set_meta($Price->id, 'price', 'options', $Price->options); $prices[] = $Price; } } $metaopts = shopp_product_meta($product, 'options'); $metaopts['a'] = array(); $i = 1; foreach ($options as $optname => $option) { if (!isset($metaopts['a'][$i])) { $metaopts['a'][$i] = array('id' => $i, 'name' => $optname, 'options' => array()); } foreach ($option as $value) { $metaopts['a'][$i]['options'][$mapping[$optname][$value]] = array('id' => $mapping[$optname][$value], 'name' => $value, 'linked' => "off"); } $i++; } shopp_set_product_meta($product, 'options', $metaopts); $Product->addons = "on"; if ('save' == $summary) { $Product->sumup(); } return $prices; }
/** * shopp_product_meta_count - number of meta entries associated with a product * * @api * @since 1.2 * * @param int $product (required) the product id * @param string $type (optional default: meta) the meta type to count * @return int count of meta entries, false on failure **/ function shopp_product_meta_count($product = false, $type = 'meta') { if (!$product) { shopp_debug(__FUNCTION__ . ' failed: product id required'); return false; } $meta = shopp_product_meta($product, false, $type); return count($meta); }
/** * Returns an array of two elements, the first being the ticket start date and the second the * ticket end date. If a date is not set / cannot be retrieved an empty string will be provided * for that element. * * @param $ticket_id * @return array */ protected function ticket_sale_dates($ticket_id) { $start_date = shopp_product_meta($ticket_id, 'shopptickets_start_date'); $end_date = shopp_product_meta($ticket_id, 'shopptickets_end_date'); if (is_array($start_date)) { $start_date = array_shift($start_date); } if (is_array($end_date)) { $end_date = array_shift($end_date); } return array($start_date !== null ? $start_date : '', $end_date !== null ? $end_date : ''); }