Laravel Response::download() without exposing download path - laravel-4

I am a bit confused with Response::download() in Laravel 4.2
I would like to trigger a download of a ZIP archive without exposing the actual public path of the file..
This is the error I am getting when accessing the route
Symfony \ Component \ HttpKernel \ Exception \ NotFoundHttpException
My ROUTE is written like this:
/*
/ Download Package (GET)
*/
Route::get('/download-packages/{$package}', array(
'as' => 'download-package',
'uses' => 'DownloadController#getPackageDownload'
));
In the Controller getPackageDownload function is written like this:
public function getPackageDownload( $package ){
$file = public_path() . "/downloads/packages/" . $package . ".zip" ;
$name = $package . ".zip";
$headers = array(
'Content-Type' => 'application/zip',
);
return Response::download($file, $name, $headers);
}
My View button code:
Download</div>
The Download link generated in the view is something like this
http://app.dev/laravel/public/download-packages/package-name
It is different from the actual public location of the ZIP file but that is desired and my understanding is that the response should be triggered in the getPackageDownload function.

So, after walking away from the code and coming back to it with refreshed eyes it turns out I simply had a routing error,, routing parameter $package should not have "$" in front of it..
/*
/ Download Package (GET)
*/
Route::get('/download-packages/{package}', array(
'as' => 'download-package',
'uses' => 'DownloadController#getPackageDownload'
));

Related

Laravel route group is not taken properly

I created 2 route groups in my api route file, and I can't access to routes of second group.
First group :
$api = app('Dingo\Api\Routing\Router');
$request = app('\Dingo\Api\Http\Request');
$api->dispatch($request);
/* API V1 ROUTES */
$prefix = 'test';
$api->group(['prefix' => $prefix,'version'=> 'v1'],function($api) {
$api->post('/entity/validate/{code}', [
'as' => 'validate.code',
'uses' => 'App\Http\Controllers\XXX\Api\SmsController#validateCodeV1',
]);
});
This is working perfectly and I reach my function validateCodeV1 that does perfectly its job.
On another side I have right after it
Second group :
$prefix = 'testv2';
$api->group(['prefix' => $prefix,'version'=> 'v2'],function($api) {
$api->post('/entity/validate/{code}', [
'as' => 'validate.code',
'uses' => 'App\Http\Controllers\XXX\Api\SmsController#validateCode',
]);
});
Here I have a 404 when I try to call my api with a prefix testv2/entity/validate/XXX
I don't know how I can specify properly my prefix to swap from my v1 route to my v2 route...
I use Laravel 5.5
EDIT :
check of routes contains only one of my 2 routes, even after cache clear :
php artisan route:list | grep entity/validate
| | POST | /test/entity/validate/{code} | validate.code | Closure | api.controllers |
I've tried your code and change the $api-> to Route:: and both work as they should and listed in php artisan route:list.
$prefix = 'test';
Route::group(['prefix' => $prefix,'version'=> 'v1'],function($api) {
Route::post('/entity/validate/{code}', [
'as' => 'validate.code',
'uses' => 'App\Http\Controllers\XXX\Api\SmsController#validateCodeV1',
]);
});
$prefix = 'testv2';
Route::group(['prefix' => $prefix,'version'=> 'v2'],function($api) {
Route::post('/entity/validate/{code}', [
'as' => 'validate.code',
'uses' => 'App\Http\Controllers\XXX\Api\SmsController#validateCode',
]);
});
I think, you can check your $api or $request, maybe there is an error, function, or something else that only allow v1 version.
I fixed it by mixing the 2 solutions of this post :
Dingo API - How to add version number in url?
It is not exactly a duplicate so I let my post, but if someone think it is appropriated to remove my post just ask and I will do it

update file name of a file and updating data in database at the same time in laravel

I have a working upload file function. here's the code
public function store(Request $request)
{
$request->validate([
'name' => 'required',
'filename' => 'required|mimes:jpeg,png,jpg,gif,svg,doc,docx,xls,xlsx,pdf,txt|max:2048',
]);
$fileName = auth::user()->id.'_'.$name.'.'.request()->filename->getClientOriginalExtension();
request()->filename->storeAs('files', $fileName);
File::create ([
'name' => $name,
'filename' => $fileName,
'user_id' => $request['user_id'],
'extension' => request()->filename->getClientOriginalExtension(),
]);
return redirect('dashboard/files')->with('flash_message', 'File added!');
}
now my problem is how am I going to update the filename of the file once I update the name in the database?
thanks in advance!
Well you may want to look at observers. That would be good practise.. Observers fires when CRUD operations done. So when you change a file name on database, you'll be there through observers.
first create an observer.
php artisan make:observer FileObserver --model=File
then register your observer on AppServiceProvider::boot.
public function boot()
{
File::observe(FileObserver::class);
}
Open your FileObserver and edit "updated" method. Below method will run when a file record updated through File model.
public function updated(File $file)
{
// get old file name
$dirty = $file->getDirty();
$oldFileName = $dirty["filename"] . "." . $file->extension;
// get new file name
$newFileName = $file->filename . "." . $file->extension;
// replace old file name with new
Storage::move('files/' . $oldFileName, 'files/' . $newFileName);
}

How i can upload image to public folder in shared hosting laravel 5

