Typecho | 博客结构与插件开发笔记:插件行为触发器拦截

warning: 这篇文章距离上次修改已过413天,其中的内容可能已经有所变动。

概要

最近在学习Typecho插件开发,对于图床类插件有了基本的了解。本文将介绍今天通过对原生上传组件Widget_Upload学习到的,关于Typecho博客中附件的上传、修改、删除、查询和获取的基本过程。

上传组件

仍然是在Typecho 1.1中,作者对于附件的各种管理定义了一个Widget_Upload类,位于var/Widget/Upload.php。其中最为主要的类函数方法如下表所示。

函数名权限作用
uploadHandlepublic上传附件时会调用该方法进行处理,返回一个包含存储位置等信息的array
modifyHandlepublic在管理附件中修改文件时会调用该方法进行处理,返回一个修改完后的信息的array
deleteHandlepublic删除附件时调用,返回删除成功或失败
attachmentHandlepublic获取附件的绝对访问路径
attachmentDataHandlepublic获取附件的实际数据,下载时需要使用

方法拦截

这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.phpactivate()方法内对上传、修改、删除等等方法的注册行为,可以知道,作者设置的这个拦截会去尝试寻找第三方注册上传方法进行文件上传处理,如果没有找到并执行,$hasUploaded为false,继续执行原生的上传代码;若成功找到第三方注册上传方法并执行,则$hasUploaded为true,不再执行后续原生上传代码。

总结思考

Typecho博客程序作者所思考的对第三方插件的支持方案,在1.1版本里相对来说是有一定局限的。作者默认了附件只上传到一个地方,要么就全上传到本机,要么就全上传到外部存储位置(例如图床)。然而附件类型多样,只有受支持的图片类型才允许被上传到图床,其它正常的附件则在默认情况下应该正常上传至本机。这点虽然可以被插件作者实现,但似乎需要将原生的本地上传组件的代码重新复制一遍,而无法直接调用已有的原生方法。因为如果在插件中调用原生方法,就会由于原生方法中的拦截导致循环调用。

最后修改于:2023年03月03日 16:24

添加新评论