Laravel Upload Image and Generate Random ID as name - laravel

Whats the best way to generate and random ID number for every image where i want upload in Laravel 5?
My Upload:
<input type="file" id="mypicture" name="mypicture">
Controller:
public function MyPicture(Request $request){
$user = Auth::user();
$user->mypicture= $request->mypicture;
$user->save();
return redirect()->back();
}
Thats the way i do it always for other things:
->uniqueid = 'VA'.str_random(28);
how can i add it to my Controller for image name?
And how can i use only alphabetic character not numbers? Or i must change my DB Table.
Thanks

Try this:
public function MyPicture(Request $request){
$user = Auth::user();
$user->mypicture = date('mdYHis') . uniqid() . $request->mypicture;
$user->save();
return redirect()->back();
}
You can use Date (Y-m-d H:i:s) and uniqid() to generate unique name every file.

use uniqid()
if (Input::hasFile('mypicture')) {
$mypicture = Input::file('mypicture');
$user->mypicture= uniqid().$mypicture->getClientOriginalName();
}

Do the same here:
$user = Auth::user();
$user->mypicture = $request->mypicture;
$user->filename = str_random(28);
$user->save();
$request->mypicture->storeAs('images', $user->filename);
If you want to use only letters, use one of the existing solutions.

Laravel has an inbuilt method for this, using their File facade.
From laravel docs:
$path = $request->file('avatar')->store('avatars');
return $path;
By default, the store method will generate a unique ID to serve as the file name. The path to the file will be returned by the store method so you can store the path, including the generated file name, in your database.

Related

Laravel unlink method

can someone tell me how to unlink image from public path when product is deleted.
My current code which does not work:
public function destroy($id)
{
$product = Product::findOrFail($id);
$image_path = '/uploads/products/' . $product->image;
if(file_exists($image_path)){
unlink($image_path);
}
$product->delete();
}
Also tried:
$product = Product::findOrFail($id);
if(file_exists($product->image)){
unlink($product->image);
}
$product->delete();
Also I am using accessor so my $product->image is returning:
"http://myeshop.local/uploads/products/1593902362bluesocksupd.jpg"
Here is accessor code:
public function getImageAttribute($image){
return asset($image);
}
use model deleted event
//Product Model
protected static function boot()
{
parent::boot();
static::deleted(function($product){
// getOriginal skip accessor
$image = public_path('uploads/products/' . $product->getOriginal('image'));
if(file_exists($image)) {
unlink($image);
}
});
}
unlink($path) is a PHP function. It will delete a file located at a local path. According to your question the value of $product->image is the complete URL to the image. If it is then the following is true:
$product = Product::findOrFail($id);
$image_path = '/uploads/products/' . $product->image;
// $image_path = '/uploads/products/http://myeshop.local/uploads/products/1593902362bluesocksupd.jpg'
// and it needs to point to '/PATH/TO/LARAVEL/uploads/products/1593902362bluesocksupd.jpg'
// the following file_exists() will return false
if(file_exists($image_path)){
unlink($image_path); // so you never get here
}
There are some quick and dirty ways to fix this, but the best thing to do is to have the $product->image property point to just the name of the file. Then in your view apply the file name to the /uploads/products/ directory on the web server.
Doing this will allow you to apply the /uploads/products/ local path and have a better time finding the file you want to delete. I'm assuming the uploads directory is in your Laravel public directory so you'd want to do something like this:
// $product->image must point to the filename only: 1593902362bluesocksupd.jpg
// The file_exists should evaluate to true and unlink() will work.
$image_path = public_path('uploads/products/' . $product->image);
if(file_exists($image_path)){
unlink($image_path);
}
In your Blade template view you'd need to show the product image using something like this:
<img src="{{ url('/uploads/products/' . $product->image) }}" />
Storing a complete URL in your database doesn't scale well if you wanted to develop another website or reuse this code on another project. This way you can let Laravel manage where the URL or local file system is.
You could use PHP's unlink() method.
But if you want to do it the Laravel way, use the Storage::delete method instead :
use Illuminate\Support\Facades\Storage;
public function destroy($id)
{
$product = Product::findOrFail($id);
$image_path = public_path('uploads/products/' . $product->image);
if(file_exists($image_path)){
Storage::delete($image_path);
}
$product->delete();
}

update profile in laravel API for mobile apps

I want to build an api for mobile apps. for now, i want to create an edit profile api. but i dont know how to store an image, if user wants to upload their avatar.
Here is my code:
public function profileedit($id, Request $request){
$users = user::find($id);
$users->name = $request->firstName;
$users->thumbnail = $request->avatar;
$users->save();
$data[] = [
'id'=>$users->uid,
'name'=>$users->name,
'avatar'=>$users->thumbnail,
'status'=>200,
];
return response()->json($data);
}
how to put the $request->avatar into my project storage, and show it in url form (my project is already uploaded on the server)
The easiest way to store files in Laravel is this.
use Illuminate\Support\Facades\Storage;
public function profileedit($id, Request $request){
//validator place
$users = user::find($id);
$users->name = $request->firstName;
$users->thumbnail = $request->avatar->store('avatars','public');
$users->save();
$data[] = [
'id'=>$users->uid,
'name'=>$users->name,
'avatar'=>Storage::url($users->thumbnail),
'status'=>200,
];
return response()->json($data);
}
but as you probably know, you should run php artisan storage:link command to generate storage shortcut in public directory.
for security reason you can use validator to let only image file store. in this example I limited file to all image types with maximum 4MB size
$request->validate([
'avatar' => 'required|image|max:4096',
]);
for more information these are document links.
File Storage
Validation

