github.com/gogf/gf@v1.16.9/net/ghttp/ghttp_request_param_file.go (about)

     1  // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/gogf/gf.
     6  
     7  package ghttp
     8  
     9  import (
    10  	"context"
    11  	"github.com/gogf/gf/errors/gcode"
    12  	"github.com/gogf/gf/errors/gerror"
    13  	"github.com/gogf/gf/internal/intlog"
    14  	"github.com/gogf/gf/os/gfile"
    15  	"github.com/gogf/gf/os/gtime"
    16  	"github.com/gogf/gf/util/grand"
    17  	"io"
    18  	"mime/multipart"
    19  	"strconv"
    20  	"strings"
    21  )
    22  
    23  // UploadFile wraps the multipart uploading file with more and convenient features.
    24  type UploadFile struct {
    25  	*multipart.FileHeader
    26  	ctx context.Context
    27  }
    28  
    29  // UploadFiles is array type for *UploadFile.
    30  type UploadFiles []*UploadFile
    31  
    32  // Save saves the single uploading file to directory path and returns the saved file name.
    33  //
    34  // The parameter <dirPath> should be a directory path or it returns error.
    35  //
    36  // Note that it will OVERWRITE the target file if there's already a same name file exist.
    37  func (f *UploadFile) Save(dirPath string, randomlyRename ...bool) (filename string, err error) {
    38  	if f == nil {
    39  		return "", gerror.NewCode(
    40  			gcode.CodeMissingParameter,
    41  			"file is empty, maybe you retrieve it from invalid field name or form enctype",
    42  		)
    43  	}
    44  	if !gfile.Exists(dirPath) {
    45  		if err = gfile.Mkdir(dirPath); err != nil {
    46  			return
    47  		}
    48  	} else if !gfile.IsDir(dirPath) {
    49  		return "", gerror.NewCode(gcode.CodeInvalidParameter, `parameter "dirPath" should be a directory path`)
    50  	}
    51  
    52  	file, err := f.Open()
    53  	if err != nil {
    54  		return "", err
    55  	}
    56  	defer file.Close()
    57  
    58  	name := gfile.Basename(f.Filename)
    59  	if len(randomlyRename) > 0 && randomlyRename[0] {
    60  		name = strings.ToLower(strconv.FormatInt(gtime.TimestampNano(), 36) + grand.S(6))
    61  		name = name + gfile.Ext(f.Filename)
    62  	}
    63  	filePath := gfile.Join(dirPath, name)
    64  	newFile, err := gfile.Create(filePath)
    65  	if err != nil {
    66  		return "", err
    67  	}
    68  	defer newFile.Close()
    69  	intlog.Printf(f.ctx, `save upload file: %s`, filePath)
    70  	if _, err := io.Copy(newFile, file); err != nil {
    71  		return "", err
    72  	}
    73  	return gfile.Basename(filePath), nil
    74  }
    75  
    76  // Save saves all uploading files to specified directory path and returns the saved file names.
    77  //
    78  // The parameter <dirPath> should be a directory path or it returns error.
    79  //
    80  // The parameter <randomlyRename> specifies whether randomly renames all the file names.
    81  func (fs UploadFiles) Save(dirPath string, randomlyRename ...bool) (filenames []string, err error) {
    82  	if len(fs) == 0 {
    83  		return nil, gerror.NewCode(
    84  			gcode.CodeMissingParameter,
    85  			"file array is empty, maybe you retrieve it from invalid field name or form enctype",
    86  		)
    87  	}
    88  	for _, f := range fs {
    89  		if filename, err := f.Save(dirPath, randomlyRename...); err != nil {
    90  			return filenames, err
    91  		} else {
    92  			filenames = append(filenames, filename)
    93  		}
    94  	}
    95  	return
    96  }
    97  
    98  // GetUploadFile retrieves and returns the uploading file with specified form name.
    99  // This function is used for retrieving single uploading file object, which is
   100  // uploaded using multipart form content type.
   101  //
   102  // It returns nil if retrieving failed or no form file with given name posted.
   103  //
   104  // Note that the <name> is the file field name of the multipart form from client.
   105  func (r *Request) GetUploadFile(name string) *UploadFile {
   106  	uploadFiles := r.GetUploadFiles(name)
   107  	if len(uploadFiles) > 0 {
   108  		return uploadFiles[0]
   109  	}
   110  	return nil
   111  }
   112  
   113  // GetUploadFiles retrieves and returns multiple uploading files with specified form name.
   114  // This function is used for retrieving multiple uploading file objects, which are
   115  // uploaded using multipart form content type.
   116  //
   117  // It returns nil if retrieving failed or no form file with given name posted.
   118  //
   119  // Note that the <name> is the file field name of the multipart form from client.
   120  func (r *Request) GetUploadFiles(name string) UploadFiles {
   121  	multipartFiles := r.GetMultipartFiles(name)
   122  	if len(multipartFiles) > 0 {
   123  		uploadFiles := make(UploadFiles, len(multipartFiles))
   124  		for k, v := range multipartFiles {
   125  			uploadFiles[k] = &UploadFile{
   126  				ctx:        r.Context(),
   127  				FileHeader: v,
   128  			}
   129  		}
   130  		return uploadFiles
   131  	}
   132  	return nil
   133  }