/**
	* This function loads the next row from the database and populates an instance of the ISC_PRODUCT_IMAGE class with the returned table row. This is then set as the current object for the loop.
	* Implemented from as a requirement of the iterator interface.
	*
	* @return void
	* @see currentRow
	* @see rowNumber
	*/

	public function next()
	{
		++$this->rowNumber;

		$row = $this->db->Fetch($this->result);

		if(!$row) {
			$this->currentRow = false;
			return false;
		}

		$this->currentRow = new ISC_PRODUCT_IMAGE();
		$this->currentRow->populateFromDatabaseRow($row);
	}
Example #2
0
		private function BulkUpdateVariations()
		{
			$productId = 0;
			$vid = 0;
			$inv = 0;
			$useHash = false;

			if(isset($_GET['v']) && is_numeric($_GET['v']) && isset($_GET['inv']) && is_numeric($_GET['inv'])) {
				$vid = (int)$_GET['v'];
				$inv = (bool)$_GET['inv'];
			}

			if (isset($_GET['productId'])) {
				$productId = (int)$_GET['productId'];
			}

			if (isId($productId)) {
				$query = 'SELECT prodvariationid FROM [|PREFIX|]products WHERE productid = ' . $productId;
				$res = $GLOBALS['ISC_CLASS_DB']->Query($query);
				if ($row = $GLOBALS['ISC_CLASS_DB']->Fetch($res)) {
					if ($row['prodvariationid'] != $vid) {
						$useHash = true;
					}
				}
			}

			if (!empty($_GET['productHash'])) {
				$useHash = true;
				$productId = $GLOBALS['ISC_CLASS_DB']->Quote($_GET['productHash']);
			}

			if ($useHash) {
				$whereSQL = "vcproductid = 0 AND vcproducthash = '" . $productId . "' ";
			}
			else {
				$whereSQL = 'vcproductid = ' . $productId . ' ';
			}

			$filterOptions = array();
			if (isset($_GET['filterOptions'])) {
				parse_str($_GET['filterOptions'], $filterOptions);
			}

			// create the sql to update the filtered options
			$optionSQL = '';
			if (!empty($filterOptions)) {
				foreach ($filterOptions as $optionName => $optionValues) {
					$thisOptionSQL = '';
					foreach ($optionValues as $value) {
						if ($value == 'all') {
							continue;
						}

						if ($thisOptionSQL) {
							$thisOptionSQL .= ' OR ';
						}
						$thisOptionSQL .= "CONCAT(',', vcoptionids, ',') LIKE '%," . $value . ",%'";
					}

					if ($thisOptionSQL) {
						if ($optionSQL) {
							$optionSQL .= " AND ";
						}

						$optionSQL .= "(" . $thisOptionSQL . ")";
					}
				}
			}

			if ($optionSQL != '') {
				$optionSQL = ' AND ' . $optionSQL;
			}

			$updates = array();
			switch ($_GET['updatePurchaseable']) {
				case "reset":
				case "yes":
					$updates[] = "vcenabled = '1'";
					break;
				case "no":
					$updates[] = "vcenabled = '0'";
					break;
			}

			switch ($_GET['updatePriceDiff']) {
				case "reset":
					$updates[] = "vcpricediff = ''";
					$updates[] = "vcprice = 0";
					break;
				case "add":
				case "subtract":
				case "fixed":
					$updates[] = "vcpricediff = '" . $_GET['updatePriceDiff'] . "'";
					$updates[] = "vcprice = " . (float)$_GET['updatePrice'];
					break;
			}

			switch ($_GET['updateWeightDiff']) {
				case "reset":
					$updates[] = "vcweightdiff = ''";
					$updates[] = "vcweight = 0";
					break;
				case "add":
				case "subtract":
				case "fixed":
					$updates[] = "vcweightdiff = '" . $_GET['updateWeightDiff'] . "'";
					$updates[] = "vcweight = " . (float)$_GET['updateWeight'];
					break;
			}

			if ($inv) {
				if ($_GET['updateStockLevel'] != '') {
					$updates[] = 'vcstock = ' . (int)$_GET['updateStockLevel'];
				}

				if ($_GET['updateLowStockLevel'] != '') {
					$updates[] = 'vclowstock = ' . (int)$_GET['updateLowStockLevel'];
				}
			}

			// delete existing images?
			if (isset($_GET['updateDelImages'])) {
				// get distinct images not associated with variations that aren't in the current filter
				$query = '
					SELECT
						vcimagezoom,
						vcimagestd,
						vcimagethumb
					FROM
						[|PREFIX|]product_variation_combinations pvc
					WHERE
						' . $whereSQL .
						$optionSQL . '
					GROUP BY
						vcimagezoom
					HAVING
						COUNT(*) = (
									SELECT
										COUNT(*)
									FROM
										[|PREFIX|]product_variation_combinations pvc2
									WHERE
										pvc2.vcproductid = pvc.vcproductid AND
										pvc2.vcimagezoom = pvc.vcimagezoom
									)
				';

				$res = $GLOBALS['ISC_CLASS_DB']->Query($query);
				while ($row = $GLOBALS['ISC_CLASS_DB']->Fetch($res)) {
					GetClass('ISC_ADMIN_PRODUCT')->DeleteVariationImagesForRow($row);
				}

				$updates[] = "vcimage = ''";
				$updates[] = "vcimagezoom = ''";
				$updates[] = "vcimagestd = ''";
				$updates[] = "vcimagethumb = ''";
			}
			// import image
			elseif (isset($_FILES['updateImage'])) {
				try {
					$image = ISC_PRODUCT_IMAGE::importImage($_FILES['updateImage']['tmp_name'], $_FILES['updateImage']['name'], false, false, true, false);

					$zoom = $image->getResizedFilePath(ISC_PRODUCT_IMAGE_SIZE_ZOOM, true, false);
					$standard = $image->getResizedFilePath(ISC_PRODUCT_IMAGE_SIZE_STANDARD, true, false);
					$thumb = $image->getResizedFilePath(ISC_PRODUCT_IMAGE_SIZE_THUMBNAIL, true, false);

					$updates[] = "vcimage = '" . $image->getSourceFilePath() . "'";
					$updates[] = "vcimagezoom = '" . $zoom . "'";
					$updates[] = "vcimagestd = '" . $standard . "'";
					$updates[] = "vcimagethumb = '" . $thumb . "'";
				}
				catch (Exception $ex) {

				}
			}

			if (!empty($updates)) {
				$updates[] = "vclastmodified = " . time();

				$updateSQL = implode(', ', $updates);

				// update the combinations
				$query = 'UPDATE [|PREFIX|]product_variation_combinations SET ' . $updateSQL . ' WHERE ' . $whereSQL . $optionSQL;
				$GLOBALS['ISC_CLASS_DB']->Query($query);
			}

			// regenerate the combinations table to get fresh data
			$html = $this->GetVariationCombinationsTable($filterOptions, true);
			$response['tableData'] = $html;
			echo '<textarea>'.isc_json_encode($response).'</textarea>';
			exit;
		}
Example #3
0
	/**
	 * Generate the product images/thumbnails to be shown.
	 */
	private function SetProductImages()
	{

		$GLOBALS['ProductThumbWidth'] = ISC_PRODUCT_IMAGE::getSizeWidth(ISC_PRODUCT_IMAGE_SIZE_STANDARD);
		$GLOBALS['ProductThumbHeight'] = ISC_PRODUCT_IMAGE::getSizeHeight(ISC_PRODUCT_IMAGE_SIZE_STANDARD);

		$GLOBALS['ProductMaxTinyWidth'] = ISC_PRODUCT_IMAGE::getSizeWidth(ISC_PRODUCT_IMAGE_SIZE_TINY);
		$GLOBALS['ProductMaxTinyHeight'] = ISC_PRODUCT_IMAGE::getSizeHeight(ISC_PRODUCT_IMAGE_SIZE_TINY);



		$GLOBALS['ProductTinyBoxWidth'] = $GLOBALS['ProductMaxTinyWidth']+4;
		$GLOBALS['ProductTinyBoxHeight'] = $GLOBALS['ProductMaxTinyHeight']+4;


		$GLOBALS['ProductMaxZoomWidth'] = ISC_PRODUCT_IMAGE::getSizeWidth(ISC_PRODUCT_IMAGE_SIZE_ZOOM);
		$GLOBALS['ProductMaxZoomHeight'] = ISC_PRODUCT_IMAGE::getSizeHeight(ISC_PRODUCT_IMAGE_SIZE_ZOOM);

		$GLOBALS['ProductZoomWidth'] = ISC_PRODUCT_IMAGE::getSizeWidth(ISC_PRODUCT_IMAGE_SIZE_ZOOM);
		$GLOBALS['ProductZoomHeight'] = ISC_PRODUCT_IMAGE::getSizeHeight(ISC_PRODUCT_IMAGE_SIZE_ZOOM);


		$productImages = ISC_PRODUCT_IMAGE::getProductImagesFromDatabase($GLOBALS['ProductId']);
		$GLOBALS['NumProdImages'] = count($productImages);

		$GLOBALS['CurrentProdThumbImage'] = 0;
		$thumb = '';
		$curZoomImage = '';
		$GLOBALS['SNIPPETS']['ProductTinyImages'] = '';
		$GLOBALS['HideImageCarousel'] = 'display:none;';
		$GLOBALS['HideMorePicturesLink'] = 'display:none;';
		$thumbImageDescription = '';
		$i = 0;

		$GLOBALS['ProdImageJavascript'] = '';
		$GLOBALS['ProdImageZoomJavascript'] = '';
		$GLOBALS['LightBoxImageList'] = '';
		$GLOBALS['ZoomImageMaxWidth'] = 0;
		$GLOBALS['ZoomImageMaxHeight'] = 0;
		$GLOBALS['ZoomImageMaxWidthHeight'] = 0;
		$GLOBALS['HideAlwaysLinkedMorePicturesLink'] = 'display: none';

		if ($GLOBALS['NumProdImages']) {
			//Show image carousel

			if ($GLOBALS['NumProdImages'] == 2) {
				$var = "MorePictures1";
			} else if ($GLOBALS['NumProdImages'] == 1) {
				$var = "SeeLargerImage";
			} else {
				$var = "MorePictures2";
			}

			$GLOBALS['SeeMorePictures'] = sprintf(GetLang($var), count($productImages) - 1);
			$GLOBALS['HideAlwaysLinkedMorePicturesLink'] = '';

			if (GetConfig('ProductImagesTinyThumbnailsEnabled')) {
				$GLOBALS['HideImageCarousel'] = '';
			} else {
				$GLOBALS['HideMorePicturesLink'] = '';
			}

			$continue=false;

			foreach ($productImages as $productImage) {

				$thumbURL = '';
				$zoomImageURL = '';

				try{
					$thumbURL = $productImage->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_STANDARD, true);
					//$GLOBALS['ProductThumbURL'] = $thumbURL;
				} catch (Exception $exception) {
					// do nothing, will result in returning blank string, which is fine
				}

				try{
					$zoomImageURL = $productImage->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_ZOOM, true);
				} catch (Exception $exception) {
					// do nothing, will result in returning blank string, which is fine
				}

				if($thumbURL == '' && $zoomImageURL == '') {
					continue;
				}

				$resizedZoomDimension = $productImage->getResizedFileDimensions(ISC_PRODUCT_IMAGE_SIZE_ZOOM);
				$resizedTinyDimension = $productImage->getResizedFileDimensions(ISC_PRODUCT_IMAGE_SIZE_TINY);

				//calculate the max zoom image width and height
				if ($GLOBALS['ZoomImageMaxWidth'] < $resizedZoomDimension[ISC_PRODUCT_IMAGE_DIMENSIONS_WIDTH]) {

					$GLOBALS['ZoomImageMaxWidth'] = $resizedZoomDimension[ISC_PRODUCT_IMAGE_DIMENSIONS_WIDTH];
					//the height of the image has got the max width needed to calulate the image fancy box size.
					$GLOBALS['ZoomImageMaxWidthHeight'] = $resizedZoomDimension[ISC_PRODUCT_IMAGE_DIMENSIONS_HEIGHT];
				}

				if ($GLOBALS['ZoomImageMaxHeight'] < $resizedZoomDimension[ISC_PRODUCT_IMAGE_DIMENSIONS_HEIGHT]) {
					$GLOBALS['ZoomImageMaxHeight'] = $resizedZoomDimension[ISC_PRODUCT_IMAGE_DIMENSIONS_HEIGHT];
					//the width of the image has got the max height needed to calulate the image fancy box size.
					$GLOBALS['ZoomImageMaxHeightWidth'] = $resizedZoomDimension[ISC_PRODUCT_IMAGE_DIMENSIONS_HEIGHT];
				}

				$GLOBALS['ImageDescription'] = isc_html_escape($productImage->getDescription());
				if($GLOBALS['ImageDescription'] == '') {
					$GLOBALS['ImageDescription'] = GetLang("Image") . " " . ($i + 1);
				}

				//show image carousel
				if(GetConfig('ProductImagesTinyThumbnailsEnabled')==1) {

					$GLOBALS['ProdImageJavascript'] .= "
						ThumbURLs[".$i."] = " . isc_json_encode($thumbURL) . ";
						ProductImageDescriptions[".$i."] = " . isc_json_encode($GLOBALS['ImageDescription']) . ";
					";
					$GLOBALS['TinyImageOverJavascript'] = "showProductThumbImage(".$i.")";
					//$GLOBALS['ProductTinyImageURL'] = $productImage->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_TINY, true);

					try{
						$GLOBALS['ProductTinyImageURL'] = $productImage->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_TINY, true);
						//$GLOBALS['ProductThumbURL'] = $thumbURL;
					} catch (Exception $exception) {
						// do nothing, will result in returning blank string, which is fine
					}

					$GLOBALS['ProductThumbIndex'] = $i;
					if(GetConfig('ProductImageMode') == 'lightbox') {
						$GLOBALS['TinyImageClickJavascript'] = "showProductImageLightBox(".$i."); return false;";

					} else {
						$GLOBALS['TinyImageClickJavascript'] = "showProductImage('".GetConfig('ShopPath')."/productimage.php', ".$GLOBALS['ProductId'].", ".$i.");";
					}

					$GLOBALS['TinyImageWidth'] = $resizedTinyDimension[ISC_PRODUCT_IMAGE_DIMENSIONS_WIDTH];
					$GLOBALS['TinyImageHeight'] = $resizedTinyDimension[ISC_PRODUCT_IMAGE_DIMENSIONS_HEIGHT];
					$GLOBALS['TinyImageTopPadding'] = floor(($GLOBALS['ProductMaxTinyHeight'] - $GLOBALS['TinyImageHeight']) / 2);
					$GLOBALS['SNIPPETS']['ProductTinyImages'] .= $GLOBALS['ISC_CLASS_TEMPLATE']->GetSnippet("ProductTinyImage");
					$continue = true;
				}

				if(GetConfig('ProductImagesImageZoomEnabled') == 1) {
					//check if zoom image is large enough for image zoomer
					if($resizedZoomDimension[ISC_PRODUCT_IMAGE_DIMENSIONS_WIDTH]<ISC_PRODUCT_IMAGE_MIN_ZOOM_WIDTH && $resizedZoomDimension[ISC_PRODUCT_IMAGE_DIMENSIONS_HEIGHT]<ISC_PRODUCT_IMAGE_MIN_ZOOM_HEIGHT) {
						$zoomImageURL = '';
					}
					$GLOBALS['ProdImageZoomJavascript'] .= "
						ZoomImageURLs[".$i."] = " . isc_json_encode($zoomImageURL) . ";
					";
					$continue = true;
				}

				//	$GLOBALS['ProductZoomImageURL'] = $zoomImageURL;

				//this image is the product page thumbnail
				if($i==0) {
					//get the thumb image for product page
					$thumb = $thumbURL;
					$curZoomImage = $zoomImageURL;
					$thumbImageDescription = $GLOBALS['ImageDescription'];
					//if there is no need to loop through images anymore, get out from the loop.
					if($continue === false) {
						break;
					}
				}
				$i++;
			}
		}

		$GLOBALS['VisibleImageTotal'] = $i+1;

		$GLOBALS['ShowImageZoomer'] = GetConfig('ProductImagesImageZoomEnabled');
		if ($GLOBALS['ShowImageZoomer']) {
			$GLOBALS['SNIPPETS']['ProductImageZoomer'] = $GLOBALS['ISC_CLASS_TEMPLATE']->GetSnippet("ProductImageZoomer");
		}
		$GLOBALS['ZoomImageURL'] = $curZoomImage;

		//if no product thumb images
		if($thumb == '') {
			if(GetConfig('DefaultProductImage') == 'template') {
				$thumb = $GLOBALS['IMG_PATH'].'/ProductDefault.gif';
			}
			else {
				$thumb = GetConfig('ShopPath').'/'.GetConfig('DefaultProductImage');
			}
		}

		// need to check for variation images
		//$GLOBALS['HideOnNoImages'] = 'display: none;';
		$GLOBALS['ImageDescription'] = $thumbImageDescription;
		$GLOBALS['ThumbImageURL'] = $thumb;


		//image popup javascript for the thumbnail image when the page is loaded
		$imagePopupLink = "showProductImage('".GetConfig('ShopPath')."/productimage.php', ".$GLOBALS['ProductId'].");";
		$GLOBALS['ImagePopupLink'] = $imagePopupLink;
		$GLOBALS['TinyImageClickJavascript'] = $imagePopupLink;

		// If we're showing images as a lightbox, we need to load up the URLs for the other images for this product
		if(GetConfig('ProductImageMode') == 'lightbox') {
			$GLOBALS['TinyImageClickJavascript'] = "showProductImageLightBox(); return false;";
			$GLOBALS['LightBoxImageJavascript'] = $GLOBALS['ISC_CLASS_TEMPLATE']->GetSnippet('ProductImagesLightBox');
		}

		if ($GLOBALS['NumProdImages']) {
			$GLOBALS['SNIPPETS']['ProductThumbImage'] = $GLOBALS['ISC_CLASS_TEMPLATE']->GetSnippet('ProductThumbImage');
		} else {
			$GLOBALS['SNIPPETS']['ProductThumbImage'] = $GLOBALS['ISC_CLASS_TEMPLATE']->GetSnippet('ProductThumbImagePlaceholder');
		}
	}