How to check data selected using LOG:INFO Laravel

How I can check the selected elements that I pass from front end using Log::info? I tried using this but I dont know how to check the result, or maybe the code is wrong?
public function filterQuery(Request $request){
$name= $request->name;
$age= $request->age;
Log::info('Showing user profile for user: '.$name);
$query = user::query();
if(!empty($request->name)){
$query->where('name',$name);
}

Laravel 5.6 - Cannot change the uploaded file name in $request, temporary name is inserted in the database

I created a form with file and uploads the file and stores the data in the database very well. The problem is, I need to store the modified file name in the database but the Laravel stores the temporary name in the database. This is the code
public function store(Request $request)
{
$image = $request->file('file');
$imageName = time().rand(1,100).$image->getClientOriginalName();
$image->move(public_path('uploads'),$imageName);
$request['file'] = $imageName;
//$request->file = $imageName;
$im = new Image($request->all());
$this->user->images()->save($im);
}
I tried to modify the file manually but it didn't work. This the dd of $request
But still the temporary file name is inserted in to database.
This is the table and file column must have the name of the file
As you see the file name I provided is not in the file column, the temporary is in there
Reason why its happen:
As you have printed $request array on screen, the uploaded file name has changed as per your desired name,
but problem arises when you use $request->all() method, see below the all() method in Illuminate/Http/Concerns/InteractsWithInput.php
public function all($keys = null)
{
$input = array_replace_recursive($this->input(), $this->allFiles());
if (! $keys) {
return $input;
}
$results = [];
foreach (is_array($keys) ? $keys : func_get_args() as $key) {
Arr::set($results, $key, Arr::get($input, $key));
}
return $results;
}
The above method replaces the normal input keys with file input keys if both have same name, means if you have $request['image'] and $request->file('image') then after calling $request->all() your $request['image'] is bound to replaced by $request->file('image').
So what to do if you don't want to replace it automatically like here you want to get newly uploaded file name in $request['file'] instead of tmp\php23sf.tmp,
Solution:
one workaround is to use different name in file input and db field name, lets take your example:
You have database table field file for storing uploaded filename so use name userfile or any other name in file input as <input type="file" name="userfile">
Then after it in your controller use same code as you have used with different name:
see below:
public function store(Request $request)
{
$image = $request->file('userfile');
$imageName = time().rand(1,100).$image->getClientOriginalName();
$image->move(public_path('uploads'),$imageName);
$request['file'] = $imageName;
$im = new Image($request->all());
$this->user->images()->save($im);
}
It will work definitely, correct me if i am wrong or ask me anything if you want further info, thanks.
You have to change name from:
<input name="file" type="file"/>
to:
<input name="upload_file" type="file"/>
as #Haritsinh Gohil described
As you have printed $request array on screen, the uploaded file name
has changed as per your desired name,
but problem arises when you use $request->all() method, see below the
all() method in Illuminate/Http/Concerns/InteractsWithInput.php
However, you can keep the input with the name file and make
$image = $request->file('file');
$imageName = time().rand(1,100).$image->getClientOriginalName();
$image->move(public_path('uploads'),$imageName);
$data = $request->all();
$data['file'] = $imageName;
$im = new Image($data);
$this->user->images()->save($im)
After looking at the output you have provided, I think here is your mistake.
$imageName = time().rand(1,100).$image->getClientOriginalName();
You have to add Original Extension instead of Original Name like this,
$imageName = time().rand(1,100).$image->getClientOriginalExtension();
I hope you understand.

Laravel 5 : How to get path name from URL?

In laravel , I come across a situation where I need to get the path name from url.
e.g.
www.example.com/timeslot
In above example I want to fetch "timeslot" in my controller
public function login()
{
$url = URL::current();
echo "timeslot"; //I want to print only "timeslot" here.
}
Hello to retrieve a uri segment in laravel use it
$segment = Request::segment(1);
inside the blade view like this
{!! Request::segment(1) !!}
this will return the first segment of your project uri
www.example.com/timeslot
timeslot
simply use
$request->path();
The path method returns the request's path information. So, if the incoming request is targeted at www.example.com/timeslot, the path method will return timeslot.
See: https://laravel.com/docs/5.4/requests
This should give you the path
public function login(){
$url =\Request::path();
echo $url;
}
You need to request the path, like so.
public function test(Request $request) {
$url = $request->path();
return view('home')->with('url', $url);
}
and in your view
{{ $url }}

Resources