Пример #1
0
	/**
	 * Handles saving updates from the product editor
	 *
	 * Saves all product related information which includes core product data
	 * and supporting elements such as images, digital downloads, tags,
	 * assigned categories, specs and pricing variations.
	 *	 
	 * @return void
	 **/
	function save_product ($Product) {
		$db = DB::get();
		$Settings = &EcartSettings();
		check_admin_referer('ecart-save-product');

		if ( !(is_ecart_userlevel() || current_user_can('ecart_products')) )
			wp_die(__('You do not have sufficient permissions to access this page.'));

		$Settings->saveform(); // Save workflow setting

		$base = $Settings->get('base_operations');
		$taxrate = 0;
		if ($base['vat']) $taxrate = ecart_taxrate(null,true,$Product);

		if (empty($_POST['options'])) $Product->options = array();
		else $_POST['options'] = stripslashes_deep($_POST['options']);

		if (empty($Product->slug)) $Product->slug = sanitize_title_with_dashes($_POST['name']);

		// Check for an existing product slug
		$exclude_product = !empty($Product->id)?"AND id != $Product->id":"";
		$existing = $db->query("SELECT slug FROM $Product->_table WHERE slug='$Product->slug' $exclude_product LIMIT 1");
		if ($existing) {
			$suffix = 2;
			while($existing) {
				$altslug = substr($Product->slug, 0, 200-(strlen($suffix)+1)). "-".$suffix++;
				$existing = $db->query("SELECT slug FROM $Product->_table WHERE slug='$altslug' $exclude_product LIMIT 1");
			}
			$Product->slug = $altslug;
		}

		if ($_POST['status'] == "publish") {
			$publishfields = array('month' => '','date' => '','year' => '','hour'=>'','minute'=>'','meridiem'=>'');
			$publishdate = join('',array_merge($publishfields,$_POST['publish']));
			if (!empty($publishdate)) {
				if ($_POST['publish']['meridiem'] == "PM" && $_POST['publish']['hour'] < 12)
					$_POST['publish']['hour'] += 12;
				$_POST['publish'] = mktime($_POST['publish']['hour'],$_POST['publish']['minute'],0,$_POST['publish']['month'],$_POST['publish']['date'],$_POST['publish']['year']);
			} else {
				unset($_POST['publish']);
				// Auto set the publish date if not set (or more accurately, if set to an irrelevant timestamp)
				if ($Product->publish <= 86400) $Product->publish = time();
			}
		} else {
			unset($_POST['publish']);
			$Product->publish = 0;
		}

		if (isset($_POST['content'])) $_POST['description'] = $_POST['content'];

		$Product->updates($_POST,array('categories','prices'));
		$Product->save();

		$Product->save_categories($_POST['categories']);
		$Product->save_tags(explode(",",$_POST['taglist']));

		if (!empty($_POST['price']) && is_array($_POST['price'])) {

			// Delete prices that were marked for removal
			if (!empty($_POST['deletePrices'])) {
				$deletes = array();
				if (strpos($_POST['deletePrices'],","))	$deletes = explode(',',$_POST['deletePrices']);
				else $deletes = array($_POST['deletePrices']);

				foreach($deletes as $option) {
					$Price = new Price($option);
					$Price->delete();
				}
			}

			// Save prices that there are updates for
			foreach($_POST['price'] as $i => $option) {
				if (empty($option['id'])) {
					$Price = new Price();
					$option['product'] = $Product->id;
				} else $Price = new Price($option['id']);
				$option['sortorder'] = array_search($i,$_POST['sortorder'])+1;

				// Remove VAT amount to save in DB
				if ($base['vat'] && isset($option['tax']) && $option['tax'] == "on") {
					$option['price'] = (floatvalue($option['price'])/(1+$taxrate));
					$option['saleprice'] = (floatvalue($option['saleprice'])/(1+$taxrate));
				}
				$option['shipfee'] = floatvalue($option['shipfee']);

				$option['weight'] = floatvalue($option['weight']);
				if (isset($options['dimensions']) && is_array($options['dimensions']))
					foreach ($option['dimensions'] as &$dimension)
						$dimension = floatvalue($dimension);

				$Price->updates($option);
				$Price->save();

				if (!empty($option['download'])) $Price->attach_download($option['download']);

				if (!empty($option['downloadpath'])) { // Attach file specified by URI/path
					if (!empty($Price->download->id) || (empty($Price->download) && $Price->load_download())) {
						$File = $Price->download;
					} else $File = new ProductDownload();

					$stored = false;
					$tmpfile = sanitize_path($option['downloadpath']);

					$File->storage = false;
					$Engine = $File->_engine(); // Set engine from storage settings

					$File->parent = $Price->id;
					$File->context = "price";
					$File->type = "download";
					$File->name = !empty($option['downloadfile'])?$option['downloadfile']:basename($tmpfile);
					$File->filename = $File->name;

					if ($File->found($tmpfile)) {
						$File->uri = $tmpfile;
						$stored = true;
					} else $stored = $File->store($tmpfile,'file');

					if ($stored) {
						$File->readmeta();
						$File->save();
					}

				} // END attach file by path/uri
			}
			unset($Price);
		}

		// No variation options at all, delete all variation-pricelines
		if (!empty($Product->prices) && is_array($Product->prices)
				&& (empty($_POST['options']['v']) || empty($_POST['options']['a']))) {
			foreach ($Product->prices as $priceline) {
				// Skip if not tied to variation options
				if ($priceline->optionkey == 0) continue;
				if ((empty($_POST['options']['v']) && $priceline->context == "variation")
					|| (empty($_POST['options']['a']) && $priceline->context == "addon")) {
						$Price = new Price($priceline->id);
						$Price->delete();
				}
			}
		}

		if (!empty($_POST['details']) || !empty($_POST['deletedSpecs'])) {
			$deletes = array();
			if (!empty($_POST['deletedSpecs'])) {
				if (strpos($_POST['deletedSpecs'],","))	$deletes = explode(',',$_POST['deletedSpecs']);
				else $deletes = array($_POST['deletedSpecs']);
				foreach($deletes as $option) {
					$Spec = new Spec($option);
					$Spec->delete();
				}
				unset($Spec);
			}

			if (is_array($_POST['details'])) {
				foreach ($_POST['details'] as $i => $spec) {
					if (in_array($spec['id'],$deletes)) continue;
					if (isset($spec['new'])) {
						$Spec = new Spec();
						$spec['id'] = '';
						$spec['parent'] = $Product->id;
					} else $Spec = new Spec($spec['id']);
					$spec['sortorder'] = array_search($i,$_POST['details-sortorder'])+1;

					$Spec->updates($spec);
					$Spec->save();
				}
			}
		}

		if (!empty($_POST['deleteImages'])) {
			$deletes = array();
			if (strpos($_POST['deleteImages'],","))	$deletes = explode(',',$_POST['deleteImages']);
			else $deletes = array($_POST['deleteImages']);
			$Product->delete_images($deletes);
		}

		if (!empty($_POST['images']) && is_array($_POST['images'])) {
			$Product->link_images($_POST['images']);
			$Product->save_imageorder($_POST['images']);
			if (!empty($_POST['imagedetails']))
				$Product->update_images($_POST['imagedetails']);
		}

		do_action_ref_array('ecart_product_saved',array(&$Product));

		unset($Product);
		return true;
	}
