Drupal 8 自带的上传进度功能,需要PECL uploadprogress library扩展支持。
安装后发现效果还是不太好,不知道什么原因,进度条不能正常显示,而且上传较大文件时,速度比较慢。于是想到利用Nginx的uploadprogres模块来实现上传进度。
这个模块需要在编译安装的时候加上,编译安装请看:编译安装Nginx以及配置运行Drupal 8,实现上传进度功能
搜索了一下,找到一个模块:FileField Nginx Progress,不过只有Drupal7版本的,于是看了一下代码,了解了实现思路,根据这个思路,做了一个Drupal 8版本的出来。
模块地址:upload_progress
由于Nginx uploadprogress模块的上传进度和Drupal自带的上传进度获取方式不同,所以要把从Nginx获取到的进度信息,转换成Drupal需要的格式,再返回给Drupal前端。
简单的说一下实现的思路:
定义获取进度信息的路由
在Nginx里设置获取进度信息的URL。
定义一个路由,和对应的控制器(controller)。
在控制器里从第一步定义的URL获取到的信息,转换成Drupal需要的格式,然后返回给前端。
自定义文件控件
基于FileWidget自定义一个文件控件(widget),这样可以比较方便的覆写文件处理方法。
覆写控件的settingsForm方法,目的是实现选择进度指示器的类型(如果Drupal检测到没有安装PECL uploadprogress library扩展,不会显示选择进度指示器的表单)。
然后覆写process方法,目的是为表单预先设置一些内容。Nginx uploadprogress模块需要表单提交时以QueryString方式提供一个X-Progress-ID,而且还需要把获取进度信息的URL修改成自定义的路由。这两个动作都是在这一步完成的。
覆写value方法,这个方法是提交文件时回调的方法,后面使用Nginx upload模块替代PHP的文件上传功能,会用到这个方法。
设置进度指示器为进度条
结构 –> 内容类型 –> 管理表单显示。把需要进度条的字段的控制器,修改成上面自定义的控制器。
点击字段后面的齿轮图标,选择进度指示器为进度条。
以上步骤完成后,就可以实现进度条功能了。
接下来使用Nginx upload模块替代PHP的文件上传功能,目的是提高文件上传的性能。由于Nginx扩展是使用C语言编写的,理论上来说会比PHP性能好很多。而且可以避免上传大文件时PHP执行超时引起错误。
根据前面提供的Nginx文章,配置好Nginx之后,就可以进行以下操作。
根据上面的方法,覆写value方法。
根据Nginx里自定义的字段信息,获取POST内容(文件名,路径,大小,类型等)。
把文件移动到目标目录。
新建一个File对象,把uri设置成刚上传的文件。
把value方法的input[‘fid’]值设置成新创建的File对象的ID。
调用parent::value方法。