2020-02-26 00:48:27 +08:00
|
|
|
// Copyright 2019 gf Author(https://github.com/gogf/gf). 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 (
|
|
|
|
"errors"
|
2020-03-04 17:29:23 +08:00
|
|
|
"github.com/gogf/gf/internal/intlog"
|
2020-02-26 00:48:27 +08:00
|
|
|
"github.com/gogf/gf/os/gfile"
|
|
|
|
"github.com/gogf/gf/os/gtime"
|
|
|
|
"github.com/gogf/gf/util/grand"
|
|
|
|
"io"
|
|
|
|
"mime/multipart"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
// UploadFile wraps the multipart uploading file with more and convenient features.
|
|
|
|
type UploadFile struct {
|
|
|
|
*multipart.FileHeader
|
|
|
|
}
|
|
|
|
|
2020-02-26 01:01:28 +08:00
|
|
|
// UploadFiles is array type for *UploadFile.
|
2020-02-26 00:48:27 +08:00
|
|
|
type UploadFiles []*UploadFile
|
|
|
|
|
2020-03-07 20:20:52 +08:00
|
|
|
// 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.
|
2020-02-26 00:48:27 +08:00
|
|
|
//
|
|
|
|
// The parameter <randomlyRename> specifies whether randomly renames the file name, which
|
|
|
|
// make sense if the <path> is a directory.
|
|
|
|
//
|
|
|
|
// Note that it will overwrite the target file if there's already a same name file exist.
|
2020-03-07 20:20:52 +08:00
|
|
|
func (f *UploadFile) Save(dirPath string, randomlyRename ...bool) (filename string, err error) {
|
2020-02-26 00:48:27 +08:00
|
|
|
if f == nil {
|
2020-03-15 20:11:38 +08:00
|
|
|
return "", errors.New("file is empty, maybe you retrieve it from invalid field name or form enctype")
|
2020-02-26 00:48:27 +08:00
|
|
|
}
|
2020-03-07 20:20:52 +08:00
|
|
|
if !gfile.Exists(dirPath) {
|
|
|
|
if err = gfile.Mkdir(dirPath); err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
} else if !gfile.IsDir(dirPath) {
|
|
|
|
return "", errors.New(`parameter "dirPath" should be a directory path`)
|
|
|
|
}
|
|
|
|
|
2020-02-26 00:48:27 +08:00
|
|
|
file, err := f.Open()
|
|
|
|
if err != nil {
|
2020-03-07 19:31:33 +08:00
|
|
|
return "", err
|
2020-02-26 00:48:27 +08:00
|
|
|
}
|
|
|
|
defer file.Close()
|
|
|
|
|
2020-03-07 20:20:52 +08:00
|
|
|
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)
|
2020-02-26 00:48:27 +08:00
|
|
|
}
|
2020-03-07 20:20:52 +08:00
|
|
|
filePath := gfile.Join(dirPath, name)
|
2020-03-04 17:29:23 +08:00
|
|
|
newFile, err := gfile.Create(filePath)
|
2020-02-26 00:48:27 +08:00
|
|
|
if err != nil {
|
2020-03-07 19:31:33 +08:00
|
|
|
return "", err
|
2020-02-26 00:48:27 +08:00
|
|
|
}
|
|
|
|
defer newFile.Close()
|
2020-03-04 17:29:23 +08:00
|
|
|
intlog.Printf(`save upload file: %s`, filePath)
|
2020-02-26 00:48:27 +08:00
|
|
|
if _, err := io.Copy(newFile, file); err != nil {
|
2020-03-07 19:31:33 +08:00
|
|
|
return "", err
|
2020-02-26 00:48:27 +08:00
|
|
|
}
|
2020-03-07 19:31:33 +08:00
|
|
|
return gfile.Basename(filePath), nil
|
2020-02-26 00:48:27 +08:00
|
|
|
}
|
|
|
|
|
2020-03-07 19:31:33 +08:00
|
|
|
// Save saves all uploading files to specified directory path and returns the saved file names.
|
2020-02-26 00:48:27 +08:00
|
|
|
//
|
|
|
|
// The parameter <dirPath> should be a directory path or it returns error.
|
|
|
|
//
|
|
|
|
// The parameter <randomlyRename> specifies whether randomly renames all the file names.
|
2020-03-07 19:31:33 +08:00
|
|
|
func (fs UploadFiles) Save(dirPath string, randomlyRename ...bool) (filenames []string, err error) {
|
2020-02-26 00:48:27 +08:00
|
|
|
if len(fs) == 0 {
|
2020-03-15 20:11:38 +08:00
|
|
|
return nil, errors.New("file array is empty, maybe you retrieve it from invalid field name or form enctype")
|
2020-02-26 00:48:27 +08:00
|
|
|
}
|
|
|
|
for _, f := range fs {
|
2020-03-07 19:31:33 +08:00
|
|
|
if filename, err := f.Save(dirPath, randomlyRename...); err != nil {
|
|
|
|
return filenames, err
|
|
|
|
} else {
|
|
|
|
filenames = append(filenames, filename)
|
2020-02-26 00:48:27 +08:00
|
|
|
}
|
|
|
|
}
|
2020-03-07 19:31:33 +08:00
|
|
|
return
|
2020-02-26 00:48:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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.
|
|
|
|
//
|
|
|
|
// 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.
|
|
|
|
//
|
|
|
|
// 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{
|
|
|
|
FileHeader: v,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return uploadFiles
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|