Example #4
0
		private function _BuildProductFeed($feedTitle, $feedDescription, $feedId, $sortField, $sortOrder, $searchTerms=array())
		{
			$this->_SetFeedDetails();

			$feed = new ISC_FEED_GENERATOR($feedId, $this->_type, (int)GetConfig('RSSCacheTime')*60);

			$channel = array(
				"title" => $feedTitle,
				"description" => $feedDescription,
				"link" => $GLOBALS['ShopPath'],
				'namespaces' => array(
					'isc' => array(
						//'http://dtd.interspire.com/rss/isc-1.0.dtd',
				        '',
						array(
							'store_title' => getConfig('StoreName')
						)
					)
				)
			);
			$feed->SetChannel($channel);

			// The magical Unreal Shopping Cart RSS feeds are actually just custom searches so pipe it off to our search function
			$searchterms = BuildProductSearchTerms($searchTerms);

			$searchQueries = BuildProductSearchQuery($searchterms, '', $sortField, $sortOrder);

			// Run the query
			$searchQueries['query'] .= $GLOBALS['ISC_CLASS_DB']->AddLimit(0, (int)GetConfig('RSSItemsLimit'));
			$result = $GLOBALS['ISC_CLASS_DB']->Query($searchQueries['query']);

			while($product = $GLOBALS['ISC_CLASS_DB']->Fetch($result)) {
				if(isc_strlen($product['proddesc']) > 300) {
					$product['proddesc'] = isc_substr($product['proddesc'], 0, 298)."..";
				}

				$item = array(
					'title' => $product['prodname'],
					'date' => $product['proddateadded'],
					'link' => prodLink($product['prodname']),
					'namespaces' => array(
						'isc' => array(
							'description' => $product['proddesc'],
							'productid' => $product['productid'],
						)
					)
				);

				if($product['imagefile']) {
					$thumb = ImageThumb($product, ProdLink($product['prodname']));
					$product['proddesc'] = sprintf("<div style='float: right; padding: 10px;'>%s</div>%s", $thumb, $product['proddesc']);

					$image = new ISC_PRODUCT_IMAGE;
					$image->populateFromDatabaseRow($product);

					try {
						$item['namespaces']['isc']['thumb'] = $image->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_THUMBNAIL, true);
					} catch (Exception $exception) { }

					try {
						$item['namespaces']['isc']['image'] = $image->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_ZOOM, true);
					} catch (Exception $exception) { }

					unset ($image);
				}

				// Determine the price of this product
				$price = '';
				if (GetConfig('ShowProductPrice') && !$product['prodhideprice']) {
					$calcPrice = $product['prodcalculatedprice'];
					$plainPrice = formatProductPrice($product, $calcPrice, array(
						'strikeRetail' => false,
						'displayInclusive' => getConfig('taxDefaultTaxDisplayCatalog')
					));

					if($plainPrice) {
						$item['namespaces']['isc']['price'] = $plainPrice;
						$price = '<strong>'.getLang('Price').': '.$plainPrice.'</strong>';
					}
				}

				if(GetConfig('ShowProductRating')) {
					$ratingImage = $GLOBALS['IMG_PATH'].'/IcoRating'.(int)$product['prodavgrating'].'.gif';
					$item['namespaces']['isc']['rating'] = (int)$product['prodavgrating'];
					$item['namespaces']['isc']['rating_image'] = $ratingImage;

					$ratingImage = '<img src="'.$ratingImage.'" alt="" />';
				}
				else {
					$ratingImage = '';
				}

				$product['proddesc'] .= '<p>'.$price.' '.$ratingImage.'</p>';

				$item['description'] = $product['proddesc'];
				$feed->AddItem($item);
			}

			// Send the feed to the browser
			$feed->OutputFeed();

		}
Example #5
0
	/**
	* Sets the product data to be used to determine certain template options such as start, reserve prices etc.
	*
	* @param array $productData
	*/
	public function setProductData($productData)
	{
		$this->_productData = $productData;

		// set the item image
		if (isset($this->_productData['imageid'])) {
			$image = new ISC_PRODUCT_IMAGE;
			$image->populateFromDatabaseRow($this->_productData);

			try {
				$this->_itemImage = $image->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_STANDARD, true, true, false);
			} catch (Exception $exception) { }
		}
	}
Example #6
0
	private function _ImportImage($productId, $record, $index = '')
	{
		$existingImage = false;
		$imageId = 0;

		if (!empty($record['prodimageid' . $index]) && IsId($record['prodimageid' . $index])) {
			$imageId = $record['prodimageid' . $index];
			try {
				$existingImage = new ISC_PRODUCT_IMAGE((int)$imageId);
				if ($existingImage->getProductId() != $productId) {
					// the existing image doesn't belong to this product
					$existingImage = false;
				}
			}
			catch (Exception $ex) {
			}
		}
		$imageFile = $record['prodimagefile' . $index];
		$imageDescription = '';
		if (!empty($record['prodimagedescription' . $index])) {
			$imageDescription = $record['prodimagedescription' . $index];
		}
		$imageIsThumb = false;
		if (!empty($record['prodimageisthumb' . $index])) {
			$imageIsThumb = $record['prodimageisthumb' . $index];
		}
		$imageSort = -1;
		if (isset($record['prodimagesort' . $index]) && $record['prodimagesort' . $index] != '') {
			$imageSort = (int)$record['prodimagesort' . $index];
		}

		$importedImage = false;

		if (!$existingImage || $existingImage->getSourceFilePath() != $imageFile) {
			if (preg_match('#^(?P<scheme>[a-zA-Z0-9\.]+)://#i', $imageFile, $matches)) {
				// code exists in the new product image management classes to handle these imports
				$imageAdmin = new ISC_ADMIN_PRODUCT_IMAGE();

				// the filename is an external URL, import it against the calcualted product hash
				$imageAdmin->importImagesFromUrls(false, array($imageFile), $importImages, $importImageErrors, false, true);

				if (!empty($importImages)) {
					$importedImage = $importImages[0];
				}

				if (!empty($importImageErrors)) {
					// as this import works on one file only and importImagesFromWebUrls creates one error per file, can simply tack on the new error
					$importImageError = $importImageErrors[0];
					if (is_array($importImageError)) {
						$this->ImportSession['Results']['Warnings'][] = $importImageError[1];
					} else {
						$this->ImportSession['Results']['Warnings'][] = $importImageError;
					}
				}
			} else {
				// the filename is a local file
				$importImageFilePath = ISC_BASE_PATH . "/" . GetConfig('ImageDirectory') . "/import/" . $imageFile;
				if (file_exists($importImageFilePath)) {
					try {
						$importedImage = ISC_PRODUCT_IMAGE::importImage($importImageFilePath, basename($importImageFilePath), false, false, false, false);
						$productImages[] = $importedImage;
					} catch (Exception $exception) {
						$this->ImportSession['Results']['Warnings'][] = $exception->getMessage();
					}
				}
				else {
					$this->ImportSession['Results']['Warnings'][] = $record['prodname'].GetLang('ImportProductImageDoesntExist');
				}
			}
		}

		// do we have an existing image?
		if ($existingImage) {
			// assign the imported image file to our existing image
			if ($importedImage) {
				$existingImage->setSourceFilePath($importedImage->getSourceFilePath());
				$existingImage->saveToDatabase(false);
			}

			// use the existing image to set the description, thumb, sort
			$importedImage = $existingImage;
		}

		if ($importedImage) {
			$importedImage->setDescription($imageDescription);
			$importedImage->setIsThumbnail($imageIsThumb);
			if ($imageSort >= 0) {
				$importedImage->setSort($imageSort);
			}
		}

		return $importedImage;
	}
Example #7
0
	public function Action_GetProduct()
	{
		if(empty($this->router->request->details->productId)) {
			$this->BadRequest('The details->productId node is missing');
		}

		$image = new ISC_PRODUCT_IMAGE(); // autoload helper so we can use exceptions defined in the product image class file
		unset($image);

		$productId = (int)$this->router->request->details->productId;
		$productClass = new ISC_PRODUCT($productId);
		$product = $productClass->_product;

		// stuff that comes directly from the database may be incomplete -- use the image library to make sure
		try {
			if (!$product['imageid']) {
				// no image present in data so throw an exception just to force the removal of data below in the catch{} block
				throw new ISC_PRODUCT_IMAGE_EXCEPTION();
			}

			$image = new ISC_PRODUCT_IMAGE();
			$image->populateFromDatabaseRow($product);

			// call the image library to make sure resized images are present and then add full urls so they're useful for remote users
			$product['imagefiletiny'] = $image->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_TINY, true, true, false);
			$product['imagefilethumb'] = $image->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_THUMBNAIL, true, true, false);
			$product['imagefilestd'] = $image->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_STANDARD, true, true, false);
			$product['imagefilezoom'] = $image->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_ZOOM, true, true, false);

			// call the image library to make sure resized images are present and the sizes are correct
			$product['imagefiletinysize'] = implode('x', $image->getResizedFileDimensions(ISC_PRODUCT_IMAGE_SIZE_TINY));
			$product['imagefilethumbsize'] = implode('x', $image->getResizedFileDimensions(ISC_PRODUCT_IMAGE_SIZE_THUMBNAIL));
			$product['imagefilestdsize'] = implode('x', $image->getResizedFileDimensions(ISC_PRODUCT_IMAGE_SIZE_STANDARD));
			$product['imagefilezoomsize'] = implode('x', $image->getResizedFileDimensions(ISC_PRODUCT_IMAGE_SIZE_ZOOM));

		} catch (Exception $exception) {
			// some sort of problem when dealing with product images - remove image info from the response
			unset(
				$product['imagefiletiny'],
				$product['imagefilethumb'],
				$product['imagefilestd'],
				$product['imagefilezoom'],
				$product['imagefiletinysize'],
				$product['imagefilethumbsize'],
				$product['imagefilestdsize'],
				$product['imagefilezoomsize'],
				$product['imagedesc'],
				$product['imagedateadded']
			);
		}

		// direct data feed also includes some fields that are irrelevant or unwanted
		unset(
			$product['imagefile'],	// don't provide a link to the non-water-marked image
			$product['imageprodid'],
			$product['imageprodhash'],
			$product['imageisthumb'],
			$product['imagesort']
		);

		if(empty($product)) {
			return array();
		}

		$product['prodlink'] = ProdLink($product['prodname']);

		// Fetch any images for the product

		$images = new ISC_PRODUCT_IMAGE_ITERATOR(ISC_PRODUCT_IMAGE::generateGetProductImagesFromDatabaseSql((int)$productId));
		foreach ($images as $image) {
			/** @var $image ISC_PRODUCT_IMAGE */
			$imageisthumb = 0;
			if ($image->getIsThumbnail()) {
				$imageisthumb = 1;
			}

			try {
				$product['images']['item'][] = array(
					'imageid' => $image->getProductImageId(),
					'imagefiletiny' => $image->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_TINY, true, true, false),
					'imagefilethumb' => $image->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_THUMBNAIL, true, true, false),
					'imagefilestd' => $image->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_STANDARD, true, true, false),
					'imagefilezoom' => $image->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_ZOOM, true, true, false),
					'imagefiletinysize' => implode('x', $image->getResizedFileDimensions(ISC_PRODUCT_IMAGE_SIZE_TINY)),
					'imagefilethumbsize' => implode('x', $image->getResizedFileDimensions(ISC_PRODUCT_IMAGE_SIZE_THUMBNAIL)),
					'imagefilestdsize' => implode('x', $image->getResizedFileDimensions(ISC_PRODUCT_IMAGE_SIZE_STANDARD)),
					'imagefilezoomsize' => implode('x', $image->getResizedFileDimensions(ISC_PRODUCT_IMAGE_SIZE_ZOOM)),
					'imageisthumb' => $imageisthumb,
					'imagesort' => $image->getSort(),
					'imagedesc' => $image->getDescription(),
					'imagedateadded' => $image->getDateAdded(),
				);
			} catch (Exception $exception) {
				// skip this image and bring down the count of product images obtained from ISC_PRODUCT
				$product['numimages']--;
			}
		}

		// Fetch the categories this product belongs to
		$trailCategories = array();
		$crumbList = array();
		$query = "
			SELECT c.categoryid, c.catparentlist
			FROM [|PREFIX|]categoryassociations ca
			JOIN [|PREFIX|]categories c ON (c.categoryid=ca.categoryid)
			WHERE ca.productId='".(int)$productId."'
		";
		$result = $GLOBALS['ISC_CLASS_DB']->Query($query);
		while ($row = $GLOBALS['ISC_CLASS_DB']->Fetch($result)) {
			if ($row['catparentlist'] == '') {
				$row['catparentlist'] = $row['categoryid'];
			}
			$cats = explode(",", $row['catparentlist']);
			$trailCategories = array_merge($trailCategories, $cats);
			$crumbList[$row['categoryid']] = $row['catparentlist'];
		}

		$trailCategories = implode(",", array_unique($trailCategories));
		$categories = array();
		if ($trailCategories != '') {
			// Now load the names for the parent categories from the database
			$query = "
				SELECT categoryid, catname
				FROM [|PREFIX|]categories
				WHERE categoryid IN (".$trailCategories.")
			";
			$result = $GLOBALS['ISC_CLASS_DB']->Query($query);
			while ($row = $GLOBALS['ISC_CLASS_DB']->Fetch($result)) {
				$categories[$row['categoryid']] = $row['catname'];
			}
		}

		// Now we have all of the information we need to build the trails, lets actually build them
		foreach ($crumbList as $productcatid => $trail) {
			$cats = explode(',', $trail);
			$catName = '';
			$catLink = CatLink($productcatid, $categories[$productcatid]);
			foreach ($cats as $categoryid) {
				if(isset($categories[$categoryid])) {
					if($catName) {
						$catName .= ' &raquo; ';
					}
					$catName .= $categories[$categoryid];
				}
			}
			$product['categories']['item'][] = array(
				'name' => $catName,
				'link' => $catLink,
				'id' => $productcatid
			);
		}

		if($product['prodvariationid'] > 0) {
			if ($product['prodsaleprice'] != 0) {
				$variationBasePrice = $product['prodsaleprice'];
			}
			else {
				$variationBasePrice = $product['prodprice'];
			}

			$vop = $productClass->_prodvariationoptions;
			$vval = $productClass->_prodvariationvalues;
			foreach($productClass->_prodvariationcombinations as $variation) {
				$variationPrice = CurrencyConvertFormatPrice(CalcProductVariationPrice($variationBasePrice, $variation['vcpricediff'], $variation['vcprice'], $product));
				$variationWeight = FormatWeight(CalcProductVariationWeight($product['prodweight'], $variation['vcweightdiff'], $variation['vcweight']), true);

				$variationName = array();
				$options = explode(',', $variation['vcoptionids']);
				foreach($options as $k => $optionId) {
					$label = $vop[$k];
					$variationName[] = $label.': '.$vval[$label][$optionId];
				}
				$variationName = implode(', ', $variationName);
				$variationRow = array(
					'name' => $variationName,
					'id' => $variation['combinationid'],
					'price' => $variationPrice,
					'sku' => $variation['vcsku'],
					'weight' => $variationWeight,
				);

				if($product['prodinvtrack'] == 2) {
					$variationRow['stock'] = $variation['vcstock'];
				}

				if ($variation['vcimage']) {
					try {
						$image = new ISC_PRODUCT_IMAGE;
						$image->setSourceFilePath($variation['vcimage']);

						if($variation['vcimagethumb']) {
							$image->setResizedFilePath(ISC_PRODUCT_IMAGE_SIZE_THUMBNAIL, $variation['vcimagethumb']);
							$variationRow['thumb'] = $image->getResizedFilePath(ISC_PRODUCT_IMAGE_SIZE_THUMBNAIL, true, false);
						}

						if($variation['vcimagestd']) {
							$image->setResizedFilePath(ISC_PRODUCT_IMAGE_SIZE_STANDARD, $variation['vcimagestd']);
							$variationRow['standard'] = $image->getResizedFilePath(ISC_PRODUCT_IMAGE_SIZE_STANDARD, true, false);
						}

						if($variation['vcimagezoom']) {
							$image->setResizedFilePath(ISC_PRODUCT_IMAGE_SIZE_ZOOM, $variation['vcimagezoom']);
							$variationRow['image'] = $image->getResizedFilePath(ISC_PRODUCT_IMAGE_SIZE_ZOOM, true, false);
						}
					} catch (Exception $exception) {
						// nothing
					}
				}

				$product['variations']['item'][] = $variationRow;
			}
		}

		return $product;
	}
Example #8
0
	/**
	* Given a picnik token and a remote file, downloads and processes the remote image, updating and cleaning up local data as required, and sets up template data for displaying to the browser
	*
	* @param array $token
	* @param string $remoteFile
	* @return bool True on success, false on error - on error, a template variable named 'PicnikError' will be assigned as non-false
	*/
	public function receivePicnik($token, $remoteFile)
	{
		$this->template->assign('PicnikError', false);

		$sourceFile = $this->getSourceFileForImage($token['imagetype'], $token['imageid']);
		if (!$sourceFile) {
			$this->template->assign('PicnikError', GetLang('PicnikError_NoSourceFile'));
			return false;
		}

		$errorType = null;

		if (!$this->downloadToFile($remoteFile, $sourceFile, $errorType)) {
			if ($errorType == 1) {
				$this->template->assign('PicnikError', GetLang('PicnikError_NoWrite'));
			} else {
				$this->template->assign('PicnikError', GetLang('PicnikError_NoDownload'));
			}
			return false;
		}

		$imageSize = @getimagesize($sourceFile);
		if (!$imageSize) {
			$this->template->assign('PicnikError', GetLang('PicnikError_Invalid'));
			return false;
		}

		$callbackData = array();

		// the source file has been replaced, now regenerate other files based on it if necessary
		switch ($token['imagetype']) {
			case ISC_PICNIK_TYPE_PRODUCTIMAGE:
				$image = new ISC_PRODUCT_IMAGE((int)$token['imageid']);
				$image->removeResizedFiles();
				$image->saveToDatabase(true);
				$callbackData['thumbnail'] = $image->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_THUMBNAIL, true);
				$callbackData['zoom'] = $image->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_ZOOM, true);
				break;

			case ISC_PICNIK_TYPE_IMAGEMANAGER:
				$callbackData['name'] = basename($sourceFile);
				$callbackData['size'] = Store_Number::niceSize(filesize($sourceFile));
				$callbackData['url'] = GetConfig('ShopPathSSL') . '/' . GetConfig('ImageDirectory') . '/uploaded_images/' . $callbackData['name'];
				$callbackData['dimensions'] = $imageSize[0] . ' x ' . $imageSize[1];
				$callbackData['id'] = md5($callbackData['name']);

				$callbackData['displaywidth'] = $imageSize[0];
				$callbackData['displayheight'] = $imageSize[1];

				if ($callbackData['displaywidth'] > 200) {
					$callbackData['displayheight'] = (200 / $callbackData['displaywidth']) * $callbackData['displayheight'];
					$callbackData['displaywidth']= 200;
				}

				if ($callbackData['displayheight'] > 150) {
					$callbackData['displaywidth'] = (150/$callbackData['displayheight']) * $callbackData['displaywidth'];
					$callbackData['displayheight'] = 150;
				}
				break;
		}

		$this->removeToken($token['picniktokenid']);
		$this->template->assign('PicnikCallbackData', isc_json_encode($callbackData));
		return $callbackData;
	}
Example #9
0
	public function imagelinkFilter($v, $args=null)
	{
		if(!$v['imagefile'])
			return null;

		$image = new ISC_PRODUCT_IMAGE();
		$image->populateFromDatabaseRow($v);

		try {
			$url = $image->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_ZOOM, true, true, false);
			return $url;
		}
		catch(Exception $e)
		{
			return null;
		}
	}
Example #10
0
		public function processProductImages()
		{
			GetLib('class.json');

			/** @var ISC_LOG */
			$log = $GLOBALS['ISC_CLASS_LOG'];

			$query = "
				SELECT
					(SELECT COUNT(*) FROM [|PREFIX|]product_images) AS prodimagecount,
					(SELECT COUNT(DISTINCT vcimage, vcimagezoom, vcimagestd, vcimagethumb) FROM [|PREFIX|]product_variation_combinations WHERE vcimage != '') AS varimagecount
			";

			$result = $this->db->Query($query);
			$countrow = $this->db->Fetch($result);
			$total = $countrow['prodimagecount'] + $countrow['varimagecount'];

			$start = max(0, @(int)$_POST['start']);
			$limit = 10;
			$completed = 0;

			if ($start < $countrow['prodimagecount']) {
				$imageIterator = new ISC_PRODUCT_IMAGE_ITERATOR('select * from `[|PREFIX|]product_images` limit ' . $start . ', ' . $limit);

				foreach($imageIterator as $imageId => $image) {
					try {
						// the first argument to saveToDatabase is $generateImages. If true (is by default), the images will be regenerated
						$image->saveToDatabase();
					} catch (Exception $exception) {
						$log->LogSystemDebug('general', 'Exception while processing product image ' . $imageId, $exception->getMessage());
					}
					++$completed;
				}
			}

			// was there any remaining 'items' to process for this iteration? start on variation images
			$var_limit = $limit - $completed;

			if ($var_limit > 0) {
				$var_start = max(0, $start - $countrow['prodimagecount']);

				$query = '
					SELECT
						vcimage, vcimagezoom, vcimagestd, vcimagethumb
					FROM
						[|PREFIX|]product_variation_combinations
					WHERE
						vcimage != ""
					GROUP BY
						vcimage, vcimagezoom, vcimagestd, vcimagethumb
					ORDER BY
						vcimage
					LIMIT
						' . $var_start . ', ' . $var_limit;

				$result = $this->db->Query($query);
				while ($row = $this->db->Fetch($result)) {
					try {
						$image = new ISC_PRODUCT_IMAGE;
						$image->setSourceFilePath($row['vcimage']);

						if ($row['vcimagezoom']) {
							$image->setResizedFilePath(ISC_PRODUCT_IMAGE_SIZE_ZOOM, $row['vcimagezoom']);
						}

						if ($row['vcimagestd']) {
							$image->setResizedFilePath(ISC_PRODUCT_IMAGE_SIZE_STANDARD, $row['vcimagestd']);
						}

						if ($row['vcimagethumb']) {
							$image->setResizedFilePath(ISC_PRODUCT_IMAGE_SIZE_THUMBNAIL, $row['vcimagethumb']);
						}

						$updatedVariation = array(
							'vcimagezoom' 	=> $image->getResizedFilePath(ISC_PRODUCT_IMAGE_SIZE_ZOOM, true, false),
							'vcimagestd' 	=> $image->getResizedFilePath(ISC_PRODUCT_IMAGE_SIZE_STANDARD, true, false),
							'vcimagethumb' 	=> $image->getResizedFilePath(ISC_PRODUCT_IMAGE_SIZE_THUMBNAIL, true, false),
						);

						$this->db->UpdateQuery('product_variation_combinations', $updatedVariation, "vcimage = '" . $this->db->Quote($row['vcimage']) . "'");
					}
					catch (Exception $exception) {
						$log->LogSystemDebug('general', 'Exception while processing variation image ' . $row['vcimage'], $exception->getMessage());
					}

					++$completed;
				}
			}

			$result = array('completed' => $completed, 'start' => (int)$start, 'total'=> (int)$total);
			ISC_JSON::output('', true, $result);
			exit;
		}
Example #11
0
	/**
	* Imports a temporary image file on the server to the given product. Performs validation, moves the file to it's final location and filename and returns an instance of ISC_PRODUCT_IMAGE.
	*
	* It is up to the method calling this to delete any temporary file if something goes wrong.
	*
	* @param string $temporaryPath Absolute path to the temporary image file stored on the server to be imported -- this file will need to be read so if it is an uploaded file and is in the tmp folder you should move it to the cache directory first since open_basedir restrictions may prevent the file being read from the tmp folder
	* @param string $originalFilename Original intended filename (such as the name provided by the browser when uploading a file) which may differ from the temporary file at $temporaryPath -- this should not include any directory components
	* @param int|string|bool $productId The id (or hash when $hash is true) of the product to import to, or supply as false to not save any info to the database but still return an instance of ISC_PRODUCT_IMAGE
	* @param bool $hash If true, $productId will be treated as a hash of a product in the process of being added
	* @param bool $moveTemporaryFile If true, the provided temporary file will be moved to it's new location, otherwise it will be copied
	* @param bool $generateImages If true, when importing, will attempt to generate thumbnail images -- may not be desirable if importing many images at once
	* @throws ISC_PRODUCT_IMAGE_IMPORT_INVALIDIMAGEFILE_EXCEPTION If the file is not a valid image
	* @throws ISC_PRODUCT_IMAGE_IMPORT_NOPHPSUPPORT_EXCEPTION If the image could not be processed by any installed php extensions
	* @throws ISC_PRODUCT_IMAGE_IMPORT_EMPTYIMAGE_EXCEPTION If the image is 'empty' - has 0 width or 0 height
	* @throws ISC_PRODUCT_IMAGE_IMPORT_CANTCREATEDIR_EXCEPTION If an error prevented the image's destination directory from being created (usually lack of write permissions on parent directory)
	* @throws ISC_PRODUCT_IMAGE_IMPORT_CANTMOVEFILE_EXCEPTION If an error prevented the image from being moved to the destination directory (usually lack of write permissions on parent directory)
	* @return ISC_PRODUCT_IMAGE If everything went OK
	*/
	public static function importImage($temporaryPath, $originalFilename, $productId, $hash = false, $moveTemporaryFile = true, $generateImages = true)
	{
		if (!file_exists($temporaryPath)) {
			throw new ISC_PRODUCT_IMAGE_SOURCEFILEDOESNTEXIST_EXCEPTION($temporaryPath);
		}

		try {
			$library = ISC_IMAGE_LIBRARY_FACTORY::getImageLibraryInstance($temporaryPath);
		} catch (ISC_IMAGE_LIBRARY_FACTORY_INVALIDIMAGEFILE_EXCEPTION $ex) {
			throw new ISC_PRODUCT_IMAGE_IMPORT_INVALIDIMAGEFILE_EXCEPTION();
		} catch (ISC_IMAGE_LIBRARY_FACTORY_NOPHPSUPPORT_EXCEPTION $ex) {
			throw new ISC_PRODUCT_IMAGE_IMPORT_NOPHPSUPPORT_EXCEPTION();
		}

		if ($library->getWidth() < 1 || $library->getHeight() < 1) {
			throw new ISC_PRODUCT_IMAGE_IMPORT_EMPTYIMAGE_EXCEPTION();
		}

		$finalName = $originalFilename;


		$finalName = basename($finalName); // remove any path components from the filename
		$finalName = self::sanitiseFilename($finalName);

		if (!self::isValidFilename($finalName, false)) {
			throw new ISC_PRODUCT_IMAGE_IMPORT_INVALIDFILENAME_EXCEPTION($finalName);
		}

		// correct the uploaded extension
		$correctExtension = $library->getImageTypeExtension(false);
		if (strtolower(pathinfo($finalName, PATHINFO_EXTENSION)) != $correctExtension) {
			// remove existing extension and trailing . if any
			$finalName = preg_replace('#\.[^\.]*$#', '', $finalName);
			// add correct extension
			$finalName .= '.' . $correctExtension;
		}

		// generate a path for storing in the product_images directory
		$finalRelativePath = self::generateSourceImageRelativeFilePath($finalName);

		$image = new ISC_PRODUCT_IMAGE();
		$image->setSourceFilePath($finalRelativePath);

		$finalAbsolutePath = $image->getAbsoluteSourceFilePath();
		$finalDirectory = dirname($finalAbsolutePath);

		if (!file_exists($finalDirectory)) {
			if (!isc_mkdir($finalDirectory, ISC_WRITEABLE_DIR_PERM, true)) {
				throw new ISC_PRODUCT_IMAGE_IMPORT_CANTCREATEDIR_EXCEPTION($finalDirectory);
			}
		}

		if ($moveTemporaryFile) {
			if (!@rename($temporaryPath, $finalAbsolutePath)) {
				throw new ISC_PRODUCT_IMAGE_IMPORT_CANTMOVEFILE_EXCEPTION($finalAbsolutePath);
			}
		} else {
			if (!@copy($temporaryPath, $finalAbsolutePath)) {
				throw new ISC_PRODUCT_IMAGE_IMPORT_CANTMOVEFILE_EXCEPTION($finalAbsolutePath);
			}
		}

		// check to see if the uploaded image exceeds our internal maximum image size: ISC_PRODUCT_IMAGE_MAXLONGEDGE
		if ($library->getWidth() > ISC_PRODUCT_IMAGE_MAXLONGEDGE || $library->getHeight() > ISC_PRODUCT_IMAGE_MAXLONGEDGE) {
			// if it is, resize it and overwrite the uploaded source image because we only want to store images to a maximum size of ISC_PRODUCT_IMAGE_MAXLONGEDGE x ISC_PRODUCT_IMAGE_MAXLONGEDGE
			$library->setFilePath($finalAbsolutePath);
			$library->loadImageFileToScratch();
			$library->resampleScratchToMaximumDimensions(ISC_PRODUCT_IMAGE_MAXLONGEDGE, ISC_PRODUCT_IMAGE_MAXLONGEDGE);
			$library->saveScratchToFile($finalAbsolutePath, self::getWriteOptionsForImageType($library->getImageType()));
		}

		if ($productId === false) {
			// do not assign product hash, id or save to database if $productId is false
			if ($generateImages) {
				// manually generate images since, normally, a call to saveToDatabase would do it
				$image->getResizedFileDimensions(ISC_PRODUCT_IMAGE_SIZE_TINY, true, false);
				$image->getResizedFileDimensions(ISC_PRODUCT_IMAGE_SIZE_THUMBNAIL, true, false);
				$image->getResizedFileDimensions(ISC_PRODUCT_IMAGE_SIZE_STANDARD, true, false);
				$image->getResizedFileDimensions(ISC_PRODUCT_IMAGE_SIZE_ZOOM, true, false);
			}

			return $image;
		}

		if ($hash) {
			$image->setProductHash($productId);
		} else {
			$image->setProductId($productId);
		}

		// ISC_PRODUCT_IMAGE_SOURCEFILEDOESNTEXIST_EXCEPTION should never really happen at this point with all the checks above so, if it does, let the exception go unhandled to bubble up to a fatal error
		$image->saveToDatabase($generateImages);

		return $image;
	}
Example #12
0
	/**
	* Takes a product id and product image id and modifies the sorting values of all affected product images to "move this image after another image"
	*
	* @param ISC_ADMIN_REMOTE $remote
	*/
	public function remoteMoveImageAfterOtherImage(ISC_ADMIN_REMOTE $remote)
	{
		// this method is used instead of simply receiving a full serialize of the new product order, it allows us to update more efficiently by knowing which image was moved and only updating the affected sort orders

		$response = array();

		$productId = false;
		$productHash = false;

		if (isset($_POST['product'])) {
			$productId = (int)@$_POST['product'];
			if (!isId($productId) || !ProductExists($productId)) {
				$response[] = $remote->MakeXMLTag('error', GetLang('ProductDoesntExist'), true);
			} else if (!$GLOBALS["ISC_CLASS_ADMIN_AUTH"]->HasPermission(AUTH_Edit_Products)) {
				$response[] = $remote->MakeXMLTag('error', GetLang('Unauthorized'), true);
			}
		} else if (isset($_POST['hash']) && $_POST['hash']) {
			$productHash = $_POST['hash'];
			if (!$GLOBALS["ISC_CLASS_ADMIN_AUTH"]->HasPermission(AUTH_Create_Product)) {
				$response[] = $remote->MakeXMLTag('error', GetLang('Unauthorized'), true);
			}
		} else {
			$response[] = $remote->MakeXMLTag('error', GetLang('ProductDoesntExist'), true);
		}

		if (!empty($response)) {
			$remote->SendXMLHeader();
			$remote->SendXMLResponse($response);
			die();
		}

		$moveId = (int)$_POST['move'];

		try {
			$moveImage = new ISC_PRODUCT_IMAGE($moveId);
		} catch (ISC_PRODUCT_IMAGE_INVALIDID_EXCEPTION $e) {
			$response[] = $remote->MakeXMLTag('error', sprintf(GetLang('ProductImageInvalidId'), $moveId), true);
		} catch (ISC_PRODUCT_IMAGE_RECORDNOTFOUND_EXCEPTION $e) {
			$response[] = $remote->MakeXMLTag('error', sprintf(GetLang('ProductImageNotFound'), $moveId), true);
		} catch (Exception $e) {
			$response[] = $remote->MakeXMLTag('error', GetLang('ProductImageMoveDatabaseError'), true);
		}

		if (!empty($response)) {
			$remote->SendXMLHeader();
			$remote->SendXMLResponse($response);
			die();
		}

		$moveSort = $moveImage->getSort();

		if ($productId && $moveImage->getProductId() !== $productId || $productHash && $moveImage->getProductHash() !== $productHash) {
			// provided image id does not belong to provided product id
			$response[] = $remote->MakeXMLTag('error', sprintf(GetLang('ProductImageMismatchError'), $moveId, $productId), true);
			$remote->SendXMLHeader();
			$remote->SendXMLResponse($response);
			die();
		}

		if (isset($_POST['after'])) {
			$afterId = (int)$_POST['after'];

			try {
				$afterImage = new ISC_PRODUCT_IMAGE($afterId);
			} catch (ISC_PRODUCT_IMAGE_INVALIDID_EXCEPTION $e) {
				$response[] = $remote->MakeXMLTag('error', sprintf(GetLang('ProductImageInvalidId'), $afterId), true);
				$remote->SendXMLHeader();
				$remote->SendXMLResponse($response);
				die();
			} catch (ISC_PRODUCT_IMAGE_RECORDNOTFOUND_EXCEPTION $e) {
				$response[] = $remote->MakeXMLTag('error', sprintf(GetLang('ProductImageNotFound'), $afterId), true);
				$remote->SendXMLHeader();
				$remote->SendXMLResponse($response);
				die();
			} catch (Exception $e) {
				$response[] = $remote->MakeXMLTag('error', GetLang('ProductImageMoveDatabaseError'), true);
				$remote->SendXMLHeader();
				$remote->SendXMLResponse($response);
				die();
			}

			if ($productId && $afterImage->getProductId() !== $productId || $productHash && $afterImage->getProductHash() !== $productHash) {
				// provided image id does not belong to provided product id
				$response[] = $remote->MakeXMLTag('error', sprintf(GetLang('ProductImageMismatchError'), $afterId, $productId), true);
				$remote->SendXMLHeader();
				$remote->SendXMLResponse($response);
				die();
			}

			$afterSort = $afterImage->getSort();
		} else {
			$after = false;
			$afterSort = -1;
		}

		if ($moveImage->getProductHash()) {
			if (!$GLOBALS["ISC_CLASS_ADMIN_AUTH"]->HasPermission(AUTH_Create_Product)) {
				$response[] = GetLang('Unauthorized');
				$remote->SendXMLHeader();
				$remote->SendXMLResponse($response);
				die();
			}
		} else {
			if (!$GLOBALS["ISC_CLASS_ADMIN_AUTH"]->HasPermission(AUTH_Edit_Products)) {
				$response[] = GetLang('Unauthorized');
				$remote->SendXMLHeader();
				$remote->SendXMLResponse($response);
				die();
			}
		}

		// create an sql query to shift all sorting values between the two anchor points
		if ($moveSort > $afterSort) {
			$sql = "UPDATE `[|PREFIX|]product_images` SET imagesort = imagesort + 1 WHERE imageprodid = " . $moveImage->getProductId() . " AND imagesort > " . $afterSort . " AND imagesort < " . $moveSort;
			$newSort = $afterSort + 1;
		} else {
			$sql = "UPDATE `[|PREFIX|]product_images` SET imagesort = imagesort - 1 WHERE imageprodid = " . $moveImage->getProductId() . " AND imagesort > " . $moveSort . " AND imagesort <= " . $afterSort;
			$newSort = $afterSort;
		}

		$db = $GLOBALS['ISC_CLASS_DB'];

		$db->Query("SET autocommit = 0");
		$db->Query("LOCK TABLES `[|PREFIX|]product_images` WRITE");

		$result = $db->Query($sql);

		if ($result) {
			$moveImage->setSort($newSort);

			try {
				$moveImage->saveToDatabase(false);
				$db->Query("COMMIT");
				$response[] = $remote->MakeXMLTag('success', GetLang('ProductImagesSortOrderChanged'), true);
			} catch (Exception $e) {
				$db->Query("ROLLBACK");
				$response[] = $remote->MakeXMLTag('success', GetLang('ProductImageMoveDatabaseError'), true);
			}
			$db->Query("UNLOCK TABLES");

		} else {
			$db->Query("ROLLBACK");
			$db->Query("UNLOCK TABLES");
			$response[] = $remote->MakeXMLTag('success', GetLang('ProductImageMoveDatabaseError'), true);
		}

		$remote->SendXMLHeader();
		$remote->SendXMLResponse($response);
		die();
	}
Example #13
0
	protected function _ImportRecord($record)
	{
		// the field we have chosen to identify the product
		$prodIdentField = $this->ImportSession['IdentField'];
		$identFieldName = $this->_ImportFields[$prodIdentField];

		// chosen ident field is empty, can't continue
		if (empty($prodIdentField)) {
			$this->addImportResult('Failures', GetLang('NoIdentField', array('identField' => $identFieldName)));
			return;
		}

		// get the product for this row
		$query = "SELECT * FROM [|PREFIX|]products WHERE " . $prodIdentField . " = '" . $GLOBALS['ISC_CLASS_DB']->Quote(trim($record[$prodIdentField])) . "'";
		$result = $GLOBALS['ISC_CLASS_DB']->Query($query);
		if (($prod = $GLOBALS['ISC_CLASS_DB']->Fetch($result)) === false) {
			// no prod found? failrow
			$this->addImportResult('Failures', GetLang('AssociatedProductNotFound', array('identField' => $identFieldName, 'identValue' => $record[$prodIdentField])));
			return;
		}
		$productID = $prod['productid'];
		$variationID = $prod['prodvariationid'];

		//---- the fields we'll be updating the product with ----

		// variation code
		if (isset($record['prodvarsku'])) {
			$prodCode = $record['prodvarsku'];

			if (!empty($prodCode) || (empty($prodCode) && $this->ImportSession['DefaultForEmpty'])) {
				$updateFields['vcsku'] = $prodCode;
			}
		}
		elseif (isset($record['prodcode'])) {
			$prodCode = $record['prodcode'];

			if (!empty($prodCode) || (empty($prodCode) && $this->ImportSession['DefaultForEmpty'])) {
				$updateFields['vcsku'] = $prodCode;
			}
		}

		// variation price
		if (isset($record['prodvarprice'])) {
			$varPrice = $record['prodvarprice'];

			if (empty($varPrice) && $this->ImportSession['DefaultForEmpty']) {
				$updateFields['vcprice'] = 0;
				$updateFields['vcpricediff'] = '';
			}
			else {
				// prefixed by a + then it's a price addition
				if (isc_substr($varPrice, 0, 1) == "+") {
					$priceDiff = "add";
				} // price subtraction
				elseif ($varPrice < 0) {
					$priceDiff = "subtract";
				} // fixed price
				else {
					$priceDiff = "fixed";
				}

				$varPrice = abs((float)DefaultPriceFormat($varPrice));
				$updateFields['vcprice'] = $varPrice;
				$updateFields['vcpricediff'] = $priceDiff;
			}
		}

		// variation weight
		if (isset($record['prodvarweight'])) {
			$varWeight = $record['prodvarweight'];

			if (empty($varWeight) && $this->ImportSession['DefaultForEmpty']) {
				$updateFields['vcweight'] = 0;
				$updateFields['vcweightdiff'] = '';
			}
			elseif (!empty($record['prodvarweight'])) {
				// prefixed by a + then it's a weight addition
				if (isc_substr($varWeight, 0, 1) == "+") {
					$weightDiff = "add";
				} // weight subtraction
				elseif ($varWeight < 0) {
					$weightDiff = "subtract";
				} // fixed weight
				else {
					$weightDiff = "fixed";
				}

				$updateFields['vcweight'] = abs((float)$varWeight);
				$updateFields['vcweightdiff'] = $weightDiff;
			}
		}

		// stock level
		if (isset($record['prodvarstock'])) {
			if (empty($record['prodvarstock']) && $this->ImportSession['DefaultForEmpty']) {
				$updateFields['vcstock'] = 0;
			}
			else {
				$updateFields['vcstock'] = $record['prodvarstock'];
			}
		}

		// low stock level
		if (isset($record['prodvarlowstock'])) {
			if (empty($record['prodvarlowstock']) && $this->ImportSession['DefaultForEmpty']) {
				$updateFields['vclowstock'] = 0;
			}
			else {
				$updateFields['vclowstock'] = $record['prodvarlowstock'];
			}
		}

		// enable the option?
		if (isset($record['prodvarenabled'])) {
			if (empty($record['prodvarenabled']) && $this->ImportSession['DefaultForEmpty']) {
				$updateFields['vcenabled'] = 1;
			}
			else {
				$updateFields['vcenabled'] = $this->StringToYesNoInt($record['prodvarenabled']);
			}
		}
		else {
			// enable by default
			$updateFields['vcenabled'] = 1;
		}

		// variation image
		if(!empty($record['prodvarimage'])) {
			// code exists in the new product image management classes to handle these imports
			$imageFile = $record['prodvarimage'];
			$imageAdmin = new ISC_ADMIN_PRODUCT_IMAGE;
			$variationImage = false;

			// check if this image file (either remote or local) has already been processed on a previous variation, if
			// so, simply re-use those values instead of re-downloading / re-processing
			if (isset($this->ImportSession['ImportedImages'][$imageFile])) {
				$importedImage = $this->ImportSession['ImportedImages'][$imageFile];
				if (is_array($importedImage)) {
					$updateFields = array_merge($updateFields, $importedImage);
				}
			} else {
				$this->ImportSession['ImportedImages'][$imageFile] = false;

				if (preg_match('#^(?P<scheme>[a-zA-Z0-9\.]+)://#i', $imageFile, $matches)) {
					// the filename is an external URL, import it against the calcualted product hash
					$imageAdmin->importImagesFromUrls(false, array($imageFile), $importImages, $importImageErrors, false);

					if (!empty($importImages)) {
						$variationImage = $importImages[0];
					}

					if (!empty($importImageErrors)) {
						// as this import works on one file only and importImagesFromWebUrls creates one error per file, can simply tack on the new error
						$importImageError = $importImageErrors[0];
						if (is_array($importImageError)) {
							$this->addImportResult('Warnings', $importImageError[1]);
						} else {
							$this->addImportResult('Warnings', $importImageError);
						}
					}

				} else {
					// the filename is a local file
					$importImageFilePath = ISC_BASE_PATH . "/" . GetConfig('ImageDirectory') . "/import/" . $imageFile;

					try {
						$variationImage = ISC_PRODUCT_IMAGE::importImage($importImageFilePath, basename($importImageFilePath), false, false, false, false);
					} catch (ISC_PRODUCT_IMAGE_SOURCEFILEDOESNTEXIST_EXCEPTION $exception) {
						// exception message may contain server path; present filtered message and log the original
						$this->addImportResult('Warnings', GetLang('ProductImageFileDoesNotExist'));
						trigger_error($exception->getMessage(), E_WARNING);
					} catch (ISC_PRODUCT_IMAGE_IMPORT_CANTCREATEDIR_EXCEPTION $exception) {
						// exception message may contain server path; present filtered message and log the original
						$this->addImportResult('Warnings', GetLang('ImportProductImageFilePermissionIssue'));
						trigger_error($exception->getMessage(), E_WARNING);
					} catch (ISC_PRODUCT_IMAGE_IMPORT_CANTMOVEFILE_EXCEPTION $exception) {
						// exception message may contain server path; present filtered message and log the original
						$this->addImportResult('Warnings', GetLang('ImportProductImageFilePermissionIssue'));
						trigger_error($exception->getMessage(), E_WARNING);
					} catch (Exception $exception) {
						// other exceptions should be ok to present
						$this->addImportResult('Warnings', $exception->getMessage());
					}
				}

				if ($variationImage !== false) {
					try {
						$importedImage = array(
							'vcimage' => $variationImage->getSourceFilePath(),
							'vcimagezoom' => $variationImage->getResizedFilePath(ISC_PRODUCT_IMAGE_SIZE_ZOOM, true, false),
							'vcimagestd' => $variationImage->getResizedFilePath(ISC_PRODUCT_IMAGE_SIZE_STANDARD, true, false),
							'vcimagethumb' => $variationImage->getResizedFilePath(ISC_PRODUCT_IMAGE_SIZE_THUMBNAIL, true, false),
						);
						$updateFields = array_merge($updateFields, $importedImage);
						$this->ImportSession['ImportedImages'][$imageFile] = $importedImage;
					} catch (ISC_PRODUCT_IMAGE_SOURCEFILEDOESNTEXIST_EXCEPTION $exception) {
						// exception message may contain server path; present filtered message and log the original
						$this->addImportResult('Warnings', GetLang('ProductImageFileDoesNotExist'));
						trigger_error($exception->getMessage(), E_WARNING);
					} catch (ISC_PRODUCT_IMAGE_IMPORT_CANTCREATEDIR_EXCEPTION $exception) {
						// exception message may contain server path; present filtered message and log the original
						$this->addImportResult('Warnings', GetLang('ImportProductImageFilePermissionIssue'));
						trigger_error($exception->getMessage(), E_WARNING);
					} catch (ISC_PRODUCT_IMAGE_IMPORT_CANTMOVEFILE_EXCEPTION $exception) {
						// exception message may contain server path; present filtered message and log the original
						$this->addImportResult('Warnings', GetLang('ImportProductImageFilePermissionIssue'));
						trigger_error($exception->getMessage(), E_WARNING);
					} catch (Exception $exception) {
						// other exceptions should be ok to present
						$this->addImportResult('Warnings', $exception->getMessage());
					}
				}
			}
		}


		// get the index of the last matched field...we assume that all the remaining fields are variations
		$lastindex = 0;
		foreach ($this->ImportSession['FieldList'] as $field => $index) {
			if ($index > $lastindex) {
				$lastindex = $index;
			}
		}

		$variationStartIndex = $lastindex + 1;

		// get the variation fields
		$variationFields = array_slice($record['original_record'], $variationStartIndex);

		// split the variation fields into key => value pairs
		$variationData = array();
		foreach ($variationFields as $field) {
			$varField = explode(":", $field, 2);
			// ensure we have a key and value...otherwise bad field
			if (count($varField) != 2) {
				$this->addImportResult('Failures', GetLang('CantExtractData', array('dataField' => $field)));
				return;
			}

			$varName = trim($varField[0]);
			$varValue = trim($varField[1]);
			$variationData[$varName] = $varValue;
		}

		// ensure we actually have variation data
		if (empty($variationData)) {
			// generate a failure
			$this->addImportResult('Failures', GetLang('NoVariationData', array('rowNum' => $this->ImportSession['DoneCount'] + 1)));
			return;
		}

		// are we choosing to update an existing variation combination or replacing with a new variation?
		// make sure this isn't a variation we've created this session
		if ($this->ImportSession['UpdateExisting'] && $variationID > 0 && !isset($this->ImportSession['NewVariations'][$productID])){
			// find the variation options so we can find the combination
			$query = "
			SELECT
				voptionid,
				voname,
				vovalue
			FROM
				[|PREFIX|]product_variation_options
			WHERE
				vovariationid = " . $variationID . " AND (";

			$where = "";
			foreach ($variationData as $varName => $varValue) {
				if ($where) {
					$where .= " OR ";
				}
				$where .= "
					(
						voname = '" . $GLOBALS['ISC_CLASS_DB']->Quote($varName) . "' AND
						vovalue = '" . $GLOBALS['ISC_CLASS_DB']->Quote($varValue) . "'
					)
				";
			}

			$query .= $where . ") ORDER BY vooptionsort, vovaluesort";

			$result = $GLOBALS['ISC_CLASS_DB']->Query($query);
			$optionList = array();
			$notFoundOptions = $variationData;
			// get the option id's
			if ($GLOBALS['ISC_CLASS_DB']->CountResult($result)) {
				while ($optionRow = $GLOBALS['ISC_CLASS_DB']->Fetch($result)) {
					$optionList[] = $optionRow['voptionid'];
					unset($notFoundOptions[$optionRow['voname']]);
				}
			}

			$updatedName = false;

			// create any remaining options
			if (!empty($notFoundOptions)) {
				foreach ($notFoundOptions as $varName => $varValue) {
					// find whether it's the option name or value that doesn't exist
					$query = "
						SELECT
							COUNT(*) AS valuecount,
							vooptionsort,
							voname
						FROM
							[|PREFIX|]product_variation_options
						WHERE
							vovariationid = " . $variationID . " AND
							voname = '" . $GLOBALS['ISC_CLASS_DB']->Quote($varName) . "'
						GROUP BY
							voname
					";
					$result = $GLOBALS['ISC_CLASS_DB']->Query($query);
					// name exists, just create a new value
					if ($option = $GLOBALS['ISC_CLASS_DB']->Fetch($result)) {
						$newOption = array(
							'vovariationid' => $variationID,
							'voname'		=> $option['voname'],
							'vovalue'		=> $varValue,
							'vooptionsort'	=> $option['vooptionsort'],
							'vovaluesort'	=> $option['valuecount'] + 1
						);

						$optionID = $GLOBALS['ISC_CLASS_DB']->InsertQuery('product_variation_options', $newOption);
						array_splice($optionList, $option['vooptionsort'] - 1, 0, $optionID);

						// we have a new value, we have to create new combinations for each of the rows using the existing data

						// get existing combinations but exclude the option name that we're on
						if ($this->ImportSession['CreateAllCombos']) {
							$combinations = GetVariationCombinations($productID, $varName);
							foreach ($combinations as $combination) {
								$newCombination = $combination;
								// insert the option at correct position
								array_splice($newCombination, $option['vooptionsort'] - 1, 0, $optionID);
								$newOptionList = implode(',', $newCombination);

								// create combination
								$newCombo = array(
									'vcproductid'	=> $productID,
									'vcvariationid'	=> $variationID,
									'vcoptionids'	=> $newOptionList,
									'vcenabled'		=> 1
								);
								$GLOBALS['ISC_CLASS_DB']->InsertQuery('product_variation_combinations', $newCombo);
							}
						}
					}
					else {
						// name not found, create it with the option

						// get total option names
						$query = "SELECT COUNT(DISTINCT voname) AS optioncount FROM [|PREFIX|]product_variation_options WHERE vovariationid = " . $variationID;
						$result = $GLOBALS['ISC_CLASS_DB']->Query($query);
						$optioncount = $GLOBALS['ISC_CLASS_DB']->FetchOne($result, 'optioncount');

						$newOption = array(
							'vovariationid' => $variationID,
							'voname'		=> $varName,
							'vovalue'		=> $varValue,
							'vooptionsort'	=> $optioncount + 1,
							'vovaluesort'	=> 1
						);

						$optionID = $GLOBALS['ISC_CLASS_DB']->InsertQuery('product_variation_options', $newOption);
						array_splice($optionList, $optioncount, 0, $optionID);

						// we have a new option name, so append the new option id to existing combinations
						$query = "
							UPDATE
								[|PREFIX|]product_variation_combinations
							SET
								vcoptionids = CONCAT(vcoptionids, '," . $optionID . "')
							WHERE
								vcvariationid = " . $variationID;

						$GLOBALS['ISC_CLASS_DB']->Query($query);

						// update the variation option count
						$query = "UPDATE [|PREFIX|]product_variations SET vnumoptions = vnumoptions + 1 WHERE variationid = " . $variationID;
						$GLOBALS['ISC_CLASS_DB']->Query($query);
					}
				}
			}

			$optionString = implode(",", $optionList);

			// attempt to find existing combination again using list of options
			$query = "
				SELECT
					combinationid
				FROM
					[|PREFIX|]product_variation_combinations
				WHERE
					vcproductid = " . $productID . " AND
					vcvariationid = " . $variationID . " AND
					vcoptionids = '" . $optionString . "'
			";

			$result = $GLOBALS['ISC_CLASS_DB']->Query($query);

			// update the combination
			if ($comboID = $GLOBALS['ISC_CLASS_DB']->FetchOne($result, 'combinationid')) {
				$GLOBALS['ISC_CLASS_DB']->UpdateQuery('product_variation_combinations', $updateFields, 'combinationid = ' . $comboID);

				$this->addImportResult('Updates', $prod['prodname']);
			}
			else {
				// couldn't update an existing combo, create a new one

				$newCombo = array(
					'vcproductid'	=> $productID,
					'vcvariationid'	=> $variationID,
					'vcoptionids'	=> $optionString
				);

				$newCombo = $newCombo + $updateFields;

				$GLOBALS['ISC_CLASS_DB']->InsertQuery('product_variation_combinations', $newCombo);

				$this->ImportSession['Results']['SuccessCount']++;
			}
		}
		else {
			// create a new variation for this product

			// have we already created a variation for this product in this import session?
			if (isset($this->ImportSession['NewVariations'][$productID])) {
				// we only need to create our new options and the combinations

				// find any options previously created
				$thisVar = $this->ImportSession['NewVariations'][$productID];
				$thisOptions = array();
				$thisOptionsL = array();
				foreach ($variationData as $varName => $varValue) {
					if (isset($thisVar[isc_strtolower($varName)][isc_strtolower($varValue)])) {
						$thisOptions[$varName] = $thisVar[isc_strtolower($varName)][isc_strtolower($varValue)];
						$thisOptionsL[isc_strtolower($varName)] = $thisVar[isc_strtolower($varName)][isc_strtolower($varValue)];
					}
				}

				// create any remaining uncreated options
				$remainingOptions = array_diff_key($variationData, $thisOptions);
				if (!empty($remainingOptions)) {
					foreach ($remainingOptions as $varName => $varValue) {
						$lvarName = isc_strtolower($varName);
						// get the option and value sort numbers

						// does this option name exist, but just not the value?
						if (isset($thisVar[$lvarName])) {
							$keyIndex = array_search($lvarName, array_keys($thisVar));

							$optionSort = $keyIndex + 1;
							$valueSort = count($thisVar[$lvarName]) + 1;
						}
						else {
							$valueSort = 1;
							$optionSort = count($thisVar) + 1;
						}

						$insertOption = array(
							'vovariationid'	=> $variationID,
							'voname' 		=> $varName,
							'vovalue'		=> $varValue,
							'vooptionsort'	=> $optionSort,
							'vovaluesort'	=> $valueSort
						);

						$optionID = $GLOBALS['ISC_CLASS_DB']->InsertQuery('product_variation_options', $insertOption);
						// add this new option to the list
						$thisVar[$lvarName][isc_strtolower($varValue)] = $optionID;
						$thisOptionsL[$lvarName] = $optionID;

						// is it a new option name?
						if (!$thisVar[isc_strtolower($varName)]) {
							// we have a new option name, so append the new option id to existing combinations
							$query = "
								UPDATE
									[|PREFIX|]product_variation_combinations
								SET
									vcoptionids = CONCAT(vcoptionids, '," . $optionID . "')
								WHERE
									vcvariationid = " . $variationID;

							$GLOBALS['ISC_CLASS_DB']->Query($query);
						}
					}
				}

				// store options back in session
				$this->ImportSession['NewVariations'][$productID] = $thisVar;

				// get the option ids for this combination. they must be in the order that the option names were created.
				$comboRows = array(array());
				foreach ($thisVar as $varName => $varData) {
					// is there an option that may have already been created but is missing for this record?
					if (isset($thisOptionsL[$varName])) {
						foreach ($comboRows as &$combo) {
							$combo[] = $thisOptionsL[$varName];
						}
					}
					else {
						$newRows = array();
						// missing option, iterate through all values for that option and create combinations
						foreach ($comboRows as $combo) {
							foreach ($varData as $varValue => $optionID) {
								$newRow = $combo;
								$newRow[] = $optionID;
								$newRows[] = $newRow;
							}
						}
						$comboRows = $newRows;
					}
				}

				// insert all our combinations
				foreach ($comboRows as $thisCombo) {
					$optionString = implode(",", $thisCombo);

					// now we can finally create the combination
					$newCombo = array(
						'vcproductid'	=> $prod['productid'],
						'vcvariationid'	=> $variationID,
						'vcoptionids'	=> $optionString
					);

					$newCombo = $newCombo + $updateFields;

					$GLOBALS['ISC_CLASS_DB']->InsertQuery('product_variation_combinations', $newCombo);
				}

				$this->ImportSession['Results']['SuccessCount']++;
			}
			else {
				// do we have an existing combinations for this product? we should delete any combinations for that first
				if ($variationID) {
					$GLOBALS['ISC_CLASS_DB']->DeleteQuery('product_variation_combinations', 'WHERE vcproductid = ' . $productID);
				}

				// name of our new variation .. check if it already exists
				$variationName = $prod['prodname'] . " Variations " . date('dmy');
				$query = "SELECT variationid FROM [|PREFIX|]product_variations WHERE vname = '" . $GLOBALS['ISC_CLASS_DB']->Quote($variationName) . "'";
				$result = $GLOBALS['ISC_CLASS_DB']->Query($query);
				if ($varRow = $GLOBALS['ISC_CLASS_DB']->Fetch($result)) {
					// delete the old variation
					$GLOBALS['ISC_CLASS_DB']->DeleteQuery('product_variations', 'WHERE variationid = ' . $varRow['variationid']);
					$GLOBALS['ISC_CLASS_DB']->DeleteQuery('product_variation_options', 'WHERE vovariationid = ' . $varRow['variationid']);
					$GLOBALS['ISC_CLASS_DB']->DeleteQuery('product_variation_combinations', 'WHERE vcvariationid = ' . $varRow['variationid']);

					// update products that use this variation
					$updateProd = array(
						'prodvariationid' => 0
					);
					$GLOBALS['ISC_CLASS_DB']->UpdateQuery('products', $updateProd, 'prodvariationid = ' . $varRow['variationid']);
				}


				// create our new variation first
				$newVariation = array(
					'vname'		=> $variationName,
					'vvendorid' => $prod['prodvendorid']
				);

				$variationID = $GLOBALS['ISC_CLASS_DB']->InsertQuery('product_variations', $newVariation);

				$this->ImportSession['NewVariationIDs'][$productID] = $variationID;

				// update our product with the variation ID
				$updateProd = array(
					'prodvariationid' => $variationID
				);
				$GLOBALS['ISC_CLASS_DB']->UpdateQuery('products', $updateProd, 'productid = ' . $productID);

				$thisVar = array();
				$options = array();

				// now to create the options
				$optionCount = 0;
				foreach ($variationData as $varName => $varValue) {
					$newOption = array(
						'vovariationid'	=> $variationID,
						'voname'		=> $varName,
						'vovalue'		=> $varValue,
						'vooptionsort'	=> ++$optionCount,
						'vovaluesort'	=> 1
					);

					$optionID = $GLOBALS['ISC_CLASS_DB']->InsertQuery('product_variation_options', $newOption);

					$thisVar[isc_strtolower($varName)][isc_strtolower($varValue)] = $optionID;
					$options[] = $optionID;
				}

				$this->ImportSession['NewVariations'][$productID] = $thisVar;

				// create the combination
				$optionString = implode(",", $options);

				$newCombo = array(
					'vcproductid'	=> $productID,
					'vcvariationid'	=> $variationID,
					'vcoptionids'	=> $optionString
				);

				$newCombo = $newCombo + $updateFields;

				$GLOBALS['ISC_CLASS_DB']->InsertQuery('product_variation_combinations', $newCombo);

				$this->ImportSession['Results']['SuccessCount']++;
			}
		}

		// a stock or low stock is supplied, enable inventory tracking for the product
		if (!empty($record['prodvarstock']) || !empty($record['prodvarlowstock'])) {
			$updateProd = array(
				'prodinvtrack' => 2
			);

			$GLOBALS['ISC_CLASS_DB']->UpdateQuery('products', $updateProd, 'productid = ' . $productID);
		}

		/**
		 * This is a bit hackish but we need to update the product last modified time WITHOUT using the
		 * product entity class (shock horror). This is because we have nothing else to update it with
		 */
		$savedata = array(
			"prodlastmodified" => time()
		);

		$GLOBALS["ISC_CLASS_DB"]->UpdateQuery("products", $savedata, "productid = " . $productID);
	}
Example #14
0
	/**
	 * Get the thumbnail image of this quote item.
	 *
	 * @return string Thumbnail image path.
	 */
	public function getThumbnail()
	{
		$productData = $this->getProductData();

		if (!empty($productData['variation']['vcimage']) && !empty($productData['variation']['vcimagethumb'])) {
			try {
				$image = new ISC_PRODUCT_IMAGE;
				$image->setSourceFilePath($productData['variation']['vcimage']);
				$image->setResizedFilePath(ISC_PRODUCT_IMAGE_SIZE_THUMBNAIL, $productData['variation']['vcimagethumb']);
				return $image->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_THUMBNAIL, true, false);
			} catch (Exception $exception) {
				return '';
			}
		}

		try {
			$image = new ISC_PRODUCT_IMAGE();
			$image->populateFromDatabaseRow($productData);
			return $image->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_THUMBNAIL, true);
		} catch (Exception $exception) {
			return '';
		}
	}
	/**
	* DeleteVariations
	* Delete one/more product variations from the database
	*
	* @return Void
	*/
	public function deleteProductVariationsAction()
	{
		if(isset($_POST['variations']) && is_array($_POST['variations'])) {

			foreach ($_POST['variations'] as $k => $v) {
				$_POST['variations'][$k] = (int) $v;
			}

			// What we do here is feed the list of product IDs in to a query with the vendor applied so that way
			// we're sure we're only deleting variations this user has permission to delete.
			$variation_ids = implode("','", array_map('intval', $_POST['variations']));
			$vendorId = $GLOBALS['ISC_CLASS_ADMIN_AUTH']->GetVendorId();
			if($vendorId > 0) {
				$query = "
					SELECT variationid
					FROM [|PREFIX|]product_variations
					WHERE variationid IN ('".$variation_ids."') AND vvendorid='".(int)$vendorId."'
				";
				$result = $GLOBALS['ISC_CLASS_DB']->Query($query);
				$variation_ids = '';
				while($variation = $GLOBALS['ISC_CLASS_DB']->Fetch($result)) {
					$variation_ids .= $variation['variationid'].',';
				}
				$variation_ids = rtrim($variation_ids, ',');
			}

			// ISC-1650 need to delete images for deleted variation combinations, to do that we need a list of the
			// images that will be deleted before deleting the records below
			$deletedImages = array();
			$deletedCombinations = "
				SELECT DISTINCT
					vcimage, vcimagezoom, vcimagestd, vcimagethumb
				FROM
					[|PREFIX|]product_variation_combinations
				WHERE
					vcvariationid IN ('" . $variation_ids . "')
			";
			$deletedCombinations = new Interspire_Db_QueryIterator($this->db, $deletedCombinations);
			foreach ($deletedCombinations as $deletedCombination) {
				$deletedImages[$deletedCombination['vcimage']] = true;
				$deletedImages[$deletedCombination['vcimagezoom']] = true;
				$deletedImages[$deletedCombination['vcimagestd']] = true;
				$deletedImages[$deletedCombination['vcimagethumb']] = true;
			}

			$GLOBALS["ISC_CLASS_DB"]->StartTransaction();

			$errors = 0;

			// Delete the variation
			if (!$GLOBALS["ISC_CLASS_DB"]->DeleteQuery("product_variations", sprintf("WHERE variationid IN('%s')", $variation_ids))) {
				$errors++;
			}

			// Delete the variation combinations
			if (!$GLOBALS["ISC_CLASS_DB"]->DeleteQuery("product_variation_combinations", sprintf("WHERE vcvariationid IN('%s')", $variation_ids))) {
				$errors++;
			}

			// Delete the variation options
			if (!$GLOBALS["ISC_CLASS_DB"]->DeleteQuery("product_variation_options", sprintf("WHERE vovariationid IN('%s')", $variation_ids))) {
				$errors++;
			}

			// Update the products that use this variation to not use any at all
			if (!$GLOBALS["ISC_CLASS_DB"]->UpdateQuery("products", array("prodvariationid" => "0"), "prodvariationid IN('" . $variation_ids . "')")) {
				$errors++;
			}

			if (!$errors) {
				// ISC-1650 delete combination images which are no longer in the system anywhere
				foreach ($deletedImages as $deletedImage => $foo) {
					try {
						if (ISC_PRODUCT_IMAGE::isImageInUse($deletedImage)) {
							// the image is referenced elsewhere and should stay
							continue;
						}
					} catch (Exception $exception) {
						// something failed -- don't delete since we're unsure if the image is in use or not
						continue;
					}

					$deletedImagePath = ISC_BASE_PATH . '/' . GetConfig('ImageDirectory') . '/' . $deletedImage;
					if (!file_exists($deletedImagePath)) {
						continue;
					}
					// the image is not used anywhere, delete it
					unlink($deletedImagePath);
				}
			}

			if (!$errors) {
				$GLOBALS["ISC_CLASS_DB"]->CommitTransaction();
				return $this->viewProductVariationsAction(GetLang("VariationDeletedSuccessfully"), MSG_SUCCESS);
			}
			else {
				$GLOBALS["ISC_CLASS_DB"]->RollbackTransaction();
				return $this->viewProductVariationsAction(sprintf(GetLang("ErrorWhenDeletingVariation"), $GLOBALS["ISC_CLASS_DB"]->GetErrorMsg()), MSG_ERROR);
			}
		}
		else {
			return $this->viewProductVariationsAction();
		}
	}
Example #16
0
	/**
	* Gets a set of images for the first option set in a variation for a specific product.
	* Eg. For a variation: Color => (Red, Blue, Green), Size => (S, M, L) :
	*  	Red => ../image1.jpg
	* 	Blue => ../image2.jpg
	* 	Green => ../image3.jpg
	* will be returned.
	*
	* @param int $productId The product to find images for
	* @param int $variationId The variation to find images for
	* @return array An array of combination images indexed by option name
	*/
	public static function getCombinationImagesForFirstOption($productId, $variationId)
	{
		// get the variation options for the first option set
		$query = "
			SELECT
				*
			FROM
				[|PREFIX|]product_variation_options
			WHERE
				vovariationid = " . $variationId . " AND
				vooptionsort = 1
		";

		$res = $GLOBALS['ISC_CLASS_DB']->Query($query);

		$optionIdsArray = array();
		$optionName = '';

		while ($optionRow = $GLOBALS['ISC_CLASS_DB']->Fetch($res)) {
			$optionName = $optionRow['voname'];

			$optionIdsArray[$optionRow['voptionid']] = $optionRow['vovalue'];
		}

		// now find a set of images for the options
		$setMatches = array();
		foreach($optionIdsArray as $optionId => $optionValue) {
			$setMatches[] = 'FIND_IN_SET(' . $optionId . ', vcoptionids)';
		}

		$query = "
			SELECT
				vcoptionids,
				vcimage,
				vcimagestd
			FROM
				[|PREFIX|]product_variation_combinations
			WHERE
				vcvariationid = " . $variationId . " AND
				vcproductid = " . $productId . " AND
				vcenabled = 1 AND (
				" . implode(' OR ', $setMatches) . "
				) AND
				vcimage != '' AND
				vcimagestd != ''
		";

		$res = $GLOBALS['ISC_CLASS_DB']->Query($query);
		$images = array();
		while ($comboRow = $GLOBALS['ISC_CLASS_DB']->Fetch($res)) {
			$comboOptionIds = explode(',', $comboRow['vcoptionids']);

			// get the option id that was matched for this row
			$optionId = current(array_intersect(array_keys($optionIdsArray), $comboOptionIds));

			// get the option that this row corresponds to
			$optionName = $optionIdsArray[$optionId];

			if (!isset($images[$optionName])) {
				try {
					$productImage = new ISC_PRODUCT_IMAGE;
					$productImage->setSourceFilePath($comboRow['vcimage'])
						->setResizedFilePath(ISC_PRODUCT_IMAGE_SIZE_STANDARD, $comboRow['vcimagestd']);
					$images[$optionName] = $productImage->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_STANDARD, true, false);
				} catch (Exception $exception) {
					// nothing
				}
			}
		}

		return $images;
	}
Example #17
0
	private function getOrderData($orderRow, $addressIndex)
	{
		// Get the customer data
		if ($orderRow['ordcustid'] == 0){
			$customerData = array(
				'CustomerID' 	=> -1,
				'Phone' 		=> $orderRow['ordbillphone'],
				'Email'			=> $orderRow['ordbillemail']
			);
		}
		else {
			$customer = GetCustomer($orderRow['ordcustid']);
			$customerData = array(
				'CustomerID'	=> $orderRow['ordcustid'],
				'Phone'			=> $customer['custconphone'],
				'Email'			=> $customer['custconemail']
			);
		}

		$orderId = $orderRow['orderid'];

		if ($orderRow['shipping_address_count'] > 1) {
			$orderId .= '-' . $addressIndex;
		}

		$data = array(
			'OrderNumber' 		=> $orderId,
			'OrderDate' 		=> gmdate('Y-m-d H:i:s', $orderRow['orddate']),
			'LastModified' 		=> gmdate('Y-m-d H:i:s', $orderRow['ordlastmodified']),
			'LastModifiedLocal'	=> isc_date('Y-m-d H:i:s', $orderRow['ordlastmodified']),
			'ShippingMethod'	=> $orderRow['method'],
			'StatusCode'		=> $orderRow['ordstatus'],

			'CustomerComment'	=> $orderRow['ordcustmessage'],
			'Customer'			=> $customerData,

			'ShipAddress'		=> array(
									'Name'		=> $orderRow['first_name'] . ' ' . $orderRow['last_name'],
									'Company'	=> $orderRow['company'],
									'Street1'	=> $orderRow['address_1'],
									'Street2'	=> $orderRow['address_2'],
									'Street3'	=> '',
									'City'		=> $orderRow['city'],
									'PostalCode'=> $orderRow['zip'],
									'State'		=> $orderRow['state'],
									'Country'	=> $orderRow['country_iso2']
								),

			'BillAddress'		=> array(
									'Name'		=> $orderRow['ordbillfirstname'] . ' ' . $orderRow['ordbilllastname'],
									'Company'	=> $orderRow['ordbillcompany'],
									'Street1'	=> $orderRow['ordbillstreet1'],
									'Street2'	=> $orderRow['ordbillstreet2'],
									'Street3'	=> '',
									'City'		=> $orderRow['ordbillsuburb'],
									'PostalCode'=> $orderRow['ordbillzip'],
									'State'		=> $orderRow['ordbillstate'],
									'Country'	=> $orderRow['ordbillcountrycode']
								),

			'Payment'			=> array(
									'Method' => $orderRow['orderpaymentmethod'],
								),
		);


		$incTaxPrices = false;
		if (GetConfig('taxDefaultTaxDisplayOrders') != TAX_PRICES_DISPLAY_EXCLUSIVE) {
			$incTaxPrices = true;
		}

		// get the products for the order
		$items = array();
		$totalWrapCost = 0;

		$query = '
			SELECT
				op.*,
				pi.*
			FROM
				[|PREFIX|]order_products op
				LEFT JOIN [|PREFIX|]product_images pi ON (pi.imageprodid = op.ordprodid AND pi.imageisthumb = 1)
			WHERE
				op.order_address_id = ' . $orderRow['address_id'];

		$res = $GLOBALS['ISC_CLASS_DB']->Query($query);
		while ($productRow = $GLOBALS['ISC_CLASS_DB']->Fetch($res)) {
			$item = array(
				'ItemID'	=> $productRow['orderprodid'],
				'ProductID'	=> $productRow['ordprodid'],
				'Code'		=> $productRow['ordprodsku'],
				'Name'		=> $productRow['ordprodname'],
				'Quantity'	=> $productRow['ordprodqty'],
				'Weight'	=> ConvertWeight($productRow['ordprodweight'], 'lbs'),
			);

			if ($incTaxPrices) {
				$item['UnitPrice'] = $productRow['price_inc_tax'];
				$totalWrapCost += $productRow['wrapping_cost_inc_tax'] * $productRow['ordprodqty'];
			}
			else {
				$item['UnitPrice'] = $productRow['price_ex_tax'];
				$totalWrapCost += $productRow['wrapping_cost_ex_tax'] * $productRow['ordprodqty'];
			}

			try {
				$image = new ISC_PRODUCT_IMAGE();
				$image->populateFromDatabaseRow($productRow);
				$item['Image'] = $image->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_ZOOM, true);
			}
			catch (Exception $ex) {
			}

			$items['Item'][] = $item;
		}

		$data['Items'] = $items;

		// get the totals
		$totals = array();
		$totalID = 1;

		// gift wrapping cost
		if ($totalWrapCost > 0) {
			$total = array(
				'TotalID' 	=> $totalID++,
				'Name'		=> GetLang('ShipWorksGiftWrapping'),
				'Text'		=> FormatPrice($totalWrapCost),
				'Value'		=> $totalWrapCost,
				'Class'		=> 'Adjust'
			);

			$totals['Total'][] = $total;
		}

		// shipping cost
		if ($orderRow['shipping_cost_ex_tax'] > 0) {
			if ($incTaxPrices) {
				$shippingCost = $orderRow['shipping_cost_inc_tax'];
			}
			else {
				$shippingCost = $orderRow['shipping_cost_ex_tax'];
			}

			$total = array(
				'TotalID' 	=> $totalID++,
				'Name'		=> GetLang('ShipWorksShipping'),
				'Text'		=> FormatPrice($shippingCost),
				'Value'		=> $shippingCost,
				'Class'		=> 'Shipping'
			);

			$totals['Total'][] = $total;
		}

		// handling cost
		if ($orderRow['handling_cost_ex_tax'] > 0) {
			if ($incTaxPrices) {
				$handlingCost = $orderRow['handling_cost_inc_tax'];
			}
			else {
				$handlingCost = $orderRow['handling_cost_ex_tax'];
			}

			$total = array(
				'TotalID' 	=> $totalID++,
				'Name'		=> GetLang('ShipWorksHandling'),
				'Text'		=> FormatPrice($handlingCost),
				'Value'		=> $handlingCost,
				'Class'		=> 'Shipping'
			);

			$totals['Total'][] = $total;
		}

		// tax (not included in total)
		if ($orderRow['total_tax'] > 0 && !$incTaxPrices) {
			$total = array(
				'TotalID' 	=> $totalID++,
				'Name'		=> 'Tax',
				'Text'		=> FormatPrice($orderRow['total_tax']),
				'Value'		=> $orderRow['total_tax'],
				'Class'		=> 'Tax'
			);

			$totals['Total'][] = $total;
		}

		// total
		if ($incTaxPrices) {
			$orderTotal = $orderRow['total_inc_tax'];
		}
		else {
			$orderTotal = $orderRow['total_ex_tax'];
		}

		$total = array(
			'TotalID' 	=> $totalID++,
			'Name'		=> GetLang('ShipWorksTotal'),
			'Text'		=> FormatPrice($orderTotal),
			'Value'		=> $orderTotal,
			'Class'		=> 'ot_total'
		);

		$totals['Total'][] = $total;

		// gift certificates
		if ($orderRow['ordgiftcertificateamount'] > 0) {
			$total = array(
				'TotalID' 	=> $totalID++,
				'Name'		=> GetLang('ShipWorksGiftCertificates'),
				'Text'		=> FormatPrice($orderRow['ordgiftcertificateamount']),
				'Value'		=> $orderRow['ordgiftcertificateamount'] * -1,
				'Class'		=> 'Adjust'
			);

			$totals['Total'][] = $total;
		}

		// other discount amount
		if ($orderRow['orddiscountamount'] > 0) {
			$total = array(
				'TotalID' 	=> $totalID++,
				'Name'		=> GetLang('ShipWorksDiscounts'),
				'Text'		=> FormatPrice($orderRow['orddiscountamount']),
				'Value'		=> $orderRow['orddiscountamount'] * -1,
				'Class'		=> 'Adjust'
			);

			$totals['Total'][] = $total;
		}

		$data['Totals'] = $totals;

		return $data;
	}
Example #18
0
		public function CopyProductStep1($MsgDesc = "", $MsgStatus = "", $PreservePost=false, $OriginalProductID=0)
		{
			if ($MsgDesc != "") {
				$GLOBALS['Message'] = MessageBox($MsgDesc, $MsgStatus);
			}

			// Show the form to edit a product
			if (isset($_REQUEST['productId']) && isId($_REQUEST['productId'])) {
				$OriginalProductID = $_REQUEST['productId'];
			}

			$prodId = $OriginalProductID;
			$z = 0;
			$arrData = array();
			$arrCustomFields = array();

			if (GetConfig('CurrencyLocation') == 'right') {
				$GLOBALS['CurrencyTokenLeft'] = '';
				$GLOBALS['CurrencyTokenRight'] = GetConfig('CurrencyToken');
			} else {
				$GLOBALS['CurrencyTokenLeft'] = GetConfig('CurrencyToken');
				$GLOBALS['CurrencyTokenRight'] = '';
			}

			$GLOBALS['ServerFiles'] = $this->_GetImportFilesOptions();

			$GLOBALS['ISC_CLASS_ADMIN_CATEGORY'] = GetClass('ISC_ADMIN_CATEGORY');

			// Make sure the product exists
			if (ProductExists($prodId)) {

				if($PreservePost == true) {
					$this->_GetProductData(0, $arrData);
					$this->_GetCustomFieldData(0, $arrCustomFields);
					$GLOBALS['ProductFields'] = $this->_GetProductFieldsLayout(0, true);

					// Restore the hash
					$GLOBALS['ProductHash'] = $arrData['prodhash'];
				} else {
					$this->_GetProductData($prodId, $arrData);
					$this->_GetCustomFieldData($prodId, $arrCustomFields);
					$GLOBALS['ProductFields'] = $this->_GetProductFieldsLayout($prodId, true);

					// Generate the hash
					$GLOBALS['ProductHash'] = md5(time().uniqid(rand(), true));

					// We'll need to duplicate (copy) the thumbnail, images and download files here
					$this->_CopyDownloads($prodId, 0, $GLOBALS['ProductHash']);
					$productImages = ISC_PRODUCT_IMAGE::copyImagesToProductHash($prodId, $GLOBALS['ProductHash']);
					$this->setupProductImageGlobals($productImages);

					$arrData['prodname'] = GetLang('CopyOf') . $arrData['prodname'];
				}

				$this->template->assign('product', $arrData);

				// Does this user have permission to edit this product?
				if($GLOBALS['ISC_CLASS_ADMIN_AUTH']->GetVendorId() && $arrData['prodvendorid'] != $GLOBALS['ISC_CLASS_ADMIN_AUTH']->GetVendorId()) {
					FlashMessage(GetLang('Unauthorized'), MSG_ERROR, 'index.php?ToDo=viewProducts');
				}

				if(isset($_POST['currentTab'])) {
					$GLOBALS['CurrentTab'] = (int)$_POST['currentTab'];
				}
				else {
					$GLOBALS['CurrentTab'] = 0;
				}

				$GLOBALS['FormAction'] = 'copyProduct2';
				$GLOBALS['Title'] = GetLang('CopyProductTitle');
				$GLOBALS['Intro'] = GetLang('CopyProductIntro');
				$GLOBALS["ProdType_" . $arrData['prodtype']] = 'checked="checked"';
				$GLOBALS['ProdType'] = $arrData['prodtype'] - 1;
				$GLOBALS['ProdCode'] = isc_html_escape($arrData['prodcode']);
				$GLOBALS['ProdName'] = isc_html_escape($arrData['prodname']);
				$GLOBALS['OriginalProductId'] = $OriginalProductID;

				$visibleCategories = array();
				if($GLOBALS['ISC_CLASS_ADMIN_AUTH']->GetVendorId()) {
					$vendorData = $GLOBALS['ISC_CLASS_ADMIN_AUTH']->GetVendor();
					if($vendorData['vendoraccesscats']) {
						$visibleCategories = explode(',', $vendorData['vendoraccesscats']);
					}
				}
				$GLOBALS['CategoryOptions'] = $GLOBALS['ISC_CLASS_ADMIN_CATEGORY']->GetCategoryOptions($arrData['prodcats'], "<option %s value='%d'>%s</option>", "selected='selected'", "", false, '', $visibleCategories);
				$GLOBALS['RelatedCategoryOptions'] = $GLOBALS['ISC_CLASS_ADMIN_CATEGORY']->GetCategoryOptions(0, "<option %s value='%d'>%s</option>", "selected='selected'", "- ", false);

				$wysiwygOptions = array(
					'id'		=> 'wysiwyg',
					'width'		=> '100%',
					'height'	=> '500px',
					'value'		=> $arrData['proddesc']
				);
				$GLOBALS['WYSIWYG'] = GetClass('ISC_ADMIN_EDITOR')->GetWysiwygEditor($wysiwygOptions);

				$GLOBALS['ProdSearchKeywords'] = isc_html_escape($arrData['prodsearchkeywords']);
				$GLOBALS['ProdAvailability'] = isc_html_escape($arrData['prodavailability']);
				$GLOBALS['ProdPrice'] = number_format($arrData['prodprice'], GetConfig('DecimalPlaces'), GetConfig('DecimalToken'), "");

				if (CFloat($arrData['prodcostprice']) > 0) {
					$GLOBALS['ProdCostPrice'] = number_format($arrData['prodcostprice'], GetConfig('DecimalPlaces'), GetConfig('DecimalToken'), "");
				}

				if (CFloat($arrData['prodretailprice']) > 0) {
					$GLOBALS['ProdRetailPrice'] = number_format($arrData['prodretailprice'], GetConfig('DecimalPlaces'), GetConfig('DecimalToken'), "");
				}

				if (CFloat($arrData['prodsaleprice']) > 0) {
					$GLOBALS['ProdSalePrice'] = number_format($arrData['prodsaleprice'], GetConfig('DecimalPlaces'), GetConfig('DecimalToken'), "");
				}

				$GLOBALS['ProdSortOrder'] = $arrData['prodsortorder'];

				if ($arrData['prodvisible'] == 1) {
					$GLOBALS['ProdVisible'] = "checked";
				}

				if ($arrData['prodfeatured'] == 1) {
					$GLOBALS['ProdFeatured'] = "checked";
				}

				if($GLOBALS['ISC_CLASS_ADMIN_AUTH']->GetVendorId()) {
					$GLOBALS['HideStoreFeatured'] = 'display: none';
				}
				else if(!gzte11(ISC_HUGEPRINT) || !$arrData['prodvendorid']) {
					$GLOBALS['HideVendorFeatured'] = 'display: none';
				}

				if($arrData['prodvendorfeatured'] == 1) {
					$GLOBALS['ProdVendorFeatured'] = 'checked="checked"';
				}

				if($arrData['prodallowpurchases'] == 1) {
					$GLOBALS['ProdAllowPurchases'] = 'checked="checked"';
				}
				else {
					if($arrData['prodhideprice'] == 1) {
						$GLOBALS['ProdHidePrice'] = 'checked="checked"';
					}
					$GLOBALS['ProdCallForPricingLabel'] = isc_html_escape($arrData['prodcallforpricinglabel']);
				}

				$GLOBALS['ProdWarranty'] = $arrData['prodwarranty'];
				$GLOBALS['ProdWeight'] = number_format($arrData['prodweight'], GetConfig('DecimalPlaces'), GetConfig('DecimalToken'), "");

				if (CFloat($arrData['prodwidth']) > 0) {
					$GLOBALS['ProdWidth'] = number_format($arrData['prodwidth'], GetConfig('DecimalPlaces'), GetConfig('DecimalToken'), "");
				}

				if (CFloat($arrData['prodheight']) > 0) {
					$GLOBALS['ProdHeight'] = number_format($arrData['prodheight'], GetConfig('DecimalPlaces'), GetConfig('DecimalToken'), "");
				}

				if (CFloat($arrData['proddepth']) > 0) {
					$GLOBALS['ProdDepth'] = number_format($arrData['proddepth'], GetConfig('DecimalPlaces'), GetConfig('DecimalToken'), "");
				}

				if (CFloat($arrData['prodfixedshippingcost']) > 0) {
					$GLOBALS['ProdFixedShippingCost'] = number_format($arrData['prodfixedshippingcost'], GetConfig('DecimalPlaces'), GetConfig('DecimalToken'), "");
				}

				if ($arrData['prodfreeshipping'] == 1) {
					$GLOBALS['FreeShipping'] = 'checked="checked"';
				}

				if($arrData['prodrelatedproducts'] == -1) {
					$GLOBALS['IsProdRelatedAuto'] = 'checked="checked"';
				}
				else if(isset($arrData['prodrelated'])) {
					$GLOBALS['RelatedProductOptions'] = "";

					foreach ($arrData['prodrelated'] as $r) {
						$GLOBALS['RelatedProductOptions'] .= sprintf("<option value='%d'>%s</option>", (int) $r[0], isc_html_escape($r[1]));
					}
				}

				$GLOBALS['ProdTags'] = $arrData['prodtags'];

				$GLOBALS['CurrentStockLevel'] = $arrData['prodcurrentinv'];
				$GLOBALS['LowStockLevel'] = $arrData['prodlowinv'];
				$GLOBALS["InvTrack_" . $arrData['prodinvtrack']] = 'checked="checked"';

				$GLOBALS['WrappingOptions'] = $this->BuildGiftWrappingSelect(explode(',', $arrData['prodwrapoptions']));
				$GLOBALS['HideGiftWrappingOptions'] = 'display: none';
				if($arrData['prodwrapoptions'] == 0) {
					$GLOBALS['WrappingOptionsDefaultChecked'] = 'checked="checked"';
				}
				else if($arrData['prodwrapoptions'] == -1) {
					$GLOBALS['WrappingOptionsNoneChecked'] = 'checked="checked"';
				}
				else {
					$GLOBALS['HideGiftWrappingOptions'] = '';
					$GLOBALS['WrappingOptionsCustomChecked'] = 'checked="checked"';
				}

				if ($arrData['prodinvtrack'] == 1) {
					$GLOBALS['OptionButtons'] = "ToggleProductInventoryOptions(true);";
				} else {
					$GLOBALS['OptionButtons'] = "ToggleProductInventoryOptions(false);";
				}

				if ($arrData['prodoptionsrequired'] == 1) {
					$GLOBALS['OptionsRequired'] = 'checked="checked"';
				}

				if ($arrData['prodtype'] == 1) {
					$GLOBALS['HideProductInventoryOptions'] = "none";
				}

				$GLOBALS['EnterOptionPrice'] = sprintf(GetLang('EnterOptionPrice'), GetConfig('CurrencyToken'), GetConfig('CurrencyToken'));
				$GLOBALS['EnterOptionWeight'] = sprintf(GetLang('EnterOptionWeight'), GetConfig('WeightMeasurement'));
				$GLOBALS['HideCustomFieldLink'] = "none";

				if(getConfig('taxEnteredWithPrices') == TAX_PRICES_ENTERED_INCLUSIVE) {
					$this->template->assign('enterPricesWithTax', true);
				}

				$GLOBALS['CustomFields'] = '';
				$GLOBALS['CustomFieldKey'] = 0;

				if (!empty($arrCustomFields)) {
					foreach ($arrCustomFields as $f) {
						$GLOBALS['CustomFieldName'] = isc_html_escape($f['name']);
						$GLOBALS['CustomFieldValue'] = isc_html_escape($f['value']);
						$GLOBALS['CustomFieldLabel'] = $this->GetFieldLabel(($GLOBALS['CustomFieldKey']+1), GetLang('CustomField'));

						if (!$GLOBALS['CustomFieldKey']) {
							$GLOBALS['HideCustomFieldDelete'] = 'none';
						} else {
							$GLOBALS['HideCustomFieldDelete'] = '';
						}

						$GLOBALS['CustomFields'] .= $this->template->render('Snippets/CustomFields.html');

						$GLOBALS['CustomFieldKey']++;
					}
				}

				// Add one more custom field
				$GLOBALS['CustomFieldName'] = '';
				$GLOBALS['CustomFieldValue'] = '';
				$GLOBALS['CustomFieldLabel'] = $this->GetFieldLabel(($GLOBALS['CustomFieldKey']+1), GetLang('CustomField'));

				if (!$GLOBALS['CustomFieldKey']) {
					$GLOBALS['HideCustomFieldDelete'] = 'none';
				} else {
					$GLOBALS['HideCustomFieldDelete'] = '';
				}

				$GLOBALS['CustomFields'] .= $this->template->render('Snippets/CustomFields.html');

				// Get a list of any downloads associated with this product
				$GLOBALS['DownloadsGrid'] = $this->GetDownloadsGrid(0, $GLOBALS['ProductHash']);
				$GLOBALS['ISC_LANG']['MaxUploadSize'] = sprintf(GetLang('MaxUploadSize'), GetMaxUploadSize());
				if($GLOBALS['DownloadsGrid'] == '') {
					$GLOBALS['DisplayDownloaadGrid'] = "none";
				}

				// Get the brands as select options
				$GLOBALS['ISC_CLASS_ADMIN_BRANDS'] = GetClass('ISC_ADMIN_BRANDS');
				$GLOBALS['BrandNameOptions'] = $GLOBALS['ISC_CLASS_ADMIN_BRANDS']->GetBrandsAsOptions($arrData['prodbrandid']);
				$GLOBALS['SaveAndAddAnother'] = GetLang('SaveAndAddAnother');

				// Get a list of all layout files
				$layoutFile = 'product.html';
				if($arrData['prodlayoutfile'] != '') {
					$layoutFile = $arrData['prodlayoutfile'];
				}
				$GLOBALS['LayoutFiles'] = GetCustomLayoutFilesAsOptions("product.html", $layoutFile);

				$GLOBALS['ProdPageTitle'] = isc_html_escape($arrData['prodpagetitle']);
				$GLOBALS['ProdMetaKeywords'] = isc_html_escape($arrData['prodmetakeywords']);
				$GLOBALS['ProdMetaDesc'] = isc_html_escape($arrData['prodmetadesc']);
				$GLOBALS['SaveAndAddAnother'] = GetLang('SaveAndAddAnother');

				if(!gzte11(ISC_MEDIUMPRINT)) {
					$GLOBALS['HideInventoryOptions'] = "none";
				}
				else {
					$GLOBALS['HideInventoryOptions'] = '';
				}

				// Does this product have a variation assigned to it?
				$GLOBALS['ProductVariationExisting'] = $arrData['prodvariationid'];

				if($arrData['prodvariationid'] > 0) {
					$GLOBALS['IsYesVariation'] = 'checked="checked"';
				}
				else {
					$GLOBALS['IsNoVariation'] = 'checked="checked"';
					$GLOBALS['HideVariationList'] = "none";
					$GLOBALS['HideVariationCombinationList'] = "none";
				}

				// Get the list of tax classes and assign them
				$this->template->assign('taxClasses', array(
					0 => getLang('DefaultTaxClass')
				) + getClass('ISC_TAX')->getTaxClasses());

				// If there are no variations then disable the option to choose one
				$numVariations = 0;
				$GLOBALS['VariationOptions'] = $this->GetVariationsAsOptions($numVariations, $arrData['prodvariationid']);

				if($numVariations == 0) {
					$GLOBALS['VariationDisabled'] = "DISABLED";
					$GLOBALS['VariationColor'] = "#CACACA";
					$GLOBALS['IsNoVariation'] = 'checked="checked"';
					$GLOBALS['IsYesVariation'] = "";
					$GLOBALS['HideVariationCombinationList'] = "none";
				}
				else {
					// Load the variation combinations
					if($arrData['prodinvtrack'] == 2) {
						$show_inv_fields = true;
					}
					else {
						$show_inv_fields = false;
					}

					/**
					 * We'll need to duplicate the variation combinations here if we are NOT preserving the post
					 */
					if (!$PreservePost) {
						$this->_CopyVariationData($arrData['productid'], 0, $GLOBALS['ProductHash']);
					}

					$GLOBALS['VariationCombinationList'] = $this->_LoadVariationCombinationsTable($arrData['prodvariationid'], $show_inv_fields, 0, $GLOBALS['ProductHash']);
				}

				if(!gzte11(ISC_HUGEPRINT)) {
					$GLOBALS['HideVendorOption'] = 'display: none';
				}
				else {
					$vendorData = $GLOBALS['ISC_CLASS_ADMIN_AUTH']->GetVendor();
					if(isset($vendorData['vendorid'])) {
						$GLOBALS['HideVendorSelect'] = 'display: none';
						$GLOBALS['CurrentVendor'] = isc_html_escape($vendorData['vendorname']);
					}
					else {
						$GLOBALS['HideVendorLabel'] = 'display: none';
						$GLOBALS['VendorList'] = $this->BuildVendorSelect($arrData['prodvendorid']);
					}
				}

				// Display the discount rules
				if ($PreservePost == true) {
					$GLOBALS['DiscountRules'] = $this->GetDiscountRules(0);
				} else {
					$GLOBALS['DiscountRules'] = $this->GetDiscountRules($prodId);
				}


				// Hide if we are not enabled
				if (!GetConfig('BulkDiscountEnabled')) {
					$GLOBALS['HideDiscountRulesWarningBox'] = '';
					$GLOBALS['DiscountRulesWarningText'] = GetLang('DiscountRulesNotEnabledWarning');
					$GLOBALS['DiscountRulesWithWarning'] = 'none';

				// Also hide it if this product has variations
				} else if (isset($arrData['prodvariationid']) && isId($arrData['prodvariationid'])) {
					$GLOBALS['HideDiscountRulesWarningBox'] = '';
					$GLOBALS['DiscountRulesWarningText'] = GetLang('DiscountRulesVariationWarning');
					$GLOBALS['DiscountRulesWithWarning'] = 'none';
				} else {
					$GLOBALS['HideDiscountRulesWarningBox'] = 'none';
					$GLOBALS['DiscountRulesWithWarning'] = '';
				}

				$GLOBALS['DiscountRulesEnabled'] = (int)GetConfig('BulkDiscountEnabled');

				$GLOBALS['EventDateFieldName'] = $arrData['prodeventdatefieldname'];

				if ($GLOBALS['EventDateFieldName'] == null) {
					$GLOBALS['EventDateFieldName'] = GetLang('EventDateDefault');
				}

				if ($arrData['prodeventdaterequired'] == 1) {
					$GLOBALS['EventDateRequired'] = 'checked="checked"';
					$from_stamp = $arrData['prodeventdatelimitedstartdate'];
					$to_stamp = $arrData['prodeventdatelimitedenddate'];
				} else {
					$from_stamp = isc_gmmktime(0, 0, 0, isc_date("m"), isc_date("d"), isc_date("Y"));
					$to_stamp = isc_gmmktime(0, 0, 0, isc_date("m")+1, isc_date("d"), isc_date("Y"));
				}
				if ($arrData['prodeventdatelimited'] == 1) {
					$GLOBALS['LimitDates'] = 'checked="checked"';
				}

				$GLOBALS['LimitDateOption1'] = '';
				$GLOBALS['LimitDateOption2'] = '';
				$GLOBALS['LimitDateOption3'] = '';

				switch ($arrData['prodeventdatelimitedtype']) {

					case 1 :
						$GLOBALS['LimitDateOption1'] = 'selected="selected"';
					break;
					case 2 :
						$GLOBALS['LimitDateOption2'] = 'selected="selected"';
					break;
					case 3 :
						$GLOBALS['LimitDateOption3'] = 'selected="selected"';
					break;
				}

				// Set the global variables for the select boxes

				$from_day = isc_date("d", $from_stamp);
				$from_month = isc_date("m", $from_stamp);
				$from_year = isc_date("Y", $from_stamp);

				$to_day = isc_date("d", $to_stamp);
				$to_month = isc_date("m", $to_stamp);
				$to_year = isc_date("Y", $to_stamp);

				$GLOBALS['OverviewFromDays'] = $this->_GetDayOptions($from_day);
				$GLOBALS['OverviewFromMonths'] = $this->_GetMonthOptions($from_month);
				$GLOBALS['OverviewFromYears'] = $this->_GetYearOptions($from_year);

				$GLOBALS['OverviewToDays'] = $this->_GetDayOptions($to_day);
				$GLOBALS['OverviewToMonths'] = $this->_GetMonthOptions($to_month);
				$GLOBALS['OverviewToYears'] = $this->_GetYearOptions($to_year);

				if(!$GLOBALS['ISC_CLASS_ADMIN_AUTH']->HasPermission(AUTH_Create_Category)) {
					$GLOBALS['HideCategoryCreation'] = 'display: none';
				}

				//Google website optimizer
				$GLOBALS['HideOptimizerConfigForm'] = 'display:none;';
				$GLOBALS['CheckEnableOptimizer'] = '';
				$GLOBALS['SkipConfirmMsg'] = 'false';
				$GLOBALS['GoogleWebsiteOptimizerIntro'] = GetLang('ProdGoogleWebsiteOptimizerIntro');

				$enabledOptimizers = GetConfig('OptimizerMethods');
				if(!empty($enabledOptimizers)) {
					foreach ($enabledOptimizers as $id => $date) {
						GetModuleById('optimizer', $optimizerModule, $id);
						if ($optimizerModule->_testPage == 'products' || $optimizerModule->_testPage == 'all') {
							$GLOBALS['SkipConfirmMsg'] = 'false';
							break;
						}
					}
				}
				if($arrData['product_enable_optimizer'] == '1') {
					$GLOBALS['HideOptimizerConfigForm'] = '';
					$GLOBALS['CheckEnableOptimizer'] = 'Checked';
				}

				$this->template->assign('prodminqty', $arrData['prodminqty']);
				$this->template->assign('prodmaxqty', $arrData['prodmaxqty']);

				$optimizer = getClass('ISC_ADMIN_OPTIMIZER');
				$GLOBALS['OptimizerConfigForm'] = $optimizer->showPerItemConfigForm('product', $arrData['productid'],prodLink($arrData['prodname']));

				if ($arrData['prodpreorder'] && $arrData['prodreleasedateremove'] && time() >= $arrData['prodreleasedate']) {
					// pre-order release date has passed and remove is ticked, remove it now for the copy form at least - saving it will commit it to the db
					$arrData['prodpreorder'] = 0;
					$arrData['prodreleasedate'] = 0;
					$arrData['prodreleasedateremove'] = 0;
				}

				// note: prodpreorder is a database column does not map directly to a form field, it'll be set to 1 if _prodorderable is 'pre', along with prodallowpurchases to 1
				// note: _prodorderable is a form field that does not map to a database column
				if (!$arrData['prodallowpurchases']) {
					$this->template->assign('_prodorderable', 'no');
				} else if ($arrData['prodpreorder']) {
					$this->template->assign('_prodorderable', 'pre');
				} else {
					$this->template->assign('_prodorderable', 'yes');
				}

				$this->template->assign('prodreleasedateremove', $arrData['prodreleasedateremove']);

				if (isset($arrData['prodpreordermessage']) && $arrData['prodpreordermessage']) {
					$this->template->assign('prodpreordermessage', $arrData['prodpreordermessage']);
				} else {
					$this->template->assign('prodpreordermessage', GetConfig('DefaultPreOrderMessage'));
				}

				if ($arrData['prodreleasedate']) {
					$this->template->assign('prodreleasedate', isc_date('d/m/Y', $arrData['prodreleasedate']));
				}

				$GLOBALS['ProdCondition' . $arrData['prodcondition'] . 'Selected'] = 'selected="selected"';
				if ($arrData['prodshowcondition']) {
					$GLOBALS['ProdShowCondition'] = 'checked="checked"';
				}

				// Open Graph Settings
				$this->template->assign('openGraphTypes', ISC_OPENGRAPH::getObjectTypes(true));
				$this->template->assign('openGraphSelectedType', $arrData['opengraph_type']);
				$this->template->assign('openGraphUseProductName', (bool)$arrData['opengraph_use_product_name']);
				$this->template->assign('openGraphTitle', $arrData['opengraph_title']);
				$this->template->assign('openGraphUseMetaDescription', (bool)$arrData['opengraph_use_meta_description']);
				$this->template->assign('openGraphDescription', $arrData['opengraph_description']);
				$this->template->assign('openGraphUseImage', (bool)$arrData['opengraph_use_image']);

				// UPC
				$this->template->assign('ProdUPC', $arrData['upc']);

				// Google Checkout
				$this->template->assign('ProdDisableGoogleCheckout', $arrData['disable_google_checkout']);

				$GLOBALS['SaveAndAddAnother'] = GetLang('SaveAndAddAnother');
				$this->setupProductLanguageString();
				$this->template->display('product.form.tpl');
			} else {
				// The product doesn't exist
				if ($GLOBALS["ISC_CLASS_ADMIN_AUTH"]->HasPermission(AUTH_Manage_Products)) {
					$this->ManageProducts(GetLang('ProductDoesntExist'), MSG_ERROR);
				} else {
					$GLOBALS['ISC_CLASS_ADMIN_ENGINE']->DoHomePage(GetLang('Unauthorized'), MSG_ERROR);
				}
			}
		}
Example #19
0
	/**
	 * Download product data from the database to SEOM
	 *
	 * Method will process the posted data and create XML to be displayed.
	 *
	 * @access public
	 * @return string XML response to display on the page for products requested
	 */

	public function DownloadProducts()
	{
		$xml = '';
		$xml = new SimpleXMLElement('<?xml version="1.0"?><SETIProducts />');

		// set our default queries
		$query = StoneEdgeProductQuery();
		$CountQuery = StoneEdgeProductQueryCount();

		if (isset($_REQUEST['startnum']) && (int)$_REQUEST['startnum'] > 0 && isset($_REQUEST['batchsize']) && (int)$_REQUEST['batchsize'] > 0) {
			$start = (int)$_REQUEST['startnum'] - 1;
			$numresults = (int)$_REQUEST['batchsize'];

			if ($start >= 0 && $numresults > 0) {
				$query = StoneEdgeProductQuery('LIMIT ' . $start . ', ' .$numresults);
			//	$CountQuery = StoneEdgeProductQueryCount('LIMIT ' . $start . ', ' .$numresults);
			}
		}

		if ($GLOBALS['ISC_CLASS_DB']->FetchOne($CountQuery) > $start) {
			//then there are products available for download, display header
			$responseNode = $xml->addChild('Response');
			$responseNode->addChild('ResponseCode', 1);
			$responseNode->addChild('ResponseDescription', 'Success');

			$products = $GLOBALS['ISC_CLASS_DB']->Query($query);

			//content
			while ($product = $GLOBALS['ISC_CLASS_DB']->Fetch($products)) {
				$fullImage = '';
				try {
					$productImage = ISC_PRODUCT_IMAGE::getBaseThumbnailImageForProduct($product['productid']);
					if ($productImage) {
						$fullImage = $productImage->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_STANDARD, true);
					}
				} catch (Exception $exception) {
					// nothing
				}

				if ($product['prodistaxable'] == 1) {
					$taxable = 'Yes';
				} else{
					$taxable = 'No';
				}

				if ($product['prodvisible'] == 0) {
					$discontinued = 'Yes';
				} else {
					$discontinued = 'No';
				}

				$productNode = $xml->addChild('Product');
				$desc = isc_html_escape($product['proddesc']); // the tags need to be escaped
				$productNode->addChild('Taxable', $taxable);
				$productNode->addChild('Discontinued', $discontinued);

				if ($product['prodvariationid'] == 0) {
					// no variations, just send the product as is
					if(isset($product['prodcode']) && $product['prodcode'] != ''){
						$productNode->addChild('Code', htmlentities($product['prodcode']));
					}else{
						$productNode->addChild('Code', htmlentities($product['prodname']));
					}
					$productNode->addChild('WebID', $product['productid']);
					$productNode->addChild('Name', $product['prodname']);
					$productNode->addChild('Price', number_format($product['prodcalculatedprice'],2));

					$productNode->addChild('Weight', $product['prodweight']);
					$productNode->addChild('Thumb', $GLOBALS['ShopPath'] . '/product_images/' . $product['imagefile']);
					$productNode->addChild('Image', $fullImage);
					$productNode->addChild('QOH', $product['prodcurrentinv']);

				} else {
					// product has variation, we need to send each variation as a different product
					$variationQuery = "SELECT vo.voptionid, vo.voname, vo.vovalue
					FROM [|PREFIX|]product_variations v
					LEFT JOIN [|PREFIX|]product_variation_options vo ON v.variationid = vo.vovariationid
					WHERE v.variationid = '" . $product['prodvariationid'] . "'
					ORDER BY vo.voname ASC";

					$varResource = $GLOBALS['ISC_CLASS_DB']->Query($variationQuery);
					$variationids = array();
					$varnames = array();
					$varvalues = array();

					while($varReturn = $GLOBALS['ISC_CLASS_DB']->Fetch($varResource)) {
						$variationids[] = $varReturn['voptionid'];
						$varnames[] = $varReturn['voname'];
						$varvalues[] = $varReturn['vovalue'];
					}

					$variationName = array();
					$variationValues = array();
					$options = explode(',',$product['vcoptionids']);
					foreach($options as $thisOption){
						$key = array_search($thisOption, $variationids);

						if($key === false || !isset($variationids[$key])) {
							continue;
						}

						$variationName[]   = $varnames[$key];
						$variationValues[] = $varvalues[$key];
					}

					$variationValue =  implode(', ', $variationValues);

					$comboPrice = 0;
					if ($product['vcpricediff'] != '' && $product['vcpricediff'] != 'fixed') {
						$comboPrice = $product['vcprice'];
						if ($product['vcpricediff'] == 'subtract') {
							$comboPrice = $product['vcprice'] * -1;
						}
					}

					$comboWeight = 0;
					if ($product['vcweightdiff'] != '' && $product['vcweightdiff'] != 'fixed') {
						$comboWeight = $product['vcweight'];
						if ($product['vcweightdiff'] == 'subtract') {
							$comboWeight = $product['vcweight'] * -1;
						}
					}

					if(isset($product['prodcode']) && $product['prodcode'] != ''){
						$productNode->addChild('Code', htmlentities($product['prodcode']));
					}else{
						$productNode->addChild('Code', htmlentities($product['prodname']) . ' [VARID:' . $product['combinationid'] . ']');
					}
					$productNode->addChild('WebID', $product['productid'] . "-" .  $product['combinationid']);
					$productNode->addChild('Name', $product['prodname'] . ' (' . $variationValue. ')');
					$productNode->addChild('Price', number_format(($product['prodcalculatedprice'] + $comboPrice),2));
					$productNode->addChild('Description', $desc);
					$productNode->addChild('Weight', ($product['prodweight']+$comboWeight));
					$productNode->addChild('Thumb', $GLOBALS['ShopPath'] . '/product_images/' . $product['imagefile']);
					$productNode->addChild('Image', $GLOBALS['ShopPath'] . '/product_images/' . $product['vcimage']);

					$productNode->addChild('QOH', $product['vcstock']);
				} // end if this product has a variation
			}

		} else {
			//no products, return the "none available" message.
			$responseNode = $xml->addChild('Response');
			$responseNode->addChild('ResponseCode', 2);
			$responseNode->addChild('ResponseDescription', 'Success');

		}
		return $xml->asXML();
	}
