Typecho | 博客结构与插件开发笔记:插件行为触发器拦截
概要
最近在学习Typecho插件开发,对于图床类插件有了基本的了解。本文将介绍今天通过对原生上传组件Widget_Upload
学习到的,关于Typecho博客中附件的上传、修改、删除、查询和获取的基本过程。
上传组件
仍然是在Typecho 1.1中,作者对于附件的各种管理定义了一个Widget_Upload
类,位于var/Widget/Upload.php
。其中最为主要的类函数方法如下表所示。
函数名 | 权限 | 作用 |
---|---|---|
uploadHandle | public | 上传附件时会调用该方法进行处理,返回一个包含存储位置等信息的array |
modifyHandle | public | 在管理附件中修改文件时会调用该方法进行处理,返回一个修改完后的信息的array |
deleteHandle | public | 删除附件时调用,返回删除成功或失败 |
attachmentHandle | public | 获取附件的绝对访问路径 |
attachmentDataHandle | public | 获取附件的实际数据,下载时需要使用 |
方法拦截
这5个方法在正式执行前,都通过一句相似的代码插入了trigger,也就是为插件作者提供了对原生方法的拦截。以Widget_Upload
中的原生上传函数uploadHandle($file)
为例,其最开始执行的代码如下:
public static function uploadHandle($file)
{
if (empty($file['name'])) {
return false;
}
$result = Typecho_Plugin::factory('Widget_Upload')->trigger($hasUploaded)->uploadHandle($file);
if ($hasUploaded) {
return $result;
}
// ....其它代码
}
可以看到其中执行了一句Typecho_Plugin::factory('Widget_Upload')->trigger($hasUploaded)->uploadHandle($file);
并根据$hasUploaded
的值来决定是否要执行后续的文件上传代码,实际上起到一个拦截的作用。
联系到上一篇博文中对插件开发的基本学习中,在Plugin.php
的activate()
方法内对上传、修改、删除等等方法的注册行为,可以知道,作者设置的这个拦截会去尝试寻找第三方注册上传方法进行文件上传处理,如果没有找到并执行,$hasUploaded
为false,继续执行原生的上传代码;若成功找到第三方注册上传方法并执行,则$hasUploaded
为true,不再执行后续原生上传代码。
总结思考
Typecho博客程序作者所思考的对第三方插件的支持方案,在1.1版本里相对来说是有一定局限的。作者默认了附件只上传到一个地方,要么就全上传到本机,要么就全上传到外部存储位置(例如图床)。然而附件类型多样,只有受支持的图片类型才允许被上传到图床,其它正常的附件则在默认情况下应该正常上传至本机。这点虽然可以被插件作者实现,但似乎需要将原生的本地上传组件的代码重新复制一遍,而无法直接调用已有的原生方法。因为如果在插件中调用原生方法,就会由于原生方法中的拦截导致循环调用。