Пример #2
0
/**
 * Get a specific Price object
 *
 * @api
 * @since 1.2
 *
 * @param mixed $variant the id of the variant, or array('product'=>int, 'option' => array('menu1name'=>'option', 'menu2name'=>'option') ) to specify variant by product id and option
 * @param string $pricetype (optional default:variant) product, variant, or addon
 * @return ShoppPrice Price object or false on error
 **/
function shopp_product_variant($variant = false, $pricetype = 'variant')
{
    if (false === $variant) {
        shopp_debug(__FUNCTION__ . " failed: Variant id required.");
        return false;
    }
    if (is_numeric($variant)) {
        $Price = new ShoppPrice($variant);
        if (empty($Price->id)) {
            shopp_debug(__FUNCTION__ . " failed: Unable to load variant {$variant}.");
            return false;
        }
    } else {
        if (is_array($variant)) {
            // specifying variant by product id and option
            $Product = new stdClass();
            if (isset($variant['product']) && is_numeric($variant['product'])) {
                $Product = new ShoppProduct($variant['product']);
                $Product->load_data(array('prices', 'meta', 'summary'));
            }
            if (empty($Product->id) || empty($Product->prices)) {
                shopp_debug(__FUNCTION__ . " failed: Unable to load variant.  Invalid Product.");
                return false;
            }
            $pricetype = $pricetype == 'variant' ? 'variation' : $pricetype;
            $pricetypes = array('product', 'variation', 'addon');
            if (!in_array($pricetype, $pricetypes)) {
                shopp_debug(__FUNCTION__ . " failed: Invalid pricetype.  Can be product, variant, or addon.");
                return false;
            }
            if ('product' == $pricetype) {
                // No product context for product with variants
                if ('on' == $Product->variants) {
                    shopp_debug(__FUNCTION__ . " failed: Invalid pricetype for this product.");
                    return false;
                }
                foreach ($Product->prices as $price) {
                    if ('product' == $price->context) {
                        $Price = new ShoppPrice();
                        $Price->populate($price);
                        $Price->load_settings();
                        $Price->load_download();
                        break;
                    }
                }
            } else {
                // addon or variant
                if (!isset($variant['option']) || !is_array($variant['option']) || empty($variant['option'])) {
                    shopp_debug(__FUNCTION__ . " failed: Missing option array.");
                    return false;
                }
                $menukey = substr($pricetype, 0, 1);
                $flag = $pricetype == 'variation' ? 'variants' : 'addons';
                if (!isset($Product->options[$menukey]) || $Product->{$flag} == 'off') {
                    shopp_debug(__FUNCTION__ . " failed: No product variant options of type {$pricetype} for product {$Product->id}");
                    return false;
                }
                // build simple option menu array
                $menu = array();
                foreach ($Product->options[$menukey] as $optionmenu) {
                    $key = $optionmenu['name'];
                    $menu[$key] = array();
                    foreach ($optionmenu['options'] as $option) {
                        $menu[$key][] = $option['name'];
                    }
                }
                list($optionkey, $options, $label, $mapping) = $Product->optionmap($variant['option'], $menu, $pricetype);
                if ('variation' == $pricetype && !isset($Product->pricekey[$optionkey]) || !$options) {
                    shopp_debug(__FUNCTION__ . " failed: Invalid option.");
                    return false;
                }
                if ('variation' == $pricetype) {
                    $price = $Product->pricekey[$optionkey];
                } else {
                    // Find the option
                    foreach ($Product->prices as $price) {
                        if ($price->context == $pricetype && $price->options == $options) {
                            break;
                        }
                    }
                }
                $Price = new Price();
                $Price->populate($price);
                $Price->load_settings();
                $Price->load_download();
            }
            // end if product type / addon/variants type
        }
    }
    if (!isset($Price)) {
        shopp_debug(__FUNCTION__ . " failed: Product, Variant, or Addon Price object could not be found.");
        return false;
    }
    return $Price;
}