yiichou / aliyun-oss-support

基于阿里云OSS的WordPress远程附件支持插件
Other
353 stars 81 forks source link

解决srcset无法显示图片和安装插件后转移已有图片到OSS #9

Closed hairui219 closed 8 years ago

hairui219 commented 8 years ago

修复srcset的图片显示

我当前应用的是WordPress 4.4.2版本,文章中插入的图片,如果编辑过大小,那么WordPress会使用srcset项目来根据缩放大小自动的显示图片。示例如下:

<img class="alignnone wp-image-463" src="http://img.example.com/wp/2016/03/example.jpg" alt="example" width="201"
     height="201"
     srcset="http://oss.example.com/wp/2016/03/example-150x150.jpg 150w,
            http://oss.example.com/wp/2016/03/example-300x300.jpg 300w,
            http://oss.example.com/wp/2016/03/example-768x768.jpg 768w,
            http://oss.example.com/wp/2016/03/example-1024x1024.jpg 1024w,
            http://oss.example.com/wp/2016/03/example-210x210.jpg 210w,
            http://oss.example.com/wp/2016/03/example.jpg 1280w"
     sizes="(max-width: 201px) 100vw, 201px">

此代码存在两个问题

  1. 图片链接不正确,oss.example.com是附件上传地址,无法使用OSS的图片服务。
  2. 图片文件名称不正确,使用OSS图片服务,命名应该为example.jpg@!thumbnail等。

经过研究代码后发现,此项功能并没有应用wp_get_attachment_url这项功能,而是由函数内部通过wp_calculate_image_srcset_meta_wp_upload_dir_baseurl获取链接后自行拼接。因此,为了修复这个问题,我同时修改了插件和WordPress源代码来修复这一问题。(由于本人对WordPress并不熟悉,因此修复方案并非最佳解决方案,如果有更好方案请互相交流。)

修改方案

修改PATH/wp-content/plugins/aliyun-oss-support-master/oss-support.php文件

// wp-content/plugins/aliyun-oss-support-master/oss-support.php
// 第194行起
if(!$oss_options['img_url'] == "")
    add_action('wp_delete_file', 'delete_thumb_img', 99);

改为

if(!$oss_options['img_url'] == ""){
    add_filter('wp_get_attachment_metadata', 'modefiy_img_meta', 990);
    add_filter('wp_calculate_image_srcset_meta', 'modefiy_img_meta', 990); //增加此项处理
}

修改 PATH/wp-includes/media.php文件

// wp-includes/media.php
// 第1048行起(4.4.2版本)
$image_baseurl = _wp_upload_dir_baseurl();
$image_baseurl = trailingslashit( $image_baseurl ) . $dirname;

改为


$image_baseurl = _wp_upload_dir_baseurl();

//插入如下部分,借用了插件中替换url的部分代码
$oss_options = get_option('oss_options', TRUE);
if(!$oss_options['img_url'] == ""){
    $image_baseurl = rtrim($oss_options['img_url'], '/');
    if(rtrim($oss_options['path'], '/') != ""){
        $image_baseurl = $image_baseurl .'/'. rtrim($oss_options['path'], '/');
    }
}

$image_baseurl = trailingslashit( $image_baseurl ) . $dirname;

运行效果演示(可正常的从oss中获取图片并显示出来)

<img class="alignnone wp-image-463" src="http://img.example.com/wp/2016/03/example.jpg" alt="example" width="201"
     height="201"
     srcset="http://img.example.com/wp/2016/03/example.jpg@!thumbnail 150w, 
                  http://img.example.com/wp/2016/03/example.jpg@!medium 300w, 
                  http://img.example.com/wp/2016/03/example.jpg@!medium_large 768w, 
                  http://img.example.com/wp/2016/03/example.jpg@!large 1024w, 
                  http://img.example.com/wp/2016/03/example.jpg@!medium 210w, 
                  http://img.example.com/wp/2016/03/example.jpg 1280w"
     sizes="(max-width: 201px) 100vw, 201px">

可以看到,链接被替换成img.example.com,图片名称也正确了。

另外,演示代码中的图片类型数量与原版插件支持的要多一些(如多了medium_large),如果有需要,请自行在oss-support.php文件的modefiy_img_meta函数中添加(请在阿里云OSS后台的图片处理功能中也一并添加,具体教程在插件安装说明中)。

转移已有图片到OSS并修复链接

安装好插件后,我进行了一次批量的wp-content/uploads上传到OSS服务器的文件传输。

但是,已经上传好的文章中,还是保存着本地的文件链接,修改方法只需要运行一次SQL指令即可,指令如下:

update `wp_posts` set `post_content`=REPLACE(`post_content`,'http://example.com/wp-content/uploads/','http://img.example.com/wp/');

请注意,请先备份数据库,并将上诉SQL语句中的两个链接替换成您自己的地址 http://example.com/wp-content/uploads/ - 之前数据库中保存的链接 http://img.example.com/wp/ - 阿里云OSS的图片链接

yiichou commented 8 years ago

😄😄😄😄 感谢反馈~~~

其实你可以直接贡献代码 fork 一份,修改后给我提一个 request,有好的建议或改进就可以直接更新到主分支

hairui219 commented 8 years ago

因为此项修改并不只是修改了插件中的内容,而是同时修改了WordPress的源代码,因此我只能特意撰写此流程来帮助有需要的用户,如果后续还发现有什么问题,我会直接提交request给您。

这个问题主要原因其实是WordPress的内部编码并未调用设计好的功能代码,而是自己实现一份,并非是OSS插件的问题。我目前还发现有一些广泛使用的插件也是类似的处理,自带resizer或者自己实现文件的转储(调用php的文件接口),造成OSS插件无法完美的工作,我在网上搜寻时,国外用户使用Amazon S3也是经常碰到类似的问题。

不过还是非常感谢您贡献的插件,对我帮助非常大。我制作的是一个福利机构的网站,主要发布日常一些活动的照片,因此每个页面的照片都非常多。通过使用此插件,我的页面读取速度和能够提供的访问量提高了非常多。在此表示感谢。

yiichou commented 8 years ago

Commit d18cb08 已经修复,不用改系统文件了