atk4/filestore

ATK UI 表单上传字段与 PHP Flysystem 的集成

5.0.0 2024-03-28 14:40 UTC

This package is auto-updated.

Last update: 2024-09-04 10:01:21 UTC


README

从 ATK UI 1.4 版本开始,它增加了对文件和图像上传的支持。在其原始形式中,开发者负责在上传文件后对其进行处理。在大多数情况下,开发者可能希望将文件存储在本地或远程文件系统中,但需要自己执行此操作。

Filestore 是一个用于 ATK 数据和 ATK UI 的插件,它提供了与 Flysystem 无缝集成。

简介

使用 Filestore 将文件附加到数据库记录非常简单。以下示例可以在几行代码内实现并添加到您的 PHP 应用程序中。

upload1

由于 ATK 表单使用 AJAX 提交,文件必须在选择后立即发送到服务器。文件立即放置在 flysystem 中(在演示中我使用的是本地存储),并在数据库中创建一个包含有关文件的全部信息的记录,包括是否为图像以及如果是图像,则包括尺寸。

upload1

生成两个随机标识符 - 一个用于实际的文件名(以确保您不会覆盖现有文件),另一个(令牌)将用于引用文件。实际上您根本看不到令牌,但它用于保持安全。

您可以直接在 CRUD 中上传文件,并且可以拥有多个文件字段。

upload1

在您的主要表中,您只需要一个 varchar 字段来存储文件令牌。如果您使用 SQL,则可以访问额外的字段,如原始文件名等。

upload1

这对于您需要在自定义模板中包含所有这些字段的情况非常有价值。

安装和代码

要安装,请运行 composer require atk4\filestore 并需要创建 filestore_file 表。在模型定义中,您只需声明一个新的字段。

$this->addField('file', [\Atk4\Filestore\Field\FileField::class, 'flysystem' => $this->getApp()->filesystem]);

这基本上就处理了所有事情!有关完整示例,请参阅文件 demos/basic.php

功能

目前实现了以下功能

  • 美观的文件上传界面和与 ATK UI 表单的完整集成。上传跟踪带有进度条。
  • 保持文件整洁,删除记录也会删除相关联的文件。上传但未链接的文件将保留在“草案”状态,您可以定期清理它们。
  • 通过与 flysystem 集成,支持任何存储。
  • 非常灵活,可以使用不同的表,不同地映射字段,使用多个位置,添加自定义操作等等。
  • 文件可以基于 "user_id" 进行范围限制,以提供进一步的安全性(即使用户知道令牌,用户也无法访问其他用户的图像)。

路线图

对于即将推出的版本,我们有以下想法。如果您想帮助实现以下任何功能(或赞助),请联系 @romaninsh (https://gitter.im/atk4/atk4)。

  • 指定要接受的扩展名和/或文件类型。
  • 轻松下载之前上传的文件。
  • 添加自动缩略图创建。与原始图像一起删除缩略图。
  • 指定上传、链接、取消链接和删除的自定义操作。
  • 显示文件类型的图标或图像的预览。
  • 添加交互式裁剪。
  • 添加验证文件的方法。
  • 添加拖放上传。
  • 为大型拖放目标添加新视图或使用任意视图(无需表单上传)。
  • 添加“文件管理”的UI。
  • 支持从原始图片重新裁剪缩略图。
  • 集成NoSQL持久化支持。
  • 在存储前加密文件,在加载时解密。
  • 添加将文件“哈希”到子目录的选项。

旧README

事件,因此文件上传将在文件被选中时立即发生。但是,有一些条件,当文件已上传/删除但表单未提交时。

成功完成后,PHP端回调执行以生成IDFilestore提供此回调并执行以下操作

  • 收集有关文件的信息 - 原始文件名、大小、MIME类型等。
  • 在“文件”模型中存储信息,生成ID。
  • 使用随机名称将文件移动到Flysystem中,并在“文件”模型中记录。
  • 返回文件的ID,然后将其传递回表单提交处理程序。

示例

如果您有一个如Friend的模型,并且希望上传朋友的照片,Filestore提供了一种很好的集成方式

// in Friend::init();
$this->addField('photo_file_token', [\Atk4\Filestore\Field\FileField::class]);

此字段将自动出现在表单中作为上传字段,但在数据库中将存储来自“文件”模型的“token”。您甚至可以定义多个这样的字段。

默认情况下,将使用本地文件存储,但您可以通过将配置传递到您的字段来配置不同的位置

$this->addField('photo_file_token', [
    \Atk4\Filestore\Field\FileField::class,
    // specify if you want to only accept certain types of files or extensions.
    'onlyTypes' => ['image/*', 'application/x-pdf'],
    'onlyExtensions' => ['img', 'png', 'pdf'], // safer to specify both

    // where to store
    'flysystem' => $flysystem,

    // you can also define callback if you wish to do something more with the file
    'onUpload' => function ($file) {
        // do something with file
    },

    // this is called when form with the file is submitted
    'onAttach' => function ($file) {
        // $file is a model object
    },

    // when user detaches file from the related entity
    'onDetach' => function ($file) {
        // $file is a model object
    },
])

如果您打开已附加文件的Friend表单,您将能够删除文件。但是,“删除”文件不一定意味着它们将被解除关联,用户仍然可以点击“取消”。然而,当表单保存时,如果文件被删除,它也将从存储和File表中删除。

图像

Filestore还实现了\Atk4\Filestore\Field\Image类,该类通过扩展File自动裁剪并存储图像的各种缩略图,从而提供额外功能。

$this->addField('picture_id', [
    \Atk4\Filestore\Field\Image::class,

    // no need to specify types, will only accept valid images

    // where to store
    'flysystem' => $flysystem,

    // you can still define this if you wish to pre-process your file, e.g. add watermark
    'onUpload' => function ($file) {
        // do something with file
    },

    // cropping table
    'crop' => [
        'medium' => [200, 300], // width, height
        'small' => [50, 50],
    ],
])

裁剪将保持原始图像的纵横比,但将确保图像被填充。将使用“imagick”或“gd”进行操作。参数定义如下

  • 0 => 200,宽度
  • 1 => height,高度
  • 'type' => 'jpeg' 可选。默认为'png'

为了存储缩略图,Filestore将在File表中创建额外的文件。

文件模型

Filestore附带一个自定义模型Atk4\Filestore\Model\File,该模型设计用于存储文件元信息。对于每个上传的文件,它存储以下内容

  • file_token - 随机生成,用于在表单中传递回提交处理程序
  • location - (用于在Flysystem中标识文件。随机生成)
  • storage - (有关所使用存储的简短信息)
  • source_file_id (指定原始文件的ID。用于缩略图或其他生成文件)
  • status (定义文件当前的位置)

定义了几个“元”字段,用于描述文件内容

  • meta_filename
  • meta_extension
  • meta_md5
  • meta_mime_type
  • meta_size
  • meta_is_image
  • meta_image_width
  • meta_image_height

方法

$file->createFromPath('path/to/file.txt', 'my_file.txt');

创建一个File实体,将数据保存到flysystem并保存实体。

$stream = $file->getStream();

返回文件内容的流。您可以通过调用$stream->getContents()来获取文件内容作为字符串。

路线图

一些可能的功能

  • 添加“临时”位置以存储文件
  • 在通过模型加载随机文件时允许初始化Flysystem详细信息