示例#1
0
	/**
	 * Return a URL content or write its output to file if a destination is provided.
	 * 
	 * Note, this implementation require the PHP CURL extension installed.
	 * 
	 * @param string $url Content source
	 * @param string $destination [optional] File destination where output should be written
	 * @return mixed URL content or boolean true if a destination is provided
	 */
	public static function read($url,$destination=null){
		if(!function_exists('curl_init')){
			throw new Exception('PHP CURL Extension Required');
		}
		$ch = curl_init($url);
		curl_setopt($ch,CURLOPT_HEADER,false);
		if($destination){
			PurFile::mkdir(dirname($destination));
			if(file_exists($destination)) PurFile::delete($destination);
			$fp = fopen($destination,'w');
			curl_setopt($ch,CURLOPT_FILE,$fp);
		}else{
			curl_setopt($ch,CURLOPT_RETURNTRANSFER,1) ;
		}
		if(($data = curl_exec($ch))===false){
			throw new Exception('Failed to download url: "'.$url.'"');
		}
		$header = curl_getinfo($ch);
		curl_close($ch);
		if($destination){
			fclose($fp);
		}
		if($header['http_code']!=self::SUCCESS_OK){
			if($destination){
				PurFile::delete($destination);
			}
			throw new Exception('Download Failed: "'.constant('PurHTTP::'.'CODE_'.$header['http_code']).'" ('.$header['http_code'].')');
		}
		return $data;
	}
