Hi need help in creating nested folders.
I currently have a folder called images and i would like to clone the folders and save it in a different folder call backup. and the backup will only happen when user clicks backup.
For example:
- Images
- Car
- A
- A1
- A1-1
- A2
- B
- Van
How can i write the code so that it will create the folders?
Currently i have done this so how can i do it?
public function sync(Request $request)
{
$arr = [];
$folderToSync = $request->input('folderName');
$originalPath = public_path($folderToSync);
$newFolderPath = public_path('S3/'.$folderToSync);
$this->createFolder($newFolderPath); // create the selected folder
$directories = $this->getAllFolders($originalPath); // getting all folders under the original path
$this->folder($directories, $newFolderPath, $originalPath);
dd('end');
}
public function createFolder($path)
{
if (!is_dir($path)) {
#mkdir($path, 0777, true);
}
}
public function folder($directories, $newFolderPath, $originalPath)
{
foreach ($directories as $directory) {
$newPath = $newFolderPath.'/'.$directory;
$oriPath = $originalPath.'/'.$directory;
$this->createFolder($newPath);
$subFolders = $this->getAllFolders($oriPath);
if ($subFolders) {
$this->subfolder($subFolders, $newPath);
}
}
}
public function subfolder($directories, $path)
{
foreach ($directories as $directory) {
$this->createFolder($path.'/'.$directory);
}
}
public function getAllFolders($path)
{
return array_map('basename', \File::directories($path));
}
public function getAllFiles($path)
{
return;
}
but its not creating the subfolders. How can i modify it ?
i would run the code every week and i want to check also which folder have been created and which have not been created. if the folder does not exist then create the folder.
I would have a look at the storage api from the Laravel documentation: https://laravel.com/docs/5.7/filesystem#directories
To acquire folders and subfolders:
// Recursive...
$directories = Storage::allDirectories($directory);
Creating a new directory:
Storage::makeDirectory($directory);
Storing files:
Storage::put('file.jpg', $contents);
Storage::put('file.jpg', $resource);
The put method will take either the file contents or a resource.
Don't forget to include the Storage facade:
use Illuminate\Support\Facades\Storage;
Related
I'm using Laravel 8.35.1 and try to check if a folder exists or - if not - create it.
The paths are:
data/4d61c171-cd94-48ec-82bb-8fee7394471a/processor/333afcbc-37be-4e19-bddc-605c21e766bb
data/4d61c171-cd94-48ec-82bb-8fee7394471a/downloads/333afcbc-37be-4e19-bddc-605c21e766bb
The folders should be created in storage/app/.
I do the same for both paths:
$processFolder = $fileHelper->existOrCreate('data/4d61c171-cd94-48ec-82bb-8fee7394471a/processor/333afcbc-37be-4e19-bddc-605c21e766bb');
$downloadFolder = $fileHelper->existOrCreate('data/4d61c171-cd94-48ec-82bb-8fee7394471a/downloads/333afcbc-37be-4e19-bddc-605c21e766bb');
public function existOrCreate($path)
{
if (!File::exists($path)) {
if (!File::makeDirectory($path, 0755, true)) {
send_error_mail('Folder could not be created: ' . $path);
}
}
return $path;
}
The problem is, that always the downloads folder is wrongly created in
/public/data/4d61c171-cd94-48ec-82bb-8fee7394471a/downloads/333afcbc-37be-4e19-bddc-605c21e766bb
and the processor folder is correctly created in
/storage/app/data/4d61c171-cd94-48ec-82bb-8fee7394471a/processor/333afcbc-37be-4e19-bddc-605c21e766bb
Any ideas?
Use the Storage facade instead of the File facade.
I have a form input which can upload multiple files. So all the files paths are saved in the database as an array of strings . Below is my controller to download the files. I wanted to know how I can go about presenting each file to be downloaded in blade view. So I could download a single file at a time. My controller below. It works only when downloading a single file. I get this error Invalid argument supplied for foreach().
public function download($id) {
$deal = Deal::findorFail($id);
$files = $deal->uploads;
foreach ($files as $file) {
return Storage::download($file);
}
}
public function download($id) {
$deal = Deal::findorFail($id);
$files = $deal->uploads;
foreach ($files as $file) {
return Storage::download($file);
--------^^^^^^-------------------------
}
}
when you return first file, it breaks foreach loop. So you have to return all files together. And only way to achieve this, is creating a zip file that contains all files..
For this purpose you may use chumper/zipper package
$zipper = Zipper::make(public_path('/documents/deals.zip'));
foreach ($files as $file) {
$zipper->add(public_path($file)); // update it by your path
}
$zipper->close();
return response()
->download(
public_path('/temporary_files/' . "deals.zip"),
"deals.zip",
["Content-Type" => "application/zip"]
);
update
Add accessor to Deal model to get files as array
Deal Model
php artisan getUploadsAttribute($attribute){
return explode(",",$attributes);
}
I need to list files from storage->app->public->huetten->it contains 17 folders. Each folder contains images. Any help would be appreciated.
public function show($id)
{
if(!empty($id)) {
$directories = Storage::disk('public')->allDirectories('huetten');
foreach ($directories as $directory) {
//dd($directory); // Here i get huetten/folder1
$files = Storage::files($directory);
foreach ($files as $file) {
dd($file); // But here files are not listing
}
}
}
}
Storage uses the default Filesystem disk in config/filesystems.php which is set to local (i.e storage/app/) in a fresh Laravel project.
I assume that it is set to this same value in your project.
You want to list files in storage/app/public, and this corresponds to the public disk in config/filesystems.php.
In your loop, you can correctly the search directory by getting a Filesystem instance that for the public disk like you already do when listing the directories.
$files = Storage::disk('public')->files($directory);
/* [ 'storage/app/public/huetten/folder1/foo', 'storage/app/public/huetten/folder1/bar', ...] */
Im building an application where I need to dynamically create some directories using the Azure's PHP SDK.
I did it using a loop but Im unsure if thats the correct way of doing it so heres my code;
I cant create a path that already exists so I have to check level by level if a directory and exists, than enters it and repeat.
public function generateDirectory($path)
{
$pathArray = explode("/", $path);
$currentPath = "";
try {
foreach ($pathArray as $key => $slice) {
$directories = $this->fileClient->listDirectoriesAndFiles("abraco", $currentPath)->getDirectories();
$currentPath .= $slice . "/";
$exists = false;
foreach ($directories as $key => $directory) {
if ($directory->getName() === $slice) {
$exists = true;
break;
}
}
if (!$exists) {
$this->fileClient->createDirectory("abraco", $currentPath);
}
}
return true;
} catch (Exception $e) {
return false;
}
}
Doesnt it should have a method to create a full path with subfolders? I think that this way is not performatic.
Doesnt it should have a method to create a full path with subfolders? I think that this way is not performatic.
I agree with you that there is a method to create a full path with subfolders will be better.
But currently, as you metioned that if we want to create full path with subfolders, we need to create the directory folder level by level.
If you use fiddler to capture request while you create multi-level directory structure via PHP SDK,you could find it use the following Rest API
https://myaccount.file.core.windows.net/myshare/myparentdirectorypath/mydirectory?
restype=directory
For more information please refer to Azure file Storage Create directory API.
myparentdirectorypath Optional. The path to the parent directory where mydirectory is to be created. If the parent directory path is omitted, the directory will be created within the specified share.
If specified, the parent directory must already exist within the share before mydirectory can be created.
I am studying some laravel code that I downloaded and I am getting some problem.
This supposed to be the functions to save,delete and download the files but the problem is.
The files are being saved in a folder named with a number on "storage\app\public\project-files\" (i.e. storage\app\public\project-files\11), both destroy and download methods are referencing different paths, I tried to change but didn't worked, download show FileNotFoundException and destroy just remove from the database but not from the folder
So is this code wrong? How It supposed to be?
I've read about using artisan:link but seems odd to me run this command every time I want upload a file to make a link
PS. I cheched the routes, so the methods are being called
Thanks
public function store(Request $request)
{
if ($request->hasFile('file')) {
$file = new ProjectFile();
$file->user_id = $this->user->id;
$file->project_id = $request->project_id;
$request->file->store('public/project-files/'.$request->project_id);
$file->filename = $request->file->getClientOriginalName();
$file->hashname = $request->file->hashName();
$file->size = $request->file->getSize();
$file->save();
$this->project = Project::find($request->project_id);
return view('project-files');
}
public function destroy($id)
{
$file = ProjectFile::find($id);
File::delete('storage/project-files/'.$file->project_id.'/'.$file->hashname);
ProjectFile::destroy($id);
$this->project = Project::find($file->project_id);
return view('project-files');
}
public function download($id) {
$file = ProjectFile::find($id);
return response()->download('storage/project-files/'.$file->project_id.'/'.$file->hashname);
}
You are storing files in storage so i assume you have uploaded image in the following path
project\storage\app\public\project-files
if this is the path then you can delete using
Storage::delete('public/project-files/1.JPG');
for Downlaoding file
$path= storage_path('app/public/project-files/3.JPG');
return response()->download($path);