/** * 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; }
/** * 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; }