UEditor修改之移植SAE

开发一个博客显然离不开一个给力的编辑器,虽然我手痒写了个博客,但是写一个编辑器还是饶了我吧。鉴于百度的UEditor功能强大,可定制,文档 全,所以就决定是UEditor了。但我最终是要把博客架在新浪的SAE上,而新浪把本地文件的IO操作禁止了,使得UEdiotr的附件、图片上传和在 线涂鸦功能都不可用了。好在新浪提供了Storage来支持文件上传,下面我们就利用SAE的Storage对UEditor进行简单的hack。

   文件上传修改

   首先我们在Storage中创建一个名为"upload"的domain。

   我用的UEditor版本是最新的1.2.3.0 PHP版本,在这个版本中,官方提供的PHP上传功能都统一通过调用 ueditor/php/Uploader.class.php 里的Uploader来实现,这样就更好改了。

   在构造函数中我们看到upFile这个函数被调用来实现上传。首先,我们解决普通文件的上传,注意到upFile里面的这部分代码:

$this->fullName = $this->getFolder() . '/' . $this->getName();
if ( $this->stateInfo == $this->stateMap[ 0 ] ) {
    if (!move_uploaded_file($file[ "tmp_name" ],$this->fullName)) {
        $this->stateInfo = $this->getStateInfo( "MOVE" );
    }
}

   嗯,显然move_upload_file是不能用了,SAE提供了SaeStorage这个类来执行用户文件的存储管理,说明文档戳这里

   把代码改成下面这个样子:

$this->fullName = $this->getFolder() . '/' . $this->getName();
if ( $this->stateInfo == $this->stateMap[ 0 ] ) {
    if(!defined('SAE_TMP_PATH')){
        if ( !move_uploaded_file( $file[ "tmp_name" ] , $this->fullName ) ) {
            $this->stateInfo = $this->getStateInfo( "MOVE" );
        }
    }
    else{
        $st=new SaeStorage();
        $url=$st->upload('upload',$this->fullName, $file[ "tmp_name" ]);
        if(!$url){
            $this->stateInfo = $this->getStateInfo( "MOVE" );
        }
        else{
            $this->fullName=$url;
        }
    }
}

   SAE_TMP_PATH是SAE平台上自动定义的常量,我们用它来判定是否是在SAE上(因为还要兼容其他开发环境),如果在SAE上,生成一个 SaeStorage对象,调用upload这个API,第一个参数是在SAE的Storage里创建的Domain,第二个参数是保存的文件名(可以包 含目录,如果目录不存在,Storage会自动创建),第三个参数则是文件的临时名。当图片上传成功后会返回图片的URL,我们直接 令$this->fullName=$url;这样程序就能返回图片的完整地址给UEditor了。但是好像还有点问题。。。

   上面代码的第一行调用了getFolder,代码如下:

private function getFolder()
{
    $pathStr = $this->config[ "savePath" ];
    if ( strrchr( $pathStr , "/" ) != "/" ) {
        $pathStr .= "/";
    }
    $pathStr .= date( "Ymd" );
    if ( !file_exists( $pathStr ) ) {
        if ( !mkdir( $pathStr , 0777 , true ) ) {
        return false;
        }
    }
    return $pathStr;
}

   似乎mkdir在SAE上不能用,反正Storage会自动帮我们创建目录,所以把这部分搞掉:

private function getFolder()
{
    $pathStr = $this->config[ "savePath" ];
    if ( strrchr( $pathStr , "/" ) != "/" ) {
        $pathStr .= "/";
    }
    $pathStr .= date( "Ymd" );
    if(!defined('SAE_TMP_PATH'))
    {
        if ( !file_exists( $pathStr ) ) {
            if ( !mkdir( $pathStr , 0777 , true ) ) {
                return false;
            }
        }
    }
    return $pathStr;
}

   现在我们传个文档试试,文档成功地传上去了,在Storage里面也能看到上传的文件,但是在编辑器里面无法下载却裂了。看看链接的地址,原来 UEditor给我们的地址自动加上了修正地址。在editor_config.js中把所有的图片修正地址都改成""(本地测试的时候记得把URL改成 绝对路径)清除缓存刷新,重试,成功。

   文件上传的修改完成。

   在线涂鸦修改

   由于在线涂鸦也需要保存图片到本地,所以这部分也要改一下。在线涂鸦的处理页面是scrawlUp.php,里面同样调用了调用Uploader来处理 文件的上传,不同的是,涂鸦上传采用了base64编码模式,Uploader调用base64ToImage来完成图片的保存。打开 Uploader.class.php,定位到下面的代码:

