Example #1
0
	private function HandleVariations($row)
	{
		//========Product Variations==========//

		if ($row['prodvariationid'] == 0) {
			$row['productVariations'] = array();
			return $row;
		}

		// get the position of the options in the variation fields
		$option_position = $this->GetFieldPosition('productVarDetails', $this->fields['productVariations']['fields']);

		// get the variation options
		$query = "SELECT * FROM [|PREFIX|]product_variation_options WHERE vovariationid = " . $row['prodvariationid'] . " ORDER BY voptionid";
		$result = $GLOBALS['ISC_CLASS_DB']->Query($query);
		$options_cache = array();
		while ($optionRow = $GLOBALS['ISC_CLASS_DB']->Fetch($result)) {
			$options_cache[$optionRow['voname']][] = array("id" => $optionRow['voptionid'], "value" => $optionRow['vovalue']);
		}

		// get a list of all possible combinations using the options for this variation
		$options = Interspire_Array::generateCartesianProduct($options_cache, true);

		$new_options = array();

		// the options for each variation
		foreach ($options as $option) {
			$optionids = "";
			$description = "";

			// build strings of the id's and values of each option
			foreach ($option as $key => $value) {
				if ($optionids) {
					$optionids .= ",";
				}
				$optionids .= $value["id"];

				if ($description) {
					$description .= ", ";
				}
				$description .= $key . ": " . $value["value"];
			}

			$new_options[$optionids] = array(
				"options"		=> $option,
				"description"	=> $description
			);
		}

		// get the data for the combinations
		$query = "SELECT * FROM [|PREFIX|]product_variation_combinations WHERE vcproductid = " . $row['prodid'];
		$result = $GLOBALS['ISC_CLASS_DB']->Query($query);
		while ($comborow = $GLOBALS['ISC_CLASS_DB']->Fetch($result)) {
			// get the specific combination of options
			$options = $new_options[$comborow['vcoptionids']]['options'];

			$prodoptions = array();

			$prodoptions['productVarDetails']		= $new_options[$comborow['vcoptionids']]['description'];
			$prodoptions['productVarSKU']			= $comborow['vcsku'];
			switch ($comborow['vcpricediff']) {
				case "add":
					$pricediff = "+";
					break;
				case "substract":
					$pricediff = "-";
					break;
				default:
					$pricediff = "";
			}
			$prodoptions['productVarPrice'] = $pricediff . $comborow['vcprice'];
			switch ($comborow['vcweightdiff']) {
				case "add":
				$weightdiff = "+";
					break;
				case "substract":
					$weightdiff = "-";
					break;
				default:
					$weightdiff = "";
			}
			$prodoptions['productVarWeight']		= $weightdiff . $comborow['vcweight'];
			$prodoptions['productVarStockLevel']	= $comborow['vcstock'];
			$prodoptions['productVarLowStockLevel']	= $comborow['vclowstock'];

			$prodoptions = $this->CreateSubItemArray($prodoptions, $this->fields['productVariations']['fields']);

			if ($this->fields['productVariations']['fields']['productVarDetails']['used']) {
				$optionkeys = array();
				$optionvalues = array();

				foreach ($options as $key => $value) {
					$optionvalues[$key] = $value['value'];
					$optionkeys[] = $key;
				}

				$keys = array_keys($prodoptions);
				// insert the fields into correct position
				array_splice($prodoptions, $option_position, 0, $optionvalues);
				array_splice($keys, $option_position, 0, $optionkeys);

				$prodoptions = array_combine($keys, $prodoptions);
			}

			$prodvariations[] = $prodoptions;
		}

		$row["productVariations"] = $prodvariations;

		return $row;
	}
	private function continueRebuildVariationsAction()
	{
		$sessionId = $_POST['session'];

		if (!isset($_SESSION['variations'][$sessionId])) {
			ISC_JSON::output('session ' . $sessionId . ' not found', false);
		}

		$session = &$_SESSION['variations'][$sessionId];

		// get the next product id
		$query = "
			SELECT
				productid
			FROM
				[|PREFIX|]products
			WHERE
				productid > " . $session['lastProductId'] . " AND
				prodvariationid = " . $session['variationId'] . "
			ORDER BY
				productid
			LIMIT
				1
		";

		$res = $this->db->Query($query);
		$productId = $this->db->FetchOne($res);

		// no more products to process? done.
		if (empty($productId)) {
			unset($_SESSION['variations'][$sessionId]);
			if (empty($_SESSION['variations'])) {
				unset($_SESSION['variations']);
			}
			ISC_JSON::output('', true, array('done' => true));
		}

		if ($this->db->StartTransaction() === false) {
			ISC_JSON::output('failed to start transaction', false);
		}

		$existingData = $session['existingData'];

		// were new option values (eg a new colour) added? we'll need to create some blank combinations to fill in the missing gaps.
		if (!empty($session['newValues'])) {
			$newValues = $session['newValues'];

			// iterate over the new option values
			foreach ($newValues as $optionName => $newValueIds) {
				foreach ($newValueIds as $newValueId) {
					// build combination id set
					$optionIdSets = array();

					foreach ($existingData['options'] as $optionIndex => $option) {
						if ($optionName == $option['name']) {
							$optionIdSets[$optionIndex][] = $newValueId;
							continue;
						}

						foreach ($option['values'] as $valueIndex => $value) {
							$optionIdSets[$optionIndex][] = $value['valueid'];
						}
					}

					// build a cartesian product of all the combinations that we need to generate
					$cartesian = Interspire_Array::generateCartesianProduct($optionIdSets);

					// iterate over each combination and insert to DB for all products using this variation
					foreach ($cartesian as $combination) {
						$combinationString = implode(',', $combination);

						$newCombination = array(
							'vcproductid'		=> $productId,
							'vcvariationid'		=> $session['variationId'],
							'vcoptionids'		=> $combinationString,
							'vclastmodified'	=> time(),
						);

						$this->db->InsertQuery('product_variation_combinations', $newCombination);
					}
				}
			}
		}

		// process new option set (eg. Material)
		if (!empty($session['newOptionValues'])) {
			$valuesForNewOption = $session['newOptionValues'];

			$likeMatch = str_repeat(",%", count($existingData['options']) - 2);
			$likeMatch = "%" . $likeMatch;

			foreach ($valuesForNewOption as $newOptionIndex => $newValueIds) {
				$newOptionCount = 0;

				foreach ($newValueIds as $newValueId) {
					// for the first new option value, we don't want to insert new combinations, but update the existing ones
					// store the option id for later and continue on
					if ($newOptionCount == 0) {
						$delayForUpdate = $newValueId;

						$newOptionCount++;
						continue;
					}

					$query = "
						INSERT INTO
							[|PREFIX|]product_variation_combinations (vcproductid, vcproducthash, vcvariationid, vcenabled, vcoptionids, vcsku, vcpricediff, vcprice, vcweightdiff, vcweight, vcimage, vcimagezoom, vcimagestd, vcimagethumb, vcstock, vclowstock, vclastmodified)
							SELECT
								vcproductid,
								vcproductid,
								vcvariationid,
								vcenabled,
								CONCAT(vcoptionids, ',', " . $newValueId . "),
								vcsku,
								vcpricediff,
								vcprice,
								vcweightdiff,
								vcweight,
								vcimage,
								vcimagezoom,
								vcimagestd,
								vcimagethumb,
								vcstock,
								vclowstock,
								" . time() . "
							FROM
								[|PREFIX|]product_variation_combinations
							WHERE
								vcproductid = " . $productId . " AND
								vcproducthash = ''
					";

					$this->db->Query($query);

					$newOptionCount++;
				}
			}

			// for the first new option id, add it onto the remaining existing row
			if (!empty($delayForUpdate)) {
				$query = "
					UPDATE
						[|PREFIX|]product_variation_combinations
					SET
						vcoptionids = CONCAT(vcoptionids, ',', " . $delayForUpdate . ")
					WHERE
						vcproductid = " . $productId . " AND
						vcproducthash = ''
				";

				$this->db->Query($query);
			}

			// blank the hash
			$query = "
				UPDATE
					[|PREFIX|]product_variation_combinations
				SET
					vcproducthash = ''
				WHERE
					vcproductid = " . $productId . "
			";
			$this->db->Query($query);
		}

		if ($this->db->CommitTransaction() === false) {
			$this->db->RollbackTransaction();
			ISC_JSON::output('failed to commit transaction', false);
		}

		$session['lastProductId'] = $productId;

		ISC_JSON::output('', true);
	}
Example #3
0
/**
* Returns an array containing all possible variation combinations
*
* @param int The product ID to get combinations for
* @param string Optional option name to exclude in the combinations
* @return array Array of all combinations
*/
function GetVariationCombinations($productID, $excludeOption = '')
{
	$where = "";
	if ($excludeOption) {
		$where = " AND voname != '" . $GLOBALS['ISC_CLASS_DB']->Quote($excludeOption) . "' ";
	}

	$query = "
		SELECT
			voname,
			GROUP_CONCAT(voptionid ORDER BY voptionid) AS optionids
		FROM
			[|PREFIX|]product_variation_options
			INNER JOIN [|PREFIX|]products p ON vovariationid = prodvariationid
		WHERE
			p.productid = " . $productID . "
			" . $where . "
		GROUP BY
			voname
	";
	$result = $GLOBALS['ISC_CLASS_DB']->Query($query);
	$optionArray = array();
	while ($optionRow = $GLOBALS['ISC_CLASS_DB']->Fetch($result)) {
		$optionArray[$optionRow['voname']] = explode(',', $optionRow['optionids']);
	}

	// calculate all the combinations
	return Interspire_Array::generateCartesianProduct($optionArray, true);
}