I moved my website from localhost to shared hosting all it's good, but i need when i upload file stored directly to public_html: something like this
public_html/storage/
I tried use somenthing like :
symlink('/home/abdoweb/bmcelarave/storage/app/public', '/bmce/public_html/storage')
the problem still exists.
my Controller :
public function addcategory(Request $request){
$title = $request->input('category_name');
$image = $request->file('category-image');
$name = $image->getClientOriginalName();
$image->move(storage_path().'/app/public/category',$name);
$data[] = $name;
$query= DB::table('category')->insert(
[
'title' => $title,
'image' => $name,
"created_at" => Carbon::now()
]);
if($query){
return redirect('categories');
}
}
My folder :
home/abdoweb/{bmcelaravel} <= my public folder
Core laravel :
home/{bmce} <= core laravel
Thank you.
You can a use storage driver :
Inside config/filesystems.php :
'disks' => [
'public' => [
'driver' => 'local',
'root' => public_path() . '/uploads',
'url' => env('APP_URL').'/public',
'visibility' => 'public',
]
]
//Now you can move the file to storage like :
Storage::disk('public')->putFile('category', $request->file('category-image'));
First of all the recommended location for that stuff is to stay on the public path not creating a new one, unless there is an actual reason for that. Did you actually check that the symlink was created?
Laravel has an own command the create a symlink from storage/app/public to public/storage (the storage folder will be generated afterwards):
php artisan storage:link
But if you want to create defaults symlinks you should create one for yourself, like you already did.
This is the symlink pattern:
ln -s target source (fill in your target and source path)
So if you actually get the correct file from your request, this code should work:
Storage::putFile($name, $request->file('category-image'));
For more and detailed infos look into the filesystem documentation

How to do an actual file upload with phpunit and Laravel that's not fake

Phpunit, Laravel 5.5
How do I emulate, not fake, an actual file upload with phpunit and Laravel. My latest stab at it is like this. From the unit test:
$handle = fopen($path,'r');
$content = fread($handle,2048);
fclose($handle);
$fdata = [
'delimiter' => '3',
'id' => 1,
'allow_shared_roles' => 'on',
'file'=>$name
];
$this->call('POST','/event/add-wizard/2',$fdata,[],[],[
'Content-Length'=>strlen($content),
'Content-Type'=>'multipart/form-data;boundary='.$content,
'Content-Disposition'=>'form-data;name="file";filename="'.$name.'"'
],$content);
Then on the server side, this is where I get hung up.
if ($request->hasFile('file')) {
$input['extension'] = strtolower($request->file('file')->getClientOriginalExtension());
}
$validator = \Validator::make($input, ['file' => 'required', 'extension' => 'in:csv', 'delimiter' => 'required'], ['extension.in' => 'The file must be a .csv file.']);
if ($validator->fails()) {
return \Redirect::back()->withInput()->withErrors($validator);
}
if (!file_exists(storage_path('temp-files'))) {
\File::makeDirectory(storage_path('temp-files'));
}
$date = \Carbon\Carbon::now();
$tmpFile = $request->file('file')->move(storage_path('temp-files'), $date->format('YmdHis') . '_' . $request->file('file')->getClientOriginalName());
Then I get move on null error on the last line shown.
Having never done this kind of thing before I admit I'm stabbing in the dark. Any help would be greatly appreciated.
After confirming in the comments that you want to check if the upload routine is being followed instead really uploading a file you can mock the facade File to see if the methods are called and with the right parameters (optional).
To mock a Facade in Laravel you can use the build in shouldReceive('method_name') method. In your situation you can add this before the call:
// should create new directory
File::shouldReceive('makeDirectory')
->once();
// should move the uploaded file to the dir
File::shouldReceive('move')
->once()
->andReturn( $fake_file );
You can read more about mocking facades here.

Laravel writing the correct variable to the URL and getting the route to pick it up

So I have these 2 routes:
/*
* Account Activate (GET)
*/
Route::get('/account/activate/{code}', array(
'as' => 'account-activate',
'uses' => 'AccountController#getActivate'
));
/*
* Account Activate EMPTY-CODE (GET)
*/
Route::get('/account/activate/', array(
'as' => 'account-activate',
'uses' => 'AccountController#getActivateEmpty'
));
They are meant to pick up the code from a URL like this: http://localhost:81/account/activate?duYCzo5TEhmRFMBnDEJUSY4EO81EBCJlOyccVBNxpNPksBg6bJJrvUVV4XnX
Unfortunately as you can see the URL isn't activate/code it's activate?code.
This is the code creating the URL (its in a Mail function):
'link' => URL::route('account-recover-code', $code)
What can I change to make sure my route works as intended?
You may try this:
URL::route('account-activate', array('code' => $code));
Also use only one route declaration and make the {code} optional using ? like this:
Route::get('/account/activate/{code?}', array(
'as' => 'account-activate',
'uses' => 'AccountController#getActivate'
));
The URL::route() method expects the route name, which is as value in the route declaration and in {code?} the ? made the parameter optional so if you pass a code to your route then you can pass it as array('code' => $code) and if you dont want to pass the parameter then just use following code to generate the URL:
URL::route('account-activate');
In this case your method should be like:
public function getActivate($code = NULL)
{
if(!is_null($code)) {
// $code is available
}
else {
// $code is not passed
}
}

Resources