serosensa / user-image-handling
在Laravel中处理用户上传的图片
Requires
- php: >=5.4.0
- intervention/image: ^2.4
Requires (Dev)
- barryvdh/laravel-debugbar: ^3.1
- orchestra/testbench: ~3.5.0|~3.6.0
- phpunit/phpunit: ^6.2|^7.0
This package is not auto-updated.
Last update: 2024-09-19 16:26:05 UTC
README
此软件包不完整
安装
- 运行
composer require serosensa/user-image-handling @dev
- 运行
php artisan vendor:publish --tag=userimage-js-assets
- 在创建主vue实例之前,但在引入vue之后,将
require('./user-image/userImageApp.js')
添加到主app.js文件中 - 运行
php artisan vendor:publish --tag=userimage-sass-assets
- 在主scss样式表中的供应商部分添加
@import "user-image/user-image"
(在设置之后但在任何自定义样式之前)
用法 & 功能
- 此软件包附带一些默认路由和一个默认UserImageController
- 您可以使用这些默认路由和相关方法,或者从UserImageController复制相关方法并根据需要进行修改。
- 如果您选择创建自己的控制器,您仍然可以利用ImageService中的有用方法。要访问来自例如ImageService的方法,扩展UserImageBaseController
class MyImageController extends UserImageBaseController
- 上传图片被视为与创建图片数据库记录的独立步骤。确保完成这两个步骤,以便可以检索图片。
###默认行为
图片上传
使用 file-upload-fetch
组件,将数据发送到fetch-image-upload,并使用UserImageController@fetchImageUpload 组件接收包含位置等文件数据的json,并发出事件 file-upload
给其父组件 //TODO 使用v-model更好地传递这些数据。父组件负责捕获此事件并适当使用数据(例如创建数据库记录)
保存图片记录
将file-upload-fetch生成的fileData传递给ImageService@saveImageRecords;将保存图片记录到默认的UploadedImages
表(有关更多信息,请参阅此readme)。您可以传递一个模型名称(例如Article)来将图片与数据库中的特定相关模型绑定。
上传并保存记录
方法UserImageController@fetchImageUploadAndRecord
通过组合上述功能来处理这两个步骤。只需创建到该方法的路由,并将file-upload-fetch的post-url设置为该路由。
异步上传图片
上传文件并接收可以用于从服务器请求图片的json
- 使用
file-upload-fetch
vue组件 属性- postUrl(可选:默认为/fetch-file-upload)
- 未使用 - fileDest - 公共磁盘中的一个可写文件夹
- 未使用 - parentIdentity(数组:父模型,id) - 用于确保正确的vue父组件捕获事件。在控制器中未使用
- multiple(可选:默认为false)
- 显示文件上传输入
- 通过postUrl访问的控制器应将图片文件保存到存储。方法
ImageService@fetchImageUpload
执行此操作并返回json。请参阅ImageService方法 - 在上传后期望接收包含文件数据的json。
- TODO 在此组件中显示上传的文件以及现有的上传文件(可选)
- 在成功上传后发出事件
file-upload
到事件总线,其中包含parentIdentity和fileData。父组件可以捕获并使用这些数据 //TODO 将此数据添加到父组件中,使用v-model代替
上传图片(Post)(未完全测试)
- 使用常规文件上传字段,将数据发送到控制器。
- 控制器可以使用
ImageService@imageUpload
重命名和调整文件大小,并使用ImageService@saveImageRecords
在UploadedImages表中创建数据库记录(请参阅ImageService方法)
保存/存储图像记录
- 一旦上传图像,将其记录保存到相关数据库表中
- 可以使用从
ImageService@imageUpload
返回的数据进行此操作 - 此包创建了一个默认的 uploaded_images 表(见 图像存储与检索)
- 可以使用
ImageService@saveImageRecords
方法将记录保存到默认表(见 ImageService 方法) - 还有上传图像的默认模型(见 默认UploadedImages模型)
- 或者,根据需要将记录保存到另一个表中
- 通过
file-upload-fetch
组件上传的图像默认将图像数据返回给父表单。在控制器中创建数据库记录以保存父表单。或者,将 file-upload-fetch 的 postUrl 设置为创建数据库记录的控制器
ImageService 方法
ImageService@imageUpload
参数 - 请求对象 - 文件目标 - 包含图像的字段名称(可选,默认:images) - 缩放图像文件的宽度(可选,默认:2000px) - 必须为表单中的每个文件输入字段运行一次 - 接受单个或多个图像 - 不执行验证 - 在调用之前进行验证 - 返回 文件数据数组,即使字段中只有一个文件
ImageService@fetchImageUpload
使用 ImageService@imageUpload
- 相同的参数 - 验证图像(TODO 处理每个字段的多个文件) - 返回 文件数据的 json(TODO 处理每个字段的多个文件)
ImageService@saveImageRecords
//TODO 未测试 - 将图像记录保存到默认的 UploadedImages
表。 - 参数 - 上传的图像数据(单个图像) - 父模型对象(可选,默认:null) - 期望上传的图像数据包含诸如文件名和路径等详细信息。从 ImageService@ImageUpload
返回的数据是合适的 - 接受图像数组或单个图像 TODO 是否有效?正在测试图像数据是否为数组,但单个图像不是数组吗? - 接受单个图像的数据 - 应在 foreach 循环中运行以处理多个图像 - 如果发送了父对象,则将父模型名称和父 ID 保存到图像记录中。否则,这些值为 null。 - 返回 记录数组或单个记录
ImageService@imageEditorSave
处理 image-editor
组件发送的数据 - 参数 - 图像实例(在调用控制器中检索图像并传递) - 请求对象 - 返回 用于组件的图像数据 json
图像存储与检索
默认UploadedImages表
//TODO - 必须手动复制迁移,包中不起作用 - 存储图像数据的记录 - 使用 ImageService@saveImageRecords
- 可选地与父模型和 ID 相关 - 这可以用来从表中检索图像,例如通过调用 UploadedImage::where(parent_model, 'article')
或 UploadedImage::where('parent_model', 'article')->where('parent_id', $parentId)
- 或者,将此表的 id
存储在枢纽表中,以便任何其他模型可以访问。它也是 -
必需字段 - 文件名 - 路径 - 可选字段 - 文件类型 - 文件大小 - category_id - 标题 - is_primary(默认:0) - is_shown(默认:1) - parent_model - 表示父模型的模型名称 - parent_id - 父 ID
默认UploadedImages模型
扩展此模型以添加所需的任何附加功能 - class MyUploadedImageModel extends Serosensa\UserImage\UploadedImage
。设置 created_at 和 updated_at 字段的日期和 guarded
- 方法?
显示/编辑现有图像
Image-display 组件
- 使用
image-display
vue 组件显示每个图像(例如使用 v-for) - Props - 图像 - 显示图像和相关数据
- 使用 slot
info-panel-default
来覆盖默认数据 - 使用 slot
info-panel-extra
来添加其他数据 - 还包含信息面板之外的一个默认插槽
- 使用 slot
图像编辑组件
- 在图像显示组件内部,添加
image-editor
组件的 属性- 图像,
- postUrl(不带图像ID或'/')
- 类别(可选)
- 允许
- 更改 is_shown 值
- 更改 is_primary 值
- 更新标题
- 旋转图像
- 设置类别(可选通过插槽)
- 显示一个编辑按钮,并有一个模态框来编辑图像。具有一些默认选项和多个插槽
- 插槽
title
- 插槽
fields-default
显示默认编辑字段。如有必要,可覆盖此插槽。 - 插槽
categories
如果需要类别选择器。如果使用,设置slot-scope="categoriesScope"
- 插槽
fields-extra
用于任何额外的字段 - 插槽
label_is_primary
- 插槽
label_is_shown
- 插槽
label_caption
- 插槽
subtext_caption
在标题下方的附加文本。验证应在控制器/自定义请求中正常进行。在验证失败时,laravel 返回一个包含错误的 JSON 数组,编辑窗口将在相应的字段旁边显示这些错误。
- 插槽
<image-display :image="{{$image}}" :categories="{{$propertyImageTypes}}" class="">
<image-editor class="" :image="{{$image}}" post-url="{{route('propertyImageUpdate', $image->id)}}" :categories="{{$propertyImageTypes}}">
<div slot="title" class="title">Edit Image</div>
</image-editor>
</image-display>
图像编辑类别
在 imageEditor 中显示类别选择器
- 通过 image-editor 的
categories
属性传递一个类别数组 - 每个类别至少必须有一个 id 和一个 name。组件使用每个类别的 'name' 字段生成 categoryName
- 确保图像有一个
category_id
字段 - 将
slot-scope="categoriesScope"
添加到使用该插槽的元素,这允许插槽与父组件之间共享数据。下面的示例创建单选按钮以选择类别
<div slot="categories" slot-scope="categoriesScope" class="form-row">
<label for="">Image Type:</label>
<span v-for="category in categoriesScope.categories">
<label for="category_id">{{ option.name }}</label>
<input type="radio" :value="category.id" v-model="categoriesScope.model.category_id">
</span>
</div>
字段错误组件
- 使用
field-errors
组件与任何可能返回错误的字段一起使用 - 显示给定字段的全部错误
- 传入错误对象和要显示错误的字段名称
<field-errors :errorObject="errors.is_primary"></field-errors>
详细信息
//TODO - 一些内容已被上述内容替代/需要更新
JS 文件(vue/通用前端)
- 文件
userImageApp.js
注册了该包提供的所有 vue 组件, - 通过运行
php artisan vendor:publish --tag=userimage-js-assets
导出此文件 - 这会将所有 JS 文件导出到resources/assets/js/user-image
。 - 警告:如果直接修改这些文件,它们可能会在包更新时被覆盖。要强制更新并覆盖文件,请向发布命令添加
--force
- 在创建主 vue 实例之前但在 require vue 之后,在应用程序的主 app.js 中引入此文件
require('./user-image/userImageApp.js');
样式
- 将 _user-image.scss 文件包含到主 sass 文件中。在包含自己的样式表之前包含此文件,以便可以轻松覆盖样式。
- 通过运行
php artisan vendor:publish --tag=userimage-sass-assets
导出此文件 - 这会将 scss 文件导出到resources/assets/sass/user-image
。
图标
- 本包中的所有图标都有
image-editor-icon
类 - 可以通过设置
$user-image-icon-color-1
和$user-image-icon-color-2
的值来重新着色图标 - 在引入供应商样式表之前(例如,在设置中)设置这些值以覆盖默认值。某些图标可能只会使用 color1。 - 您还可以通过类覆盖样式来在不同上下文中样式化图标
- 图标作为 JS 文件存在于 /vendor/serosensa/icons 中,每个模板按需引入
图像上传 - 通过 ImageService
- ImageService 处理图像文件上传的所有方面
- 它必须传递包含上传图像文件表单的 $request
- 服务可以处理每个字段上传多个图像
- 如果设置了唯一字段名称,服务可以处理表单中每个字段的上传
- 每个上传字段可以有自己的目标文件夹
- 目标文件夹应该被 .gitignored,因为它们将在服务器上独立于源代码而更改。
- imageService 将文件保存到 config/filesystems 中定义的 'public' 磁盘。如果这是 /app/public 文件夹,则在此保存的文件通过它们的 URL 或文件名对公众可见。
文件目标 / 可写文件夹
要保存上传文件的文件夹必须是可写的。为此,请运行 chmod -R 777 public/foldername
图像上传表单
- 包含文件上传的表单必须具有
enctype="multipart/form-data
或参数 files => true(如果使用 LaravelCollective 表单) - 要为每个字段上传多个图像,请在字段中添加
multiple
并在视图文件中的字段名中添加[]
默认字段名称 - 只有一个文件上传字段
- 默认情况下,
ImageService@imageUpload
函数期望一个名为images
的上传字段。如果有请求中只有一个上传字段,则可以使用此默认值,或者可以使用其他名称并将其传递给服务。
自定义字段名称 - 一个或多个文件上传字段
- ImageService 必须为每个上传字段调用一次
- 文件上传字段必须有唯一、自定义的名称,例如
thumbnail
控制器中的图像上传
- 请参阅
/examples
目录中的 ExampleController 以获取示例控制器函数。 - ImageService 处理大多数图像操作 - 控制器只需调用 ImageService、传递值并保存结果数据即可。
- 在调用 imageService@imageUpload 之前,应该验证上传的文件(以确保是正确的图像文件类型)。此包包括一个
IsValidImageRequest
,您可以使用它。如果验证失败,将返回错误包isValidImage
。 - 如果错误地调用 imageService 而请求中没有文件,则它将返回 null 而不是生成错误。
- ImageService 总是返回一个包含图像数据的嵌套数组 - 不论上传的文件数量。
ImageService@imageUpload 功能
- 一旦调用,imageservice
- 循环每个图像
- 如果已存在具有相同名称的文件,则重命名文件
- 将文件保存到指定的文件夹(在删除任何开头的 / 之后,因为这会在保存调整大小的文件时引起问题)
- 将文件调整到指定的最大宽度(除非是 svg)
- 返回包含每个图像的数据数组的数组
- 此返回的数据应按调用函数的要求进行处理 - 例如,将文件名保存到数据库中
图像旋转
image-editor
组件包含image-rotation
组件,但它也可以单独使用。- 应将图像-旋转组件传递正在编辑的图像的数据库 ID,例如
<image-rotation :image-id="image.id"></image-rotation>
- 当点击旋转按钮时,组件会发出一个事件,该事件被编辑器收集并用于转换图像预览。
- 旋转值被添加到 imageData 中,因此传递到控制器,在那里可以使用它。请参阅
ExampleController
中的示例 - ImageService 处理实际的旋转,因此此功能可以在任何地方调用。 - 当编辑保存时,
image-display
组件捕获来自 image-editor 的发出的事件。这触发了从磁盘重新加载更新的图像,因此任何更改(包括旋转和未来可能启用的任何其他更改)都反映在显示的图像中。 image-editor
组件还会从磁盘重新加载图像并重置旋转值,因此它在下次加载时是“新鲜”的。- 从磁盘重新加载是通过将图像的src设置为
versionedImage
数据对象来完成的。在加载时,这设置为原始文件名,但在每次需要更新图像(例如保存编辑时)时,都会通过调用makeVersionedImage()
函数来覆盖它。此函数将随机版本号附加到文件名末尾,从而触发重新加载。
待办事项
- 将表单/样式包作为依赖项添加(替换此包中的现有包含项?)
- IsValidImageRequest未经过适当测试 - 在ImageService@fetchFileUpload中验证文件上传
有用参考资料
- 创建包 - https://devdojo.com/blog/tutorials/how-to-create-a-laravel-package
- Laravel特定包的开发,包括有关发布文件的信息 - https://laravel.net.cn/docs/5.6/packages
- 本地开发包 - https://johannespichler.com/developing-composer-packages-locally/