/**
* 处理base64编码的图片上传
* @param $base64Data
* @return mixed
*/
private function base64ToImage( $base64Data )
{
    $img = base64_decode( $base64Data );
    $this->fileName = time() . rand( 1 , 10000 ) . ".png";
    $this->fullName = $this->getFolder() . '/' . $this->fileName;
    if ( !file_put_contents( $this->fullName , $img ) ) {
        $this->stateInfo = $this->getStateInfo( "IO" );
        return;
    }
    $this->oriName = "";
    $this->fileSize = strlen( $img );
    $this->fileType = ".png";
}

   file_put_content是不能用了,Storage提供了write这个API,改成下面的代码:

private function base64ToImage( $base64Data )
{
    $img = base64_decode( $base64Data );
    $this->fileName = "img".time() . rand( 1 , 10000 ) . ".png";
    $this->fullName = $this->getFolder() . '/' . $this->fileName;
    if(!defined('SAE_TMP_PATH')){
        if ( !file_put_contents( $this->fullName , $img ) ) {
            $this->stateInfo = $this->getStateInfo( "IO" );
            return;
        }
    }
    else{
        $st=new SaeStorage(SAE_ACCESSKEY,SAE_SECRETKEY);
        $url=$st->write('upload',$this->fullName,$img);
        if(!$url){
        $this->stateInfo = $this->getStateInfo( "IO" );
        return;
    }
        else{
        $this->fullName=$url;
        }
    }
    $this->oriName = "";
    $this->fileSize = strlen( $img );
    $this->fileType = ".png";
}

   在线涂鸦部分的代码修改完成。

   图片管理

   由于本地图片上传和附件上传方式一样,所以修改完附件上传代码,图片上传也能用了。但是图片的管理部分还是用不了,下面我们就对图片管理部分代码进行修改。

   打开imageManager.php这个文件,注意到下面这段代码:

if ( $action == "get" ) {
    $files = getfiles( $path );
    if ( !$files ) return;
    rsort($files,SORT_STRING);
    $str = "";
    foreach ( $files as $file ) {
        $str .= $file . "ue_separate_ue";
    }
    echo $str;
}

   程序通过调用递归函数getfiles来完成图片文件的查找,但是我们的文件都存储在Storage中,所以这部分getfiles对我们来说无用。Storage提供一个很方便的函数getList.

getList(string $domain, [string $prefix = NULL], [int $limit = 10], [int $offset = 0])

第一个参数是Storage的domain,第二个是路径前缀可以用来指定目录或者筛选文件,默认为NULL,第三个是返回条数,第四个是偏移量。将上面的代码改成:

$path = 'upload/';                            //最好使用缩略图地址,否则当网速慢时可能会造成严重的延时
$action = htmlspecialchars( $_POST[ "action" ] );
if ( $action == "get" ) {
    if(!defined('SAE_TMP_PATH'))
    {
   
        $files = getfiles( $path );
        if ( !$files ) return;
        rsort($files,SORT_STRING);
        $str = "";
        foreach ( $files as $file ) {
            $str .= $file . "ue_separate_ue";
        }
        echo $str;
    }
    else
    {
        $st=new SaeStorage();
   
        $num=0;
        while($ret = $st->getList("upload", NULL, 100, $num )){
            foreach($ret as $file) {
                 if ( preg_match( "/\.(gif|jpeg|jpg|png|bmp)$/i" , $file ) )
                    echo $st->getUrl('upload',$file). "ue_separate_ue";
                $num++;
            }
        }
    }
}

   至此,图片管理部分修改完成。

   

   此外还有远程图片抓取getRemoteImage.php,具体修改方法参照在线涂鸦的修改,UEditor到SAE的移植基本完工。

posted @ 2013-04-20 12:22  不负韶华668  阅读(476)  评论(0编辑  收藏  举报