LARAVEL How to transfer file from local (public) to FTP using Laravel - laravel

I wanna ask a question, anyone know how to transfer data from local / public to ftp, I'm using Storage class
https://laravel.com/docs/5.4/filesystem
Here's my code
$file_local = Storage::disk('local')->get('public/uploads/ftp/file.pdf');
$file_ftp = Storage::disk('ftp')->put('/file.pdf', $file_local');
But my code is not working, when I open the file on ftp, the file is broken, then I open it with notepad, inside file, the content is 'public/uploads/ftp/file.pdf' the content I mean content should on local not what I was wrote,
Anyone know how to transfer file from local to ftp, sorry for my bad English, Thanks for your answer anyway

To get started, you should know the details of your FTP host, FTP username, and FTP password. Once, you are ready with the details open the .env files and add the details as below:
FTP_HOST=YOUR_FTP_HOST_VALUE
FTP_USERNAME=YOUR_FTP_USERNAME_VALUE
FTP_PASSWORD=YOUR_FTP_PASSWORD_VALUE
Make sure to replace the placeholders with the actual values. Next, open the config/filesystems.php file and add the ‘ftp’ configuration to the ‘disks’ array.
<?php
return [
......
'disks' => [
......
'ftp' => [
'driver' => 'ftp',
'host' => env('FTP_HOST'),
'username' => env('FTP_USERNAME'),
'password' => env('FTP_PASSWORD'),
'root' => 'DIR_PATH_TO_WHERE_IMAGE_STORE' // for example: /var/www/html/dev/images
],
],
];
Replace DIR_PATH_TO_WHERE_IMAGE_STORE with the actual path where you need to store images. For example, if we have folder called ‘images’ and path to this folder is /var/www/html/dev/images then this path will go as the value for ‘root’ in the above array.
For uploading files through FTP we need a form where a user can submit the image. Add the below code in your view file.
<form action="{{ url('PASS_ACTION_URL_HERE') }}" method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="exampleInputFile">File input</label>
<input type="file" name="profile_image" id="exampleInputFile" multiple />
</div>
{{ csrf_field() }}
<button type="submit" class="btn btn-default">Submit</button>
</form>
You should replace the PASS_ACTION_URL_HERE with your actual route. As we are using a Laravel Storage to file uploading user need add Facade to the controller file as follows:
public function store(Request $request)
{
if($request->hasFile('profile_image')) {
//get filename with extension
$filenamewithextension = $request->file('profile_image')->getClientOriginalName();
//get filename without extension
$filename = pathinfo($filenamewithextension, PATHINFO_FILENAME);
//get file extension
$extension = $request->file('profile_image')->getClientOriginalExtension();
//filename to store
$filenametostore = $filename.'_'.uniqid().'.'.$extension;
//Upload File to external server
Storage::disk('ftp')->put($filenametostore, fopen($request->file('profile_image'), 'r+'));
//Store $filenametostore in the database
}
return redirect('images')->with('status', "Image uploaded successfully.");
}
‘profile_image’ is the name of our file input. We build the unique name of our file and then uploading it to an external server. Notice we have used Storage::disk(‘ftp’) method. This function would store our file to the path as defined in the configuration. A user should store the value ‘$filenametostore’ in your database.

'local' => [
'driver' => 'local',
'root' => storage_path().'/app',
],
If you use the local disk (config/filesystems.php) you are looking in 'storage/app' not the public folder unless you have changed the default settings. So:
$file_local = Storage::disk('local')->get('file.pdf');
will look for 'Storage/App/file.pdf'
Make sure your pdf is in that folder and give this a try:
$file_local = Storage::disk('local')->get('file.pdf');
$file_ftp = Storage::disk('ftp')->put('file.pdf', $file_local);
EDIT: also, I notice in your original post second line of code you have rogue ' after $file_local ;)

Related

How do you delete and replace a .mp3 file using the Storage class in Laravel

I am building a tool that allows users to edit audio. My plan is this:
retrieve audio text from database and generate audio
store audio file in the Laravel storage system
if the user edits the audio, delete the old one
put the new audio file in the same location
However, I can easily delete the .mp3 file. But when I go to recreate the file the one that is played for the user is the old audio file. It will work sometimes but only every now and then.
My controller code
//this is called when the user retrieves the audio the first time and this is working fine
public function getAudioInfo(Request $request){
...
$audio = audio.mp3; //just for an example, this holds an .mp3 file
$path = "Audio/audio_type/audio_sub_type/";;
$audio_name = $name.".mp3";
$save_path = 'public/'.$path.$audio_name;
Storage::put($save_path , $audio_file);
//store needed variables in the session
Session::put('audio_url', Storage::url($path)); //used to listen to the audio
Session::put('audio_path', 'public/'.$path.$audio_name); //used to get the audio on html
return back()->with('success', 'Audio retrieved');
}
//this is where is breaks, it will delete the file but when it replaces it still plays the old
//audio for the user
public function displayUpdatedAudio(Request $request){
//session variables needed
$audio_path = Session::pull('audio_path');
...
$audio_file = new_audio.mp3;
//delete old file
Storage::delete($audio_path);
Storage::put($audio_path, $audio_file); //this is where it seems to fail
return back()->with('success', 'Audio retrieved');
}
my route
Route::get('preview_update', 'Admin\AudioController#displayUpdate')->name('preview_update');
my html
<form id="preview-audio" method="GET" action="{{ route('preview_update') }}">
<div class="input-field">
<audio controls id="audio">
<source src="#if(Session::has('audio_url')) <?php echo Session::get('audio_url'); ?> #endif" type="audio/mpeg">
</audio>
</div>
<button type="submit" id="listen-submit-update">Get Updated Audio</button>
</form>
The mp3 file is probably cached by the browser and never requested a second time. In order to avoid the browser cache, you either need to:
add some random stuff to your mp3 file URL
https://example.com/1.mp3?r=123
or set the no-cache headers to the server response so that the browser will not cache your file:
->withHeaders([
'Cache-Control' => 'no-cache, no-store, must-revalidate',
'Pragma' => 'no-cache',
'Expires' => '0',
]);

Laravel phpunit test maatwebsite/excel import

I've created an maatwebsite/excel import routine and i would like to test it.
The maatwebsite/excel testing page does not provide me with any other information than to fake it.
But i need to upload my real excel-file, as i want to validate whether the data from the excel file was processed correctly.
Here's my upload input field and the corresponding button to hit the endpoint /import
<form action="/import" method="post" enctype="multipart/form-data">
#csrf
<div class="form-group">
<input type="file" class="form-control-file file-path" name="fileToUpload">
</div>
<button type="submit" class="btn btn-primary">Import File</button>
</form>
on the controller side of view, the uploaded file will be processed and imported.
...
public function store(Request $request) {
$request->validate([
'fileToUpload' => 'required|file|max:4096|mimes:xls,xlsx',
]);
// start the import
Excel::import(new SheetNavigator, request()->file('fileToUpload'));
...
The file that needs to be imported is located within my testing environment under:
/tests
/files
/myexcel.xlsx
public function test_user_can_import_file() {
Excel::fake();
$datafile = new UploadedFile(
base_path('tests/files/myfile.xlsx'),
'myfile.xlsx',
'xlsx',
13071,
true);
$res = $this->post('/import', [
'fileToUpload' => $datafile
]);
// asserting, that everything works..
}
I need a test to verify that the upload was successful and that the import-routine was triggered.
I tried everything, from faking anything to using storages.
I appreciate any kind of help, thank you!
Chris
Generally speaking the ideal way to do this is by mocking the Excel class and then checking if import has been called with the given file. Despite the fact that this seems to be a static call it's actually a Facade call so you can swap it out with a mock. In fact it seems to offer this functionality on its own:
public function testThatItImportsTheUploadedFile() {
$file = UploadedFile::fake()->create('myexcel.xlsx');
Excel::fake();
$this->post('/import', [
'fileToUpload' => $file
]);
Excel::assertImported('myexcel.xlsx');
}
Note: This verifies that the endpoint works as expected given that the file is uploaded and Excel::import will work as expected.
If you want to test with your real file you can possibly create a new UploadedFile instance (linking the symfony base class since that's where the constructor is).
$file = new UploadedFile(
base_path('tests/files/myfile.xlsx'),
'myfile.xlsx',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
null,
true
);

Download zip folder based on form input - Codeigniter

I want to create search file form, where user search files based on year.I already made folder file in a years (ex. folder 2019, folder 2018, etc), so when user input value the results will show based on user input. I get the result that i want, but i can't download file as zip because the value og path folder is null. I already tried use input-> get and session-> set_flashdata, but the result still null. My question is how do I get the year value, so can direct to the path folder?
Note : tahun is years in english
Controller
public function download_zip() {
// Read files from directory
$tahun = $this->input->get('tahun');
if($this->input-post('but_createzip2') != NULL){
// File name
$filename = $tahun . _laporan.zip;
// Directory path (uploads directory stored in project root)
$path = './uploaded/laporan/'.$tahun.'/';
// Add directory to zip
$this->zip->read_dir($path, FALSE);
// Save the zip file to archivefiles directory
$this->zip->archive('./uploaded/backup_laporan/'. $filename);
// Download
$this->zip->download($filename);
}
// Load view
$this->load->view('v_detail_laporan');
}}
View
<form role="form" action="<?php echo base_url().'laporan'?>">
<input type = "text" id="tahun" name="tahun" class="form-control" placeholder="Masukkan Tahun" required/>
</form>
// Download
<?php echo form_open('laporan/download_zip'); ?>
You are posting dat using GET method then why are you made condition in POST method
public function download_zip() {
// Read files from directory
$tahun = $this->input->get('tahun');
if($this->input->get('tahun') != NULL){ // MODIFIED HERE YOU ARE PASSING VALUES USING GET METHOD
// File name
$filename = $tahun ."_laporan.zip";
// Directory path (uploads directory stored in project root)
$path = './uploaded/laporan/'.$tahun.'/';
// Add directory to zip
$this->zip->read_dir($path, FALSE);
// Save the zip file to archivefiles directory
$this->zip->archive('./uploaded/backup_laporan/'. $filename);
// Download
$this->zip->download($filename);
}
// Load view
$this->load->view('v_detail_laporan');
}
Try this code
You have a wrong form target, try to modify the codes be like below.
View :
<?php echo form_open('laporan/download_zip', ['method' => 'post', 'role' => 'form']); ?>
<?php echo form_hidden('but_createzip2','1');?>
<input type = "text" id="tahun" name="tahun" class="form-control" placeholder="Masukkan Tahun" required/>
<?php echo form_close(); ?>
Controller :
public function download_zip() {
// Read files from directory
$tahun = $this->input->post('tahun');
if($this->input-post('but_createzip2') != NULL){
// File name
$filename = $tahun . _laporan.zip;
// Directory path (uploads directory stored in project root)
$path = './uploaded/laporan/'.$tahun.'/';
// Add directory to zip
$this->zip->read_dir($path, FALSE);
// Save the zip file to archivefiles directory
$this->zip->archive('./uploaded/backup_laporan/'. $filename);
// Download
$this->zip->download($filename);
}
// Load view
$this->load->view('v_detail_laporan');
}

How to expose a image without saving to the public folder of Laravel

I'm making an application in Laravel where I need to save images that can not be accessible in the public folder along with my js and css.
I'm saving the images in the default Laravel folder, the storage/app folder. I wanted to know a way to expose these images without putting them in the public folder. I figured I could search the image first and send it to the view along with other data such as the user name and something else, but I'm not sure how to do it.
My configuration in the filesystems.php looks like this:
filesystems.php
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
In my view, I'm trying like this:
<img src="{{ url("files/{$file->getContent()}") }}" class="rounded-circle">
In this case, I'm trying to put an image that the user uploaded.
Create and endpoint to download your file:
Route::get('/file/download', function() {
// get your filepath
$filepath = 'path/to/image/image.png';
return Response::download($filepath);
});
Then in your view:
<img src="{{url('/file/download')}}" class="rounded-circle" />

Laravel unisharp file manager combine file and image manager

Last week I discovered the Unisharp file manager plugin.
After a lot of tweaking on the plugin i managed to get the plugin working in my browser without opening a new page (Like you supposed to get with the plugin)
A view from my browser:
The first image are my images that i have uploaded and the second picture is my files that i have uploaded.
Now my problem is that I'am trying to get them both in 1 file manager so the files and images are together in one file manager.
I have tried to tweak the config/lfm.php, public/photos/ into public/files/ like you see here below
just like where the files are linked to but when i do that the images and files that i have previous uploaded wont load
So if you got any suggestions on how to combine the files and images manager together or got a other suggestion for an other plugin it would be great,
Greetings,
Noah
Full disclosure: I am the package maintainer, work for UniSharp.
You have done it well!
The only problem is, images have thumbs while files don't(files show icons).
When the get parameter "type" is set to be "Image"(link here), files and images will show but the thumbs of files will left broken.
Solution: You can set default image like below, in case of broken file thumbs.
<img onclick="useFile('{{ $file_name }}')" onError="this.src='/img/default.jpg'">
So after seeing the comment #Stream Huang. I manage to get it working, its true that the image got thumbs and the files like a pdf dont.
First thing that I did was at the UploadController#Upload change
if ('Images' === $this->file_type) {
$this->makeThumb($dest_path, $new_filename);
}
After that I made a variable that get the extension/file name of the file that you just uploaded and filter it on images.
$fileName = $file->getMimeType();
if ($fileName == "image/jpeg" || $fileName == "image/png") {
$this->makeThumb($dest_path, $new_filename);
}
In the ItemController I added a [$key] to the array
ItemController#getFileInfos (original)
$file_info[$key] = [
'name' => $file_name,
'size' => $file_size,
'created' => $file_created,
'type' => $file_type,
'icon' => $icon,
];
to:
$file_info[$key] = [
'name' => $file_name,
'size' => $file_size,
'created' => $file_created,
'type' => $file_type,
'icon' => $icon,
'title' => $file_data[$key]->title,
'alt' => $file_data[$key]->alt,
'id' => $file_data[$key]->id,
];
The title,alt and id are comming from the database (When I upload a image I first need to enter a title, alt and the image before uploading it. The data that I have I store it in the database so I can use that data for like a news article).
I also changed a couple of blades mainly the item and the index
item.blade.php (original)
#if($type == 'Images')
<img id="{{ $file_name }}" src="{{ asset($thumb_src) }}" class="pointer" onclick="useFile('{{ $file_name }}')">
#else
<i class="fa {{ $file['icon'] }} fa-5x" style="height:200px;cursor:pointer;padding-top:60px;" onclick="useFile('{{ $file_name }}')"></i>
#endif
item.blade.php (edit)
$file_name = $file_info[$key]['name'];
$filebroken = substr($file_name, -3);
$extension = array_pop($filebroken);
The file_info[$key]['name'] is a file name that is getting from the database just like image.jpg , i get the last 3 characters of the name so its most likely .jpg or .png if its a image.
After that I'm checking if $extension variable is a jpg or a png, else i make it a icon of it.
#if($extension == 'png' || $extension == 'jpg')
<img id="{{ $file_name }}" src="{{ asset($thumb_src) }} class="pointer" onclick="useFile('{{ $file_name }}')">
#else
<i class="fa {{ $file['icon'] }} fa-5x" onclick="useFile('{{ $file_name }}')"></i>
#endif

Resources