mirror of
https://gitee.com/johng/gf.git
synced 2024-12-02 20:28:17 +08:00
143 lines
4.4 KiB
Go
143 lines
4.4 KiB
Go
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
|
//
|
|
// This Source Code Form is subject to the terms of the MIT License.
|
|
// If a copy of the MIT was not distributed with this file,
|
|
// You can obtain one at https://github.com/gogf/gf.
|
|
|
|
package ghttp
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
"mime/multipart"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/gogf/gf/v2/errors/gcode"
|
|
"github.com/gogf/gf/v2/errors/gerror"
|
|
"github.com/gogf/gf/v2/internal/intlog"
|
|
"github.com/gogf/gf/v2/internal/json"
|
|
"github.com/gogf/gf/v2/os/gfile"
|
|
"github.com/gogf/gf/v2/os/gtime"
|
|
"github.com/gogf/gf/v2/util/grand"
|
|
)
|
|
|
|
// UploadFile wraps the multipart uploading file with more and convenient features.
|
|
type UploadFile struct {
|
|
*multipart.FileHeader `json:"-"`
|
|
ctx context.Context
|
|
}
|
|
|
|
// MarshalJSON implements the interface MarshalJSON for json.Marshal.
|
|
func (f UploadFile) MarshalJSON() ([]byte, error) {
|
|
return json.Marshal(f.FileHeader)
|
|
}
|
|
|
|
// UploadFiles is an array type of *UploadFile.
|
|
type UploadFiles []*UploadFile
|
|
|
|
// Save saves the single uploading file to directory path and returns the saved file name.
|
|
//
|
|
// The parameter `dirPath` should be a directory path, or it returns error.
|
|
//
|
|
// Note that it will OVERWRITE the target file if there's already a same name file exist.
|
|
func (f *UploadFile) Save(dirPath string, randomlyRename ...bool) (filename string, err error) {
|
|
if f == nil {
|
|
return "", gerror.NewCode(
|
|
gcode.CodeMissingParameter,
|
|
"file is empty, maybe you retrieve it from invalid field name or form enctype",
|
|
)
|
|
}
|
|
if !gfile.Exists(dirPath) {
|
|
if err = gfile.Mkdir(dirPath); err != nil {
|
|
return
|
|
}
|
|
} else if !gfile.IsDir(dirPath) {
|
|
return "", gerror.NewCode(gcode.CodeInvalidParameter, `parameter "dirPath" should be a directory path`)
|
|
}
|
|
|
|
file, err := f.Open()
|
|
if err != nil {
|
|
err = gerror.Wrapf(err, `UploadFile.Open failed`)
|
|
return "", err
|
|
}
|
|
defer file.Close()
|
|
|
|
name := gfile.Basename(f.Filename)
|
|
if len(randomlyRename) > 0 && randomlyRename[0] {
|
|
name = strings.ToLower(strconv.FormatInt(gtime.TimestampNano(), 36) + grand.S(6))
|
|
name = name + gfile.Ext(f.Filename)
|
|
}
|
|
filePath := gfile.Join(dirPath, name)
|
|
newFile, err := gfile.Create(filePath)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
defer newFile.Close()
|
|
intlog.Printf(f.ctx, `save upload file: %s`, filePath)
|
|
if _, err = io.Copy(newFile, file); err != nil {
|
|
err = gerror.Wrapf(err, `io.Copy failed from "%s" to "%s"`, f.Filename, filePath)
|
|
return "", err
|
|
}
|
|
return gfile.Basename(filePath), nil
|
|
}
|
|
|
|
// Save saves all uploading files to specified directory path and returns the saved file names.
|
|
//
|
|
// The parameter `dirPath` should be a directory path or it returns error.
|
|
//
|
|
// The parameter `randomlyRename` specifies whether randomly renames all the file names.
|
|
func (fs UploadFiles) Save(dirPath string, randomlyRename ...bool) (filenames []string, err error) {
|
|
if len(fs) == 0 {
|
|
return nil, gerror.NewCode(
|
|
gcode.CodeMissingParameter,
|
|
"file array is empty, maybe you retrieve it from invalid field name or form enctype",
|
|
)
|
|
}
|
|
for _, f := range fs {
|
|
if filename, err := f.Save(dirPath, randomlyRename...); err != nil {
|
|
return filenames, err
|
|
} else {
|
|
filenames = append(filenames, filename)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// GetUploadFile retrieves and returns the uploading file with specified form name.
|
|
// This function is used for retrieving single uploading file object, which is
|
|
// uploaded using multipart form content type.
|
|
//
|
|
// It returns nil if retrieving failed or no form file with given name posted.
|
|
//
|
|
// Note that the `name` is the file field name of the multipart form from client.
|
|
func (r *Request) GetUploadFile(name string) *UploadFile {
|
|
uploadFiles := r.GetUploadFiles(name)
|
|
if len(uploadFiles) > 0 {
|
|
return uploadFiles[0]
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetUploadFiles retrieves and returns multiple uploading files with specified form name.
|
|
// This function is used for retrieving multiple uploading file objects, which are
|
|
// uploaded using multipart form content type.
|
|
//
|
|
// It returns nil if retrieving failed or no form file with given name posted.
|
|
//
|
|
// Note that the `name` is the file field name of the multipart form from client.
|
|
func (r *Request) GetUploadFiles(name string) UploadFiles {
|
|
multipartFiles := r.GetMultipartFiles(name)
|
|
if len(multipartFiles) > 0 {
|
|
uploadFiles := make(UploadFiles, len(multipartFiles))
|
|
for k, v := range multipartFiles {
|
|
uploadFiles[k] = &UploadFile{
|
|
ctx: r.Context(),
|
|
FileHeader: v,
|
|
}
|
|
}
|
|
return uploadFiles
|
|
}
|
|
return nil
|
|
}
|