Example #1
0
	/**
	* Processor for importing an image via external URL
	*
	* @param int|string $productId Id of a product to import images to, or hash of a product being created if $hash is true
	* @param array $urls A list of image urls to import
	* @param array $images By reference blank array to be populated with successful images
	* @param array $errors By reference blank array to be populated with errors - each element may be a string or an array(url, error)
	* @param bool $hash If true, $productId will be treated as a product hash
	* @param bool $generateImages If true, when importing, will attempt to generate thumbnail images -- may not be desirable if importing many images at once
	*/
	public function importImagesFromUrls($productId, $urls, &$images, &$errors, $hash = false, $generateImages = true)
	{
		foreach ($urls as $originalUrl) {
			$url = $originalUrl;
			if (!preg_match('#^[a-zA-Z0-9\.]+://#i', $url)) {
				// no scheme provided in the url, assume http
				$url = 'http://' . $url;
			}

			$urlInfo = @parse_url($url);

			if (!$urlInfo) {
				$errors[] = array($originalUrl, sprintf(GetLang('ProductImageInvalidUrl'), $originalUrl));
				continue;
			}

			if ($urlInfo['scheme'] != 'http' && $urlInfo['scheme'] != 'https') {
				$errors[] = array($originalUrl, sprintf(GetLang('ProductImageHttpOnly'), $originalUrl));
				continue;
			}

			$response = PostToRemoteFileAndGetResponse($url, '', 90, $ptrfError);

			if (!$response) {
				// show error with details from PostToRemoteFileAndGetResponse

				switch ($ptrfError) {
					case ISC_REMOTEFILE_ERROR_TIMEOUT:
						$error = GetLang('ProductImageCouldNotBeDownloadedTimeout');
						break;

					case ISC_REMOTEFILE_ERROR_HTTPERROR:
						$error = GetLang('ProductImageCouldNotBeDownloadedHttpError');
						break;

					case ISC_REMOTEFILE_ERROR_EMPTY:
						$error = GetLang('ProductImageCouldNotBeDownloadedEmpty');
						break;

					case ISC_REMOTEFILE_ERROR_DNSFAIL:
						$error = GetLang('ProductImageCouldNotBeDownloadedDns');
						break;

					default:
						$error = sprintf(GetLang('ProductImageCouldNotBeDownloadedOther'), $ptrfError);
						break;
				}
				$errors[] = array($originalUrl, $error);
				continue;
			}

			// to work correctly with the product image 'import' process the image must be a file, so save it to the cache directory temporarily
			while (true) {
				// we can name it .tmp because the extension will be corrected after the image type is detected
				$temporaryPath = ISC_CACHE_DIRECTORY . 'productimage_' . ISC_PRODUCT_IMAGE::randomString(16) . '.tmp';

				if (!file_exists($temporaryPath)) {
					break;
				}
			}

			$fh = @fopen($temporaryPath, 'wb');
			if (!$fh) {
				$errors[] = array($originalUrl, GetLang('ProductImageCacheWriteError'));
				continue;
			}

			if (!@fwrite($fh, $response)) {
				$errors[] = array($originalUrl, GetLang('ProductImageCacheWriteError'));
				@fclose($fh);
				continue;
			}

			@fclose($fh);

			// determine original filename based on request path
			$originalFilename = @$urlInfo['path'];
			if ($originalFilename) {
				$pathInfo = pathinfo($urlInfo['path']);
			}

			if ($originalFilename && $pathInfo['basename']) {
				$originalFilename = $pathInfo['basename'];
			} else {
				// if no original filename was specified (e.g.: the image was the result of a script like http://www.example.com/) then generate a random name for it
				// don't need an extension because importImage will add the correct one for the type of image it is
				$originalFilename = 'image' . ISC_PRODUCT_IMAGE::randomString(3);
			}

			try {
				$image = ISC_PRODUCT_IMAGE::importImage($temporaryPath, $originalFilename, $productId, $hash, true, $generateImages);
			} catch (ISC_PRODUCT_IMAGE_IMPORT_INVALIDIMAGEFILE_EXCEPTION $exception) {
				$errors[] = array($originalUrl, $exception->getMessage() . ' ' . GetLang('ProductImageInvalidFileFromWeb'));
				@unlink($temporaryPath);
				continue;
			} catch (ISC_PRODUCT_IMAGE_IMPORT_EXCEPTION $exception) {
				// these exceptions should have language-powered messages so are safe to return to the user
				$errors[] = array($originalUrl, $exception->getMessage());
				@unlink($temporaryPath);
				continue;
			} catch (Exception $exception) {
				// other unknown error
				$errors[] = array($originalUrl, GetLang('ProductImageProcessUnknownError'));
				@unlink($temporaryPath);
				continue;
			}

			// all done, add to list of successful images
			$images[] = $image;
		}
	}