主要实现了把提交的文章中如<img src="XXXX.jpg" XXXX/>的图片抓回服务器保存为文章的附件。
并且可以本地上传的图片附件一样进行管理。
修改在sablogx 1.6 1.6 Build 20071004下通过测试
ps:如果内容中有很多张引用的远程图片是同一个地址的,则只保存一份,节约服务器空间。嘿嘿。
并且会把<img src="XXXX.jpg" XXXX/>的内容替换成相应附件id的sablog表述,如
[attach=id]
废话不说了,看代码吧。
加入article.php中的代码,因为有修改文章和新增文章两种,这里我只是简单的同样代码复制两份来解决。其实也可以抽出来做个单独的php吧。
//保存远程图片
// code by suddy
// Thanks for angel,喜悦国际村&xd888
$attachs = $attach_data = array();//由于可能远程未被触发,所以要先声明$attachs数组
if(!empty($saveremoteing)){
$gd_version = gd_version();
$content = stripslashes($content);
$img_array = array();
//获取输入内容中的远程图片部分
$ismatch=preg_match_all("/(src|SRC)=[\"|'| ]{0,}(http:\/\/(.*)\.(gif|jpg|jpeg|bmp|png))/isU",$content,$img_array);
if($ismatch!=0){
set_time_limit(0);
$imgUrl = $options['attachments_dir'];
$yearMonth = strftime("%Y%m",time());
$imgPath = SABLOG_ROOT.$imgUrl."/date_".$yearMonth;
$milliSecond = strftime("%H%M%S",time());
if(!is_dir($imgPath))
@mkdir($imgPath,0777);
$fnamehash = md5(uniqid(microtime()));
$oldvalue="suddy";//赋初值是为了后续判断中strpos函数不会在第0个位置找到而返回0的时候被解释成false
foreach($img_array[2] as $key =>$value) {
$value = trim($value);
//判断是否是重复图片,如果重复,只保存一份
if(strpos($oldvalue,$value)==false){
$oldvalue=$oldvalue.$value;
$get_file = @file_get_contents($value);
if($get_file) {
//获取远程图片文件名
preg_match_all("(((=|\)|\(|&|\^|%|$|!|@|\+|-|\w)*)\.(gif|jpg|jpeg|bmp|png))",$value,$fileName);
$fileName=addslashes(strtolower($fileName[0][0]));
//获取远程图片大小
$fileSize = getRemoteFileSize($value);
//因为实在不清楚filetype要怎么获取,手工构造了,大大们多多指点
$fileType="";
if(preg_match_all("(jpg)",$fileName,$typetemp))
$fileType="image/jpg";
if(preg_match_all("(jpeg)",$fileName,$typetemp))
$fileType="image/jpeg";
if(preg_match_all("(gif)",$fileName,$typetemp))
$fileType="image/gif";
if(preg_match_all("(png)",$fileName,$typetemp))
$fileType="image/png";
if(preg_match_all("(bmp)",$fileName,$typetemp))
$fileType="image/bmp";
//构造filepath字段,该字段以$options['attachments_dir']为根
$ext=split("(\.)",$fileName);
$ext=strtolower($ext[1]);
if($ext=="jpg")
$ext="jpg";
if($ext=="jpeg")
$ext="jpeg";
if($ext=="gif")
$ext="gif";
if($ext=="bmp")
$ext="bmp";
if($ext=="png")
$ext="png";
if($ext!="jpg"&&$ext!="jpeg"&&$ext!="gif"&&$ext!="bmp"&&$ext!="png")
$ext="";
$filePath="/date_".$yearMonth."/".$fnamehash.".".$ext;
//
$rndFileName = $imgPath."/".$fnamehash.".".$ext;
$fileurl = $cache_settings['siteurl'].$imgUrl."/date_".$yearMonth."/".$fnamehash.".".$ext;
$fp = @fopen($rndFileName,"w");
@fwrite($fp,$get_file);
@fclose($fp);
// 判断是否使用缩略图
if($imginfo=@getimagesize($value)){
if ($options['attachments_thumbs'] && $gd_version) {
$size = explode('x', strtolower($options['attachments_thumbs_size']));
$attachsubdir="/date_".$yearMonth."/";
if (($imginfo[0] > $size[0] || $imginfo[1] > $size[1]) && $fileSize < 2048000) {
$attach_thumb = array(
'filepath' => $rndFileName,
'filename' => $fnamehash,
'extension' => $ext,
'attachsubdir' => $attachsubdir,
'thumbswidth' => $size[0],
'thumbsheight' => $size[1],
);
$thumb_data = generate_thumbnail($attach_thumb);
$attach_data['thumbwidth'] = $thumb_data['thumbwidth'];
$attach_data['thumbheight'] = $thumb_data['thumbheight'];
$attach_data['thumbfilepath'] = $attachsubdir.$thumb_data['thumbfilepath'];
}
}
}//缩略图处理完毕
// 把文件信息插入数据库
$isimage=1;
$DB->query("INSERT INTO {$db_prefix}attachments (articleid,filename,filesize,filetype,filepath,dateline,downloads,isimage,thumb_filepath,thumb_width,thumb_height) VALUES ('".$articleid."', '".$fileName."', '".$fileSize."', '".addslashes($fileType)."', '".addslashes($filePath)."', '$timestamp', '0', '1', '".$attach_data['thumbfilepath']."', '".$attach_data['thumbwidth']."','".$attach_data['thumbheight']."')");
$aidtmp = $DB->insert_id();
$attachs[$aidtmp] = array(
'attachmentid' => $aidtmp,
'dateline' => $timestamp,
'filename' => addslashes($fileName),
'filetype' => addslashes($fileType),
'filepath' => addslashes($filePath),
'filesize' => addslashes($fileSize),
'downloads' => 0,
'thumb_filepath' => $attach_data['thumbfilepath'],
'thumb_width' => $attach_data['thumbwidth'],
'thumb_height' => $attach_data['thumbheight'],
'isimage' => $isimage
);
unset($isimage);
unset($attach_data);
//$s=addslashes(serialize($attachs));
//$searcharray[] = '[localfile='.$localid[$key].']';
//$searcharray[] = '[localfile='.$localid[$key].']';
//$replacearray[] = '[attach='.$aidtmp.']';
//$tobereplace=addslashes($tobereplace)
$content = ereg_replace("<(img|IMG)[^>]*(SRC|src)(\s)*=(\s)*[\"|'| ]".$value."[\"|'| ][^>]*>","[attach=".$aidtmp."]",$content);
}//一个图片附件处理完毕
}
}
unset($oldvalue);
}
//$content = addslashes($content);
}// 保存远程图片完毕
然后是uploadfiles.php中的一个小修改,去掉了$attachs的定义来让外部的$attachs数组成员直接传入使用
//$attachments = $attachs = $attach_data = array();
改为
$attachments = $attach_data = array();
在include下的func_attachment.php中加入了一个自定义函数来获取远程图片大小
function getRemoteFileSize($url){
$url = parse_url($url);
if($fp = @fsockopen($url['host'],empty($url['port'])?80:$url['port'],$error)){
fputs($fp,"GET ".(empty($url['path'])?'/':$url['path'])." HTTP/1.1");
fputs($fp,"Host:$url[host]");
while(!feof($fp)){
$tmp = fgets($fp);
if(trim($tmp) == ''){
break;
}else if(preg_match('/Content-Length:(.*)/si',$tmp,$arr)){
return trim($arr[1]);
}
}
return null;
}else{
return null;
}
}
最后就是在后台模板文件templates\admin\article.php 里加入选择保存远程图片的按钮
<input name="saveremoteing" type="checkbox" value="1" $saveremoteing>
保存远程图片<br />
附上几张使用图片
附件是所有有修改的文件。如果没修改admin目录的话直接覆盖就ok了。
ps: 使用保存远程图片的时候会比较慢一点,有大大知道如何优化的话欢迎指点。
suddy
2007-12-23 于杭州
2008-06-22
感谢tong,根据建议修复了同名覆盖的bug。重新更新了附件



#1