Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
gilour
/
foundation
/
src
/
Files
/
Actions
:
StoreFile.php
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
<?php namespace Common\Files\Actions; use Common\Files\FileEntryPayload; use Illuminate\Contracts\Filesystem\Filesystem; use Illuminate\Http\File; use Illuminate\Http\UploadedFile; use Illuminate\Support\Arr; use Illuminate\Support\Facades\File as FileFacade; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Str; use League\Flysystem\Local\LocalFilesystemAdapter; use Symfony\Component\Mime\MimeTypes; class StoreFile { protected Filesystem $disk; protected array $diskOptions; protected FileEntryPayload $payload; public function execute( FileEntryPayload $payload, array $fileOptions, ): string|false { $this->disk = $payload->public ? Storage::disk('public') : Storage::disk('uploads'); $this->diskOptions = [ 'mimetype' => $payload->clientMime, 'visibility' => $payload->visibility, ]; $this->payload = $payload; if ( // prevent uploading .htaccess files $payload->filename === '.htaccess' || // dont store php files in public disk ($payload->public && $this->isPhpFile($payload, $fileOptions)) || // prevent path traversal or storing at root in user specified folder ($payload->diskPrefix && (Str::contains($payload->diskPrefix, '..') || $payload->diskPrefix === '/')) ) { abort(403); } if (isset($fileOptions['file'])) { return $this->storeUploadedFile($fileOptions['file']); } elseif (isset($fileOptions['contents'])) { return $this->storeStringContents($fileOptions['contents']); } elseif (isset($fileOptions['path'])) { // if source and destination is local (and not temp dir) move file // instead of copying or using streams, this will be a lot faster if ( Arr::get($fileOptions, 'moveFile') === true && $this->disk->getAdapter() instanceof LocalFilesystemAdapter ) { return $this->storeLocalFile($fileOptions['path']); } else { return $this->storeUploadedFile(new File($fileOptions['path'])); } } return false; } protected function storeUploadedFile(File|UploadedFile $file): string|false { return $this->disk->putFileAs( $this->payload->diskPrefix, $file, $this->payload->filename, $this->diskOptions, ); } protected function storeStringContents(string $contents): string|false { return $this->disk->put( "{$this->payload->diskPrefix}/{$this->payload->filename}", $contents, $this->diskOptions, ); } protected function storeLocalFile(string $sourcePath): string|false { $dirPath = $this->disk->path($this->payload->diskPrefix); FileFacade::ensureDirectoryExists($dirPath); $stored = @rename($sourcePath, "$dirPath/{$this->payload->filename}"); if ($stored) { return "{$this->payload->diskPrefix}/{$this->payload->filename}"; } return false; } protected function isPhpFile( FileEntryPayload $payload, array $fileOptions, ): bool { if ( Str::of($payload->clientExtension) ->lower() ->startsWith(['php', 'phtml']) ) { return true; } $mimeType = null; if (isset($fileOptions['file'])) { $mimeType = $fileOptions['file']->getMimeType(); } elseif (isset($fileOptions['path'])) { $mimeType = MimeTypes::getDefault()->guessMimeType( $fileOptions['path'], ); } return $mimeType === 'application/x-php'; } }