示例#2
0
	/**
	 * Create an image resource base on the provided file path.
	 * 
	 * Options may include:
	 * - *width*: Canvas width of the generated image or resource; "100" and "80+top" (with top defined as 20) for 100 pixels
	 * - *height*: Canvas height of the generated image or resource; "50" and "25+top" (with top defined as 20) for 75 pixels
	 * - *top*: Offset from the top of the source in pixel
	 * - *left*: Offset from the left of the source in pixel
	 * - *bottom*: Offset from the bottom of the source in pixel
	 * - *right*: Offset from the right of the source in pixel
	 * - *temp_dir*: Path to temporary working directory
	 * - *gm_convert*: Path to the gm convert utility (used for psd images, usually "gm convert" or "convert")
	 * 
	 * Create a new transparent resource of 100x75 pixels:
	 * * PurImage::resource(array('width'=>100,'height'=>75));
	 * 
	 * Create a resource from a psd file (with "gm" available in your path as "gm convert...")
	 * * PurImage::resource('path/to/image.psd');
	 * 
	 * Create a resource from a psd file (with "gm" not available but installed)
	 * * PurImage::resource('path/to/image.psd',array('gm_convert'=>'/usr/bin/gm convert'));
	 * 
	 * @return resource Resource associated to the file path
	 * @param mixed $source File path referencing an image or null to create a transparent resource
	 * @param array $options[optional] Configuration array
	 */
	public static function resource($source=null,array $options=array()){
		if(is_array($source)){
			$options = $source;
			$source = null;
		}
		if(empty($source)){
			if(empty($options['width'])||empty($options['height'])){
				throw new InvalidArgumentException('Missing Options: width and height required when creating a new resource');
			}
			$resource = imagecreatetruecolor($options['width'],$options['height']);
			imagesavealpha($resource, true);
			imagefill($resource,0,0,imagecolorallocatealpha($resource,255,255,255,127));
			return $resource;
		}else if(is_string($source)){
			if(!is_readable($source)) throw new InvalidArgumentException('Invalid Source Path: '.PurLang::toString($source).'');
			$type = exif_imagetype($source);
			switch($type){
				case IMAGETYPE_GIF:
					$source = imagecreatefromgif($source);
					break;
				case IMAGETYPE_JPEG:
					$source = imagecreatefromjpeg($source);
					break;
				case IMAGETYPE_PNG:
					$source = imagecreatefrompng($source);
					break;
				case IMAGETYPE_SWF:
					break;
				case IMAGETYPE_PSD:
					if(!isset($options['gm_convert'])){
						throw new Exception('Missing Option For PSD Image Type: gm_convert');
					}
					$temp = (isset($options['temp_dir'])?$options['temp_dir']:sys_get_temp_dir()).'/'.uniqid();
					$cmd = $options['gm_convert'].' -flatten '.escapeshellarg($source).' '.escapeshellarg('png:'.$temp);
					exec($cmd);
					$source = imagecreatefrompng($temp);
					PurFile::delete($temp);
					break;
				case IMAGETYPE_BMP:
					break;
				case IMAGETYPE_TIFF_II:
					break;
				case IMAGETYPE_TIFF_MM:
					break;
				case IMAGETYPE_JPC:
					break;
				case IMAGETYPE_JP2:
					break;
				case IMAGETYPE_JPX:
					break;
				case IMAGETYPE_JB2:
					break;
				case IMAGETYPE_SWC:
					break;
				case IMAGETYPE_IFF:
					break;
				case IMAGETYPE_WBMP:
					$source = imagecreatefromwbmp($source);
					break;
				case IMAGETYPE_XBM:
					$source = imagecreatefromxbm($source);
					break;
			}
			$created = true;
		}else if(is_resource($source)){
			$created = false;
		}else{
			throw new InvalidArgumentException('Invalid Source: empty, string or resource accepted');
		}
//		width
//		height
//		top
//		left
//		bottom
//		right
//		imagecopyresampled($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h)
		$sourceWidth = imagesx($source);
		$sourceHeight = imagesy($source);
		// Sanitize width and height
		if(!empty($options['width'])&&!empty($options['height'])){
			if($options['width']!=$sourceWidth&&$options['height']!=$sourceHeight){
				$resized = true;
			}
		}else if(!empty($options['width'])&&$options['width']!=$sourceWidth){
			$resized = true;
			$options['height'] = $sourceHeight*$options['width']/$sourceWidth;
		}else if(!empty($options['height'])&&$options['height']!=$sourceHeight){
			$resized = true;
			$options['width'] = $sourceWidth*$options['height']/$sourceHeight;
		}
		// Sanitize resize as an array with width and height keys
		if(!empty($options['resize'])){
			$resized = true;
			switch(gettype($options['resize'])){
				case 'string':
					$options['resize'] = explode('x',$options['resize']);
				case 'array':
					if(empty($options['resize'])||count($options['resize'])>2){
						throw new Exception('Invalid "resize": '.PurLang::toString($options['resize']));
					}
					// Deal with map
					if(!empty($options['resize']['width'])){
						$width = $options['resize']['width'];
					}
					if(!empty($options['resize']['height'])){
						$height = $options['resize']['height'];
					}
					// Deal with index
					if(!isset($width)){
						$width = array_shift($options['resize']);
					}
					if(!isset($height)){
						$height = array_shift($options['resize']);
					}
					// Deal with *
					if($width=='*') $width = null;
					if($height=='*') $height = null;
					// Rebuild resize
					$options['resize']['width'] = $width;
					unset($width);
					$options['resize']['height'] = $height;
					unset($height);
					if(empty($options['resize']['width'])){
						$options['resize']['width'] = $sourceWidth*$options['resize']['height']/$sourceHeight;
					}else if(empty($options['resize']['height'])){
						$options['resize']['height'] = $sourceHeight*$options['resize']['width']/$sourceWidth;
					}
					break;
				default:
					throw new Exception('Invalid "resize": '.PurLang::toString($options['resize']));
			}
		}else{
			$options['resize'] = array('width'=>$sourceWidth,'height'=>$sourceHeight);
		}
		if(isset($resized)){
			$destination = self::resource(null,$options);
			imagecopyresampled($destination,$source,0,0,0,0,
				$options['resize']['width'],$options['resize']['height'],
				$sourceWidth,$sourceHeight);
			if($created){
				imagedestroy($source);
			}
			$source = $destination;
		}
		return $source;
	}