Example #1
0
		private function _SetImageData()
		{
			$this->_prodid = (int)$_GET['product_id'];

			// Load the product name
			$query = sprintf("select prodname from [|PREFIX|]products where productid='%d'", $GLOBALS['ISC_CLASS_DB']->Quote($this->GetProductId()));
			$result = $GLOBALS['ISC_CLASS_DB']->Query($query);
			$this->_prodname = $GLOBALS['ISC_CLASS_DB']->FetchOne($result, "prodname");

			// Are we showing the image for a particular variation?
			if(isset($_GET['variation_id'])) {
				$this->_variationid = (int)$_GET['variation_id'];
				$query = "SELECT vcimage, vcimagezoom FROM [|PREFIX|]product_variation_combinations WHERE vcproductid='".$this->_prodid."' AND combinationid='".$this->_variationid."'";
				$result = $GLOBALS['ISC_CLASS_DB']->Query($query);
				if (!$variation = $GLOBALS['ISC_CLASS_DB']->Fetch($result)) {
					// Invalid variation
					exit;
				}

				if ($variation['vcimage'] && $variation['vcimagezoom']) {
					// use the product image library to get the url which will trigger a resize if necessary
					try {
						$productImage = new ISC_PRODUCT_IMAGE;
						$productImage->setSourceFilePath($variation['vcimage']);
						$productImage->setResizedFilePath(ISC_PRODUCT_IMAGE_SIZE_ZOOM, $variation['vcimagezoom']);
						$this->_variationImage = $productImage->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_ZOOM, true, false);
					} catch (Exception $exception) {
						// nothing
					}
				}
			}
			// Otherwise, just load general images for a product
			//else {
				// Load the images into an array
				$productImages = ISC_PRODUCT_IMAGE::getProductImagesFromDatabase($this->GetProductId());
				if(!empty($productImages)) {
					$i = 0;
					foreach ($productImages as $productImage) {
						$imgDesc = '';
						$zoomImg = '';
						$tinyImg = '';
						$thumbImg = '';

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


						try{
							$thumbImg = $productImage->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_STANDARD, true);
							//$GLOBALS['ProductThumbURL'] = $thumbURL;
						} catch (Exception $exception) {
						}


						// if both standard image and zoom image not exist, go to the next image.
						if($thumbImg == '' && $zoomImg == '') {
							continue;
						}


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

						$imgDesc = $productImage->getDescription();
						if ($imgDesc == '') {
							$imgIndex= $i+1;
							$imgDesc = GetLang("Image")." ".$imgIndex;
						}

						if($zoomImg!= '' ) {
							$this->_prodimages['zoom'][] = $zoomImg;
						//use standard image if zoom image not exist.
						} else {
							$this->_prodimages['zoom'][] = $thumbImg;
						}
						$this->_prodimages['tiny'][] = $tinyImg;

						$this->_prodImagesDescriptions[] = $imgDesc;
						$i++;
					}
				//}
				// How many images are there?
				$this->_prodnumimages = count($this->_prodimages['zoom']);
			}
			// Which image should we show?
			if(isset($_GET['current_image'])) {
				$this->_prodcurrentimage = (int)$_GET['current_image'];
			} elseif(isset($_GET['variation_id'])) {
				$this->_prodcurrentimage = 'variation';
			}
		}
Example #2
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 .= ' » ';
					}
					$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 #3
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 #4
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 #5
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 '';
		}
	}
