github.com/goravel/framework@v1.13.9/filesystem/local.go (about)

     1  package filesystem
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"os"
     8  	"path/filepath"
     9  	"strings"
    10  	"time"
    11  
    12  	"github.com/goravel/framework/contracts/config"
    13  	"github.com/goravel/framework/contracts/filesystem"
    14  	supportfile "github.com/goravel/framework/support/file"
    15  	"github.com/goravel/framework/support/str"
    16  )
    17  
    18  type Local struct {
    19  	config config.Config
    20  	root   string
    21  	url    string
    22  }
    23  
    24  func NewLocal(config config.Config, disk string) (*Local, error) {
    25  	return &Local{
    26  		config: config,
    27  		root:   config.GetString(fmt.Sprintf("filesystems.disks.%s.root", disk)),
    28  		url:    config.GetString(fmt.Sprintf("filesystems.disks.%s.url", disk)),
    29  	}, nil
    30  }
    31  
    32  func (r *Local) AllDirectories(path string) ([]string, error) {
    33  	var directories []string
    34  	err := filepath.Walk(r.fullPath(path), func(fullPath string, info os.FileInfo, err error) error {
    35  		if err != nil {
    36  			return err
    37  		}
    38  		if info.IsDir() {
    39  			realPath := strings.ReplaceAll(fullPath, r.fullPath(path), "")
    40  			realPath = strings.TrimPrefix(realPath, string(filepath.Separator))
    41  			if realPath != "" {
    42  				directories = append(directories, realPath+string(filepath.Separator))
    43  			}
    44  		}
    45  
    46  		return nil
    47  	})
    48  
    49  	return directories, err
    50  }
    51  
    52  func (r *Local) AllFiles(path string) ([]string, error) {
    53  	var files []string
    54  	err := filepath.Walk(r.fullPath(path), func(fullPath string, info os.FileInfo, err error) error {
    55  		if err != nil {
    56  			return err
    57  		}
    58  		if !info.IsDir() {
    59  			files = append(files, strings.ReplaceAll(fullPath, r.fullPath(path)+string(filepath.Separator), ""))
    60  		}
    61  
    62  		return nil
    63  	})
    64  
    65  	return files, err
    66  }
    67  
    68  func (r *Local) Copy(originFile, targetFile string) error {
    69  	content, err := r.Get(originFile)
    70  	if err != nil {
    71  		return err
    72  	}
    73  
    74  	return r.Put(targetFile, content)
    75  }
    76  
    77  func (r *Local) Delete(files ...string) error {
    78  	for _, file := range files {
    79  		fileInfo, err := os.Stat(r.fullPath(file))
    80  		if err != nil {
    81  			return err
    82  		}
    83  
    84  		if fileInfo.IsDir() {
    85  			return errors.New("can't delete directory, please use DeleteDirectory")
    86  		}
    87  	}
    88  
    89  	for _, file := range files {
    90  		if err := os.Remove(r.fullPath(file)); err != nil {
    91  			return err
    92  		}
    93  	}
    94  
    95  	return nil
    96  }
    97  
    98  func (r *Local) DeleteDirectory(directory string) error {
    99  	return os.RemoveAll(r.fullPath(directory))
   100  }
   101  
   102  func (r *Local) Directories(path string) ([]string, error) {
   103  	var directories []string
   104  	fileInfo, _ := os.ReadDir(r.fullPath(path))
   105  	for _, f := range fileInfo {
   106  		if f.IsDir() {
   107  			directories = append(directories, f.Name()+string(filepath.Separator))
   108  		}
   109  	}
   110  
   111  	return directories, nil
   112  }
   113  
   114  func (r *Local) Exists(file string) bool {
   115  	_, err := os.Stat(r.fullPath(file))
   116  	if err != nil {
   117  		return os.IsExist(err)
   118  	}
   119  	return true
   120  }
   121  
   122  func (r *Local) Files(path string) ([]string, error) {
   123  	var files []string
   124  	fileInfo, err := os.ReadDir(r.fullPath(path))
   125  	if err != nil {
   126  		return nil, err
   127  	}
   128  	for _, f := range fileInfo {
   129  		if !f.IsDir() {
   130  			files = append(files, f.Name())
   131  		}
   132  	}
   133  
   134  	return files, nil
   135  }
   136  
   137  func (r *Local) Get(file string) (string, error) {
   138  	data, err := r.GetBytes(file)
   139  
   140  	return string(data), err
   141  }
   142  
   143  func (r *Local) GetBytes(file string) ([]byte, error) {
   144  	data, err := os.ReadFile(r.fullPath(file))
   145  	if err != nil {
   146  		return nil, err
   147  	}
   148  
   149  	return data, nil
   150  }
   151  
   152  func (r *Local) LastModified(file string) (time.Time, error) {
   153  	return supportfile.LastModified(r.fullPath(file), r.config.GetString("app.timezone"))
   154  }
   155  
   156  func (r *Local) MakeDirectory(directory string) error {
   157  	return os.MkdirAll(filepath.Dir(r.fullPath(directory)+string(filepath.Separator)), os.ModePerm)
   158  }
   159  
   160  func (r *Local) MimeType(file string) (string, error) {
   161  	return supportfile.MimeType(r.fullPath(file))
   162  }
   163  
   164  func (r *Local) Missing(file string) bool {
   165  	return !r.Exists(file)
   166  }
   167  
   168  func (r *Local) Move(oldFile, newFile string) error {
   169  	newFile = r.fullPath(newFile)
   170  	if err := os.MkdirAll(filepath.Dir(newFile), os.ModePerm); err != nil {
   171  		return err
   172  	}
   173  
   174  	if err := os.Rename(r.fullPath(oldFile), newFile); err != nil {
   175  		return err
   176  	}
   177  
   178  	return nil
   179  }
   180  
   181  func (r *Local) Path(file string) string {
   182  	return r.fullPath(file)
   183  }
   184  
   185  func (r *Local) Put(file, content string) error {
   186  	file = r.fullPath(file)
   187  	if err := os.MkdirAll(filepath.Dir(file), os.ModePerm); err != nil {
   188  		return err
   189  	}
   190  
   191  	f, err := os.Create(file)
   192  	if err != nil {
   193  		return err
   194  	}
   195  	defer f.Close()
   196  
   197  	if _, err = f.WriteString(content); err != nil {
   198  		return err
   199  	}
   200  
   201  	return nil
   202  }
   203  
   204  func (r *Local) PutFile(filePath string, source filesystem.File) (string, error) {
   205  	return r.PutFileAs(filePath, source, str.Random(40))
   206  }
   207  
   208  func (r *Local) PutFileAs(filePath string, source filesystem.File, name string) (string, error) {
   209  	data, err := os.ReadFile(source.File())
   210  	if err != nil {
   211  		return "", err
   212  	}
   213  
   214  	fullPath, err := fullPathOfFile(filePath, source, name)
   215  	if err != nil {
   216  		return "", err
   217  	}
   218  
   219  	if err := r.Put(fullPath, string(data)); err != nil {
   220  		return "", err
   221  	}
   222  
   223  	return fullPath, nil
   224  }
   225  
   226  func (r *Local) Size(file string) (int64, error) {
   227  	return supportfile.Size(r.fullPath(file))
   228  }
   229  
   230  func (r *Local) TemporaryUrl(file string, time time.Time) (string, error) {
   231  	return r.Url(file), nil
   232  }
   233  
   234  func (r *Local) WithContext(ctx context.Context) filesystem.Driver {
   235  	return r
   236  }
   237  
   238  func (r *Local) Url(file string) string {
   239  	return strings.TrimSuffix(r.url, "/") + "/" + strings.TrimPrefix(filepath.ToSlash(file), "/")
   240  }
   241  
   242  func (r *Local) fullPath(path string) string {
   243  	realPath := filepath.Clean(path)
   244  
   245  	if realPath == "." {
   246  		return r.rootPath()
   247  	}
   248  
   249  	return filepath.Join(r.rootPath(), realPath)
   250  }
   251  
   252  func (r *Local) rootPath() string {
   253  	return strings.TrimSuffix(r.root, string(filepath.Separator)) + string(filepath.Separator)
   254  }