sablog远程图片本地化功能hack

主要实现了把提交的文章中如<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 />

附上几张使用图片

 

大小: 78.81 K
尺寸: 400 x 220
浏览: 121 次
点击打开新窗口浏览全图

 

大小: 97.26 K
尺寸: 400 x 350
浏览: 88 次
点击打开新窗口浏览全图

大小: 60.55 K
尺寸: 400 x 284
浏览: 113 次
点击打开新窗口浏览全图

附件是所有有修改的文件。如果没修改admin目录的话直接覆盖就ok了。

ps: 使用保存远程图片的时候会比较慢一点,有大大知道如何优化的话欢迎指点。

suddy

2007-12-23 于杭州

 

2008-06-22
感谢tong,根据建议修复了同名覆盖的bug。重新更新了附件

附件: sablogx1.6remotepic_patch20080622.rar (17.52 K, 下载次数:132)

« 上一篇 | 下一篇 »

11条记录访客评论

自己顶下,折腾了一天多,终于全部搞定了,虽然效率还有点遗憾,不过功能大致ok了。
收工,睡觉。

Post by ╰☆往事如风 on 2007, December 23, 1:24 AM 引用此文发表评论 #1

强!强!

Post by niu on 2007, December 26, 9:41 PM 引用此文发表评论 #2

解决下效率问题....

Post by v2exe on 2007, December 28, 2:03 AM 引用此文发表评论 #3

引用 v2exe 说过的话:
解决下效率问题....

不知道楼上的朋友指的是怎么样的效率问题?

Post by ╰☆往事如风 on 2008, January 1, 8:59 PM 引用此文发表评论 #4

这个功能不知道 是否对本地word里面的图片直接 copy过去 是否生效?

Post by doc on 2008, May 3, 8:37 PM 引用此文发表评论 #5

请问是如何判断重复图片的?
我在远程保存的时候几幅不同的图片确存成了同一副图片

Post by tong on 2008, June 19, 3:01 AM 引用此文发表评论 #6

$fnamehash = md5(uniqid(microtime()));
原因就是上面那个赋值语句应该在foreach($img_array[2] as $key =>$value)循环中执行,否则会发生同名文件覆盖,产生只有抓取到一个文件的现象

Post by tong on 2008, June 19, 5:02 AM 引用此文发表评论 #7

引用 tong 说过的话:
$fnamehash = md5(uniqid(microtime()));
原因就是上面那个赋值语句应该在foreach($img_array[2] as $key =>$value)循环中执行,否则会发生同名文件覆盖,产生只有抓取到一个文件的现象

thanks you,
之前没考虑到这种,sorry。
现在已经修改。

Post by ╰☆往事如风 on 2008, June 22, 12:01 PM 引用此文发表评论 #8

这个图片地址多一个/在attachments前面
http://suddymail.org//attachments/date_200712/320f9097e8dae12d5ed6774a31d63ffe.jpg

Post by 相约冬天 on 2009, January 13, 10:34 AM 引用此文发表评论 #9

我去试试~~~

Post by 娱乐网 on 2010, January 28, 2:00 PM 引用此文发表评论 #10

这个支持最新版的吗

Post by saex3 on 2012, November 8, 9:43 AM 引用此文发表评论 #11


发表评论

评论内容 (必填):