Example #20
0
	public function WriteRow($row)
	{
		$expirationDate = isc_date("Y-m-d", strtotime('+29 days'));

		$link = ProdLink($row['prodname']);
		$desc = strip_tags($row['proddesc']);
		// Strip out invalid characters
		$desc = StripInvalidXMLChars($desc);

		if(isc_strlen($desc) > 1000) {
			$desc = isc_substr($desc, 0, 997)."...";
		}

		// Apply taxes to the price
		$price = getClass('ISC_TAX')->getPrice($row['prodcalculatedprice'], $row['tax_class_id'], getConfig('taxDefaultTaxDisplayProducts'));

		$entry = array(
			'title' => isc_html_escape($row['prodname']),
			'link' => isc_html_escape($link),
			'description' => isc_html_escape($desc),
			'g:department' => isc_html_escape($row['catname']),
			'g:expiration_date' => $expirationDate,
			'g:id' => $row['productid'],
			'g:condition' => isc_html_escape(isc_strtolower($row['prodcondition'])),
			'g:price' => $price
		);

		if($row['brandname']) {
			$entry['g:brand'] = isc_html_escape($row['brandname']);
		}

		if(!empty($row['imagefile'])) {
			try {
				$image = new ISC_PRODUCT_IMAGE();
				$image->populateFromDatabaseRow($row);
				$entry['g:image_link'] = isc_html_escape($image->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_ZOOM, true, true, false));
				}
			catch (Exception $ex) {
			}
		}

		if($row['prodcode']) {
			$entry['g:model_number'] = isc_html_escape($row['prodcode']);
		}

		if($row['prodweight'] > 0) {
			if(GetConfig('WeightMeasurement') == 'KGS') {
				$measure = 'kg';
			}
			else {
				$measure = strtolower(GetConfig('WeightMeasurement'));
			}
			$entry['g:weight'] = FormatWeight($row['prodweight'], false).' '.$measure;
		}

		$dimensions = array(
			'g:height' => 'prodheight',
			'g:length' => 'proddepth',
			'g:width' => 'prodwidth'
		);
		if(GetConfig('LengthMeasurement') == 'Centimeters') {
			$measure = 'cm';
		}
		else {
			$measure = strtolower(GetConfig('LengthMeasurement'));
		}

		foreach($dimensions as $google => $ours) {
			if($row[$ours] > 0) {
				$entry[$google] = $row[$ours].' '.$measure;
			}
		}

		// upc codes
		if(!empty($row['upc'])) {
			$entry['g:upc'] = StripInvalidXMLChars($row['upc']);
		}

		$xml = "<entry>\n";
		foreach($entry as $k => $v) {
			$xml .= "\t<".$k."><![CDATA[".$v."]]></".$k.">\n";
		}
		if(isset($row['prodfreeshipping']) && $row['prodfreeshipping'] != 1){
			$xml .= "</entry>\n";
		} else {
			$xml .= "\t<g:shipping><g:price><![CDATA[0]]></g:price></g:shipping>\n</entry>\n";
		}

		fwrite($this->handle, $xml);
	}
Example #21
0
		/**
		 * Build the array of searched item results for the AJAX request
		 *
		 * Method will build an array of searched item results for the AJAX request. Method will work with the ISC_SEARCH
		 * class to get the results so make sure that the object is initialised and the DoSearch executed.
		 *
		 * Each key in the array will be the 'score' value (as a string) so it can be merged in with other results and can
		 * then be further sorted using any PHP array sorting functions, so output would be something like this:
		 *
		 * EG: return = array(10, // result count
		 *                    array(
		 *                        "12.345" => array(
		 *                                          0 => [product HTML]
		 *                                          1 => [product HTML]
		 *                                          2 => [product HTML]
		 *                                    ),
		 *                        "2.784" => array(
		 *                                          0 => [product HTML]
		 *                                    ),
		 *                        "6.242" => array(
		 *                                          0 => [product HTML]
		 *                                          1 => [product HTML]
		 *                                   )
		 *                    )
		 *              );
		 *
		 * @access public
		 * @return array An array with two values, first is total number of search results. Other is the search item results AJAX array on success, empty array on error
		 */
		static public function buildSearchResultsAJAX()
		{
			if (!isset($GLOBALS["ISC_CLASS_SEARCH"]) || !is_object($GLOBALS["ISC_CLASS_SEARCH"])) {
				return array(0, array());
			}

			$totalRecords = $GLOBALS["ISC_CLASS_SEARCH"]->GetNumResults("product");

			if ($totalRecords == 0) {
				return array(0, array());
			}

			$results = $GLOBALS["ISC_CLASS_SEARCH"]->GetResults("product");
			$ajaxArray = array();

			if (!array_key_exists("results", $results) || !is_array($results["results"])) {
				return array();
			}

			$products = $results["results"];

			foreach ($products as $product) {
				if (!isset($product["score"])) {
					$product["score"] = 0;
				}

				$GLOBALS["ProductName"] = $product["prodname"];
				$GLOBALS["ProductURL"] = ProdLink($product["prodname"]);
				$GLOBALS['ProductPrice'] = '';
				if (GetConfig('ShowProductPrice') && !$product['prodhideprice']) {
					$GLOBALS['ProductPrice'] = formatProductCatalogPrice($product);
				}

				if(getProductReviewsEnabled()) {
					$ratingURL = $GLOBALS["IMG_PATH"] . "/IcoRating" . (int)$product["prodavgrating"] . ".gif";
					$GLOBALS["ProductRatingImage"] = "<img src=\"" . $ratingURL . "\" class=\"RatingIMG\" />";
				} else {
					$GLOBALS["ProductRatingImage"] = "";
				}

				$GLOBALS["ProductNoImageClassName"] = "";

				if (isset($product["imageid"]) && $product["imageid"] !== "") {
					$image = new ISC_PRODUCT_IMAGE();
					$image->populateFromDatabaseRow($product);
					$productImageSize = $image->getResizedFileDimensions(ISC_PRODUCT_IMAGE_SIZE_TINY, true);
					if ($productImageSize[0] > 70) {
						// ISCFIVEFIVEBETA-89 - cap to 70px wide
						// note: will need to adjust height by proper ratio if we want the height output to html
						$productImageSize[0] = 70;
					}
					$GLOBALS["ProductImage"] = "<img src=\"" . isc_html_escape($image->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_TINY, true)) . "\" alt=\"" . isc_html_escape($product["prodname"]) . "\" title=\"" . isc_html_escape($product["prodname"]) . "\" width=\"" . $productImageSize[0] . "\" />";
				} else {
					$GLOBALS["ProductNoImageClassName"] = "QuickSearchResultNoImage";
					$GLOBALS["ProductImage"] = "<span>" . GetLang("QuickSearchNoImage") . "</span>";
				}

				$sortKey = (string)$product["score"];

				if (!array_key_exists($sortKey, $ajaxArray) || !is_array($ajaxArray[$sortKey])) {
					$ajaxArray[$sortKey] = array();
				}

				$ajaxArray[$sortKey][] = $GLOBALS["ISC_CLASS_TEMPLATE"]->GetSnippet("SearchResultAJAXProduct");
			}

			return array($totalRecords, $ajaxArray);
		}
Example #22
0
	public function update_variation_images()
	{
		// if the column vcimagezoom exists, can assume that images have already been updated and nothing to do here.
		if ($this->ColumnExists('[|PREFIX|]product_variation_combinations', 'vcimagezoom')) {
			return true;
		}

		/**
		* Standardise the naming of columns to be consistent with regular product images
		*/

		// move the vcimage field to vcimagezoom
		$query = 'ALTER TABLE `[|PREFIX|]product_variation_combinations` CHANGE `vcimage` `vcimagezoom` VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL';
		if (!$GLOBALS['ISC_CLASS_DB']->Query($query)) {
			$this->SetError($GLOBALS['ISC_CLASS_DB']->GetErrorMsg());
			return false;
		}

		// move the vcthumb field to vcimagethumb
		$query = 'ALTER TABLE `[|PREFIX|]product_variation_combinations` CHANGE `vcthumb` `vcimagethumb` VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL';
		if (!$GLOBALS['ISC_CLASS_DB']->Query($query)) {
			$this->SetError($GLOBALS['ISC_CLASS_DB']->GetErrorMsg());
			return false;
		}

		// recreate the vcimage field which will hold our source image path
		$query = 'ALTER TABLE `[|PREFIX|]product_variation_combinations` ADD `vcimage` VARCHAR( 100 ) NOT NULL AFTER `vcweight`';
		if (!$GLOBALS['ISC_CLASS_DB']->Query($query)) {
			$this->SetError($GLOBALS['ISC_CLASS_DB']->GetErrorMsg());
			return false;
		}

		// add vcimagestd field to hold the standard size image
		$query = 'ALTER TABLE `[|PREFIX|]product_variation_combinations` ADD `vcimagestd` VARCHAR( 100 ) NOT NULL AFTER `vcimagezoom`';
		if (!$GLOBALS['ISC_CLASS_DB']->Query($query)) {
			$this->SetError($GLOBALS['ISC_CLASS_DB']->GetErrorMsg());
			return false;
		}

		// process the zoom image as the source file and recreate other versions

		// multiple combinations could be using the same image, so we don't need to resize and create multiple versions.
		$query = '
			SELECT
				GROUP_CONCAT(CAST(combinationid AS CHAR)) AS combinations,
				vcimagezoom
			FROM
				[|PREFIX|]product_variation_combinations
			WHERE
				vcimagezoom != ""
			GROUP BY
				vcimagezoom
		';

		$result = $GLOBALS['ISC_CLASS_DB']->Query($query);
		while ($row = $GLOBALS['ISC_CLASS_DB']->Fetch($result)) {
			try {
				$image = new ISC_PRODUCT_IMAGE();
				$image->setSourceFilePath($row['vcimagezoom']);

				$updatedVariation = array(
					'vcimage' 		=> $row['vcimagezoom'],
					'vcimagezoom' 	=> $image->getResizedFilePath(ISC_PRODUCT_IMAGE_SIZE_ZOOM, true, false),
					'vcimagestd' 	=> $image->getResizedFilePath(ISC_PRODUCT_IMAGE_SIZE_STANDARD, true, false),
					'vcimagethumb' 	=> $image->getResizedFilePath(ISC_PRODUCT_IMAGE_SIZE_THUMBNAIL, true, false)
				);

				$GLOBALS['ISC_CLASS_DB']->UpdateQuery('product_variation_combinations', $updatedVariation, 'combinationid IN (' . $row['combinations'] . ')');
			}
			catch (Exception $ex) {
				$this->SetError($ex->__toString());
			}
		}

		return true;
	}
Example #23
0
	/**
	 * Build the HTML for the thumbnail image of a product.
	 *
	 * @todo refactor
	 * @param string The filename of the thumbnail.
	 * @param string The URL that the thumbnail should link to.
	 * @param string The optional target for the link.
	 * @return string The built HTML for the thumbnail.
	 */
	function ImageThumb($imageData, $link='', $target='', $class='')
	{
		$altText = "";

		if(!is_array($imageData)) {
			$thumb = $imageData;
		} else {
			$image = new ISC_PRODUCT_IMAGE;
			$image->populateFromDatabaseRow($imageData);
			$altText = $image->getDescription();

			if(empty($altText) && !empty($imageData['prodname'])) {
				$altText = $imageData['prodname'];
			}

			try {
				$thumb = $image->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_THUMBNAIL, true);
			} catch (Exception $exception) {
				$thumb = '';
			}
			unset($image);
		}

		if(!$thumb) {
			switch(GetConfig('DefaultProductImage')) {
				case 'template':
					$thumb = $GLOBALS['IMG_PATH'].'/ProductDefault.gif';
					break;
				case '':
					$thumb = '';
					break;
				default:
					$thumb = GetConfig('ShopPath').'/'.GetConfig('DefaultProductImage');
			}
		}
		/*
		else {
			$thumbPath = APP_ROOT.'/'.GetConfig('ImageDirectory').'/'.$thumb;
			$thumb = $GLOBALS['ShopPath'].'/'.GetConfig('ImageDirectory').'/'.$thumb;
		}
		*/
		if(!$thumb) {
			return '';
		}

		if($target != '') {
			$target = 'target="'.$target.'"';
		}

		if($class != '') {
			$class = 'class="'.$class.'"';
		}

		$imageThumb = '';
		if($link != '') {
			$imageThumb .= '<a href="'.$link.'" '.$target.' '.$class.'>';
		}

		$imageSize = @getimagesize($thumbPath);

		if(is_array($imageSize) && !empty($imageSize)) {
			$imageThumb .= '<img src="'.$thumb.'" alt="'.$altText.'" ' . $imageSize[3] . ' />';
		}else{
			$imageThumb .= '<img src="'.$thumb.'" alt="'.$altText.'" />';
		}

		if($link != '') {
			$imageThumb .= '</a>';
		}

		return $imageThumb;
	}
Example #24
0
		public function ShowImage()
		{
			if ($this->GetNumImages() == 1) {
				// do no show nav link if there is only 1 image
				$GLOBALS['NavLinkDisplay'] = 'display:none;';
			}

			if($image = $this->GetImage()) {
				// Set product name
				$GLOBALS['ProductName'] = isc_html_escape($this->_prodname);

				// Show we show the "Previous Image" link?
				if($this->GetCurrentImage() == 0 || $this->GetCurrentImage() == 'variation') {
					$GLOBALS['DisablePrevLink'] = "disabled";
				} else {
					$GLOBALS['PrevLink'] = sprintf("%s/productimage.php?product_id=%d&current_image=%d", $GLOBALS['ShopPath'], $this->GetProductId(), $this->GetCurrentImage()-1);
				}

				// Should we show the "Next Image" link?
				if($this->GetNumImages()-1 == $this->GetCurrentImage() || $this->GetCurrentImage() == 'variation') {
					$GLOBALS['DisableNextLink'] = "disabled";
				} else {
					$GLOBALS['NextLink'] = sprintf("%s/productimage.php?product_id=%d&current_image=%d", $GLOBALS['ShopPath'], $this->GetProductId(), $this->GetCurrentImage()+1);
				}

				if($this->GetCurrentImage() == 'variation') {
					$GLOBALS['VariationImage'] = $image;
				}

				$GLOBALS['ProductMaxImageWidth'] = ISC_PRODUCT_IMAGE::getSizeWidth(ISC_PRODUCT_IMAGE_SIZE_ZOOM);
				$GLOBALS['ProductMaxImageHeight'] = ISC_PRODUCT_IMAGE::getSizeHeight(ISC_PRODUCT_IMAGE_SIZE_ZOOM);

				$GLOBALS['ProductMaxTinyWidth'] = ISC_PRODUCT_IMAGE::getSizeWidth(ISC_PRODUCT_IMAGE_SIZE_TINY);
				$GLOBALS['ProductMaxTinyHeight'] = ISC_PRODUCT_IMAGE::getSizeHeight(ISC_PRODUCT_IMAGE_SIZE_TINY);

				$GLOBALS['ProductTinyBoxWidth'] = $GLOBALS['ProductMaxTinyWidth']+4;
				$GLOBALS['ProductTinyBoxHeight'] = $GLOBALS['ProductMaxTinyHeight']+4;

				// a list of images does exist in _prodimages but it's just a list of urls with no sizing information, with the given time frame I have no choice but to re-query the db -ge
				$productImages = ISC_PRODUCT_IMAGE::getProductImagesFromDatabase($this->GetProductId());

				$GLOBALS['TotalImages'] = count($productImages);
				$GLOBALS['ProdImageJavascript'] = '';

				if ($GLOBALS['TotalImages']) {
					$GLOBALS['SNIPPETS']['ProductTinyImages'] = '';
					$GLOBALS['ProductZoomImageURLs'] = array();

					foreach ($productImages as $index => /** @var ISC_PRODUCT_IMAGE */$productImage) {
						$thumbURL = $productImage->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_ZOOM, true);

						$GLOBALS['ProductThumbURL'] = $thumbURL;
						$GLOBALS['ProductThumbIndex'] = $index;
						$GLOBALS['ImageDescription'] = isc_html_escape($productImage->getDescription());

						$GLOBALS['ProdImageJavascript'] .= "ThumbURLs[" . $index . "] = " . isc_json_encode($thumbURL) . ";";
						$GLOBALS['ProdImageJavascript'] .= "ImageDescriptions[" . $index . "]=" . isc_json_encode($GLOBALS['ImageDescription']) . ";";

						$GLOBALS['ProductTinyImageURL'] = $productImage->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_TINY, true);

						$resizedTinyDimension = $productImage->getResizedFileDimensions(ISC_PRODUCT_IMAGE_SIZE_TINY, true);
						$GLOBALS['TinyImageWidth'] = $resizedTinyDimension[ISC_PRODUCT_IMAGE_DIMENSIONS_WIDTH];
						$GLOBALS['TinyImageHeight'] = $resizedTinyDimension[ISC_PRODUCT_IMAGE_DIMENSIONS_HEIGHT];

						$GLOBALS['TinyImageTopPadding'] = floor(($GLOBALS['ProductMaxTinyHeight'] - $GLOBALS['TinyImageHeight']) / 2);

						$GLOBALS['TinyImageClickJavascript'] = "showProductZoomImage(" . $index . ");";
						$GLOBALS['SNIPPETS']['ProductTinyImages'] .= $GLOBALS['ISC_CLASS_TEMPLATE']->GetSnippet("ProductTinyImage");
					}
				}

				$GLOBALS['CurrentImageIndex'] = $this->GetCurrentImage();
				$GLOBALS['ImageFile'] = $image;
				$GLOBALS['ISC_CLASS_TEMPLATE']->SetTemplate("productimage");
				$GLOBALS['ISC_CLASS_TEMPLATE']->ParseTemplate();
			}
		}
Example #25
0
	public function deletePosthook($productId, $node)
	{
		ISC_PRODUCT_IMAGE::deleteOrphanedProductImages();
		ISC_PRODUCT_VIEWS::onProductDelete($productId);
		return true;
	}