Example #6
0
		/**
		* Gets an array of formatted details for a specific combination row such as pricing, weight, images
		*
		* @param array Database row of combination information
		* @param int The customer group to use to determine the final product price (used when getting variation details from back end quote system)
		* @return array The formatted combination details
		*/
		public function GetCombinationDetails($combination, $customerGroupId = null)
		{
			$thumb = '';
			$image = '';

			$priceOptions = array(
				'variationModifier'		=> $combination['vcpricediff'],
				'variationAdjustment'	=> $combination['vcprice'],
			);

			if (!is_null($customerGroupId)) {
				$priceOptions['customerGroup'] = $customerGroupId;
			}

			if($this->GetProductCallForPricingLabel()) {
				$variationPrice = $GLOBALS['ISC_CLASS_TEMPLATE']->ParseGL($this->GetProductCallForPricingLabel());
			}
			else {
				$variationPrice = formatProductDetailsPrice($this->_product, $priceOptions);
			}

			$calculatedPrice = calculateFinalProductPrice($this->_product, $this->_prodcalculatedprice, $priceOptions);
			$calculatedPrice = getClass('ISC_TAX')->getPrice(
				$calculatedPrice,
				$this->_product['tax_class_id'],
				getConfig('taxDefaultTaxDisplayProducts')
			);

			$variationSaveAmount = '';
			if($this->_prodretailprice > 0) {
				$rrp = calculateFinalProductPrice($this->_product, $this->_prodretailprice, $priceOptions);
				$rrp = getClass('ISC_TAX')->getPrice(
					$rrp,
					$this->_product['tax_class_id'],
					getConfig('taxDefaultTaxDisplayProducts')
				);

				$youSave = $rrp - $calculatedPrice;
				if($youSave > 0) {
					$variationSaveAmount = CurrencyConvertFormatPrice($youSave);
				}
			}

			$variationWeight = FormatWeight(CalcProductVariationWeight($this->_prodweight, $combination['vcweightdiff'], $combination['vcweight']), true);

			// use the product image class for automatic resizing
			$productImage = new ISC_PRODUCT_IMAGE;
			if ($combination['vcimage']) {
				$productImage->setSourceFilePath($combination['vcimage']);

				if ($combination['vcimagestd']) {
					$productImage->setResizedFilePath(ISC_PRODUCT_IMAGE_SIZE_STANDARD, $combination['vcimagestd']);
					$thumb = $productImage->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_STANDARD, true, false);
				}

				if ($combination['vcimagezoom']) {
					//check if zoom image is large enough for image zoomer
					try {
						$productImage->setResizedFilePath(ISC_PRODUCT_IMAGE_SIZE_ZOOM, $combination['vcimagezoom']);
						list($zoomWidth, $zoomHeight) = $productImage->getResizedFileDimensions(ISC_PRODUCT_IMAGE_SIZE_ZOOM, true, false);
						if ($zoomWidth >= ISC_PRODUCT_IMAGE_MIN_ZOOM_WIDTH || $zoomHeight >= ISC_PRODUCT_IMAGE_MIN_ZOOM_HEIGHT) {
							$image = $productImage->getResizedUrl(ISC_PRODUCT_IMAGE_SIZE_ZOOM, true, false);
						}
					} catch (Exception $exception) {
						// do nothing, will result in returning blank string, which is fine
					}
				}
			}

			// Tracking inventory on a product variation level
			if($this->_prodinvtrack == 2) {
				$stock = $combination['vcstock'];
			}
			else {
				$stock = $this->_prodcurrentinv;
			}

			if($stock <= 0 && $this->_prodinvtrack != 0) {
				$instock = false;
			}
			else {
				$instock = true;
			}

			$return = array(
				'combinationid'			=> $combination['combinationid'],
				'saveAmount'			=> $variationSaveAmount,
				'price'					=> $variationPrice,
				'unformattedPrice'      => formatPrice($calculatedPrice, false, false),
				'sku'					=> $combination['vcsku'],
				'weight'				=> $variationWeight,
				'thumb'					=> $thumb,
				'image'					=> $image,
				'instock'				=> $instock
			);

			if (GetConfig('ShowInventory') == 1 && (!$this->IsPreOrder() || GetConfig('ShowPreOrderInventory') == 1)) {
				$return['stock'] = $stock;
			}
			return $return;
		}
		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 #8
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;
	}