This question have been asked many times in SO, but still I cannot figure it out why is this not working for me.
I am working on E-Commerce Laravel Project.
The issue is that, when the admin uploads the image file of the product, get the error of:
Can't write image data to path
(http://example.com/ankur/images/uploads/products/img-newprod-540-350-350.jpg)
Here's the controller snippet of storing the image and related entries:
public function storeGeneral(Request $request)
{
$this->validate($request, [
'code' => 'required|alpha_dash|unique:products',
'name' => 'required',
'description' => 'string',
'details' => 'string',
'price' => 'required|regex:/^\d*(\.\d{2})?$/',
'tax_amount' => 'required|regex:/^\d*(\.\d{2})?$/',
'net_price' => 'required|regex:/^\d*(\.\d{2})?$/',
'weight' => 'required|integer',
'image_file' => 'image|mimes:jpeg,jpg,JPG'
]);
if ($request->ajax() ) {
if ($request->file('image_file' ) ) {
$request['img_code'] = 'img-' . $request->get('code' );
$product = Product::create($request->all() );
$product->categories()->attach($request->input('category_id') );
Session::put('product_last_inserted_id', $product->id);
$mgCode = DB::table('products')->latest()->limit(1)->pluck('img_code');
$imageType = [
'product' => [
'height' => 350,
'width' => 350
],
'carousel' => [
'height' => 163,
'width' => 163
],
'cart' => [
'height' => 64,
'width' => 64
]
];
foreach($imageType as $key => $value)
{
$fileName = Safeurl::make($mgCode );
$image = Image::make($request->file('image_file' ) );
//$path = public_path( 'images/uploads/products/' );
$path = url('/images/uploads/products/');
if ($key == 'product') {
$image->resize($value['width'], $value['height'] );
$image->save($path.'/'.$fileName."-". $value['width'] ."-".$value['height'] .".jpg", 100 );
} else if ($key == 'carousel' ) {
$image->resize($value['width'], $value['height'] );
$image->save($path.'/'.$fileName."-". $value['width'] ."-".$value['height'] .".jpg", 100 );
} else if ($key == 'cart' ) {
$image->resize($value['width'], $value['height'] );
$image->save($path.'/'.$fileName."-". $value['width'] ."-".$value['height'] .".jpg", 100 );
}
}
} else {
$product = Product::create($request->all() );
Session::put('product_last_inserted_id', $product->id);
}
return response(['status' => 'success', 'msg' => 'The product has been added successfully.']);
}
return response(['status' => 'failed', 'msg' => 'The product could not be added successfully.']);
}
The folder permission that I have is 0777 for the images directory and it's sub directories.
But still I get the above mentioned error exception.
EDIT 1:
This is the folder structure in my hosting account file manager which is inside the public_html directory:
Can anybody help me out with this.
Thanks in advance.
I have somehow figured it out.
Instead of using url() or base_path(), I used public_path().
Code that I used:
$path = public_path('../../public_html/ankur/images/uploads/products');
Worked like a charm.
You are trying to save image using url. Instead of url try following
$path = base_path().'/images/uploads/products';
You can not save the image using http path. You have to use base_path() or manual type full server directory path /home/webtuningtechnology/public_html/images/ like this
Related
Please am trying to upload 3 different images using the code below. How do I get each of the methods that generates the unique image names to run only when their respective request fields have data or is not empty. thus the form submit should not try generating any image name for afile field when that particular file field is empty.
My update controller function
public function update(Request $request, Product $product)
{
$image = $request->file('primary_image');
$name_gen = md5(rand(1000, 10000)).'.'.$image->getClientOriginalExtension();
Image::make($image)->resize(523,605)->save('upload/products/'.$name_gen);
$save_url = 'upload/products/'.$name_gen;
$image_1 = $request->file('image_1');
$name_gen = md5(rand(1000, 10000)).'.'.$image_1->getClientOriginalExtension();
Image::make($image_1)->resize(523,605)->save('upload/products/'.$name_gen);
$save_url_1 = 'upload/products/'.$name_gen;
$image_2 = $request->file('image_2');
$name_gen = md5(rand(1000, 10000)).'.'.$image_2->getClientOriginalExtension();
Image::make($image_2)->resize(523,605)->save('upload/products/'.$name_gen);
$save_url_2 = 'upload/products/'.$name_gen;
Product::insert([
'name' => $request->name,
'category' => $request->category,
'price' => $request->price,
'description' => $request->description,
'status' => $request -> status,
'estimated_delivery_time' => $request->estimated_delivery_time,
'available_quantity' => $request->available_quantity,
'colors' => $request->colors,
'supplier_name' => $request->supplier_name,
'supplier_phone' => $request->supplier_phone,
'video_description' => $request->video_description,
'primary_image' => $save_url,
'image_1' => $save_url_1,
'image_2' => $save_url_2,
]);
$notification = array(
'message' => 'Product updated successfully',
'alert-type' => 'success'
);
return redirect()->back()->with($notification);
}
Thanks so much for taking time to review my code
Since you are doing the same name generation process all through, you can use an array and do a foreach loop with an if condition like this:
$my_array = [$request->file('primary_image'), $request->file('image_1'), $request->file('image_2')];
foreach($my_array as $item) {
if($item) {
$image = $item;
$name_gen = md5(rand(1000, 10000)).'.'.$image->getClientOriginalExtension();
Image::make($image)->resize(523,605)->save('upload/products/'.$name_gen);
$save_url = 'upload/products/'.$name_gen;
}
}
Now this will only generate names for images that are not empty.
UPDATE:
For the insert functionality, I would assume your table fields for the images can have null values, so this doesn't throw an error. Now instead of the code above, do this:
$my_array = [$request->file('primary_image'), $request->file('image_1'), $request->file('image_2')];
$insert_array = [];
foreach($my_array as $item) {
$save_url = '';
if($item) {
$image = $item;
$name_gen = md5(rand(1000, 10000)).'.'.$image->getClientOriginalExtension();
Image::make($image)->resize(523,605)->save('upload/products/'.$name_gen);
$save_url = 'upload/products/'.$name_gen;
}
array_push($insert_array, $save_url);
}
Now for your insert query, do this:
Product::insert([
'name' => $request->name,
'category' => $request->category,
'price' => $request->price,
'description' => $request->description,
'status' => $request -> status,
'estimated_delivery_time' => $request->estimated_delivery_time,
'available_quantity' => $request->available_quantity,
'colors' => $request->colors,
'supplier_name' => $request->supplier_name,
'supplier_phone' => $request->supplier_phone,
'video_description' => $request->video_description,
'primary_image' => $insert_array[0],
'image_1' => $insert_array[1],
'image_2' => $insert_array[2],
]);
This would work.
I have a problem uploading a file can you help me? when I upload a smaller file it runs smoothly but when I upload a larger file it's problematic, does anyone know the solution? this is the controller part:
$title = $this->request->getPost('title');
$kategori = $this->request->getPost('kategori');
$seo = str_replace(" ", "-", strtolower($kategori));
$deskripsi = $this->request->getPost('deskripsi');
$data=array();
$file = $this->request->getFile('imagefile');
$data=array();
if ($file->getSize() > 0){
$image=$file->getRandomName();
$file->move('./uploads/peta/',$image);
$data = array(
'title' => $title,
'kategori' => $kategori,
'seo' => $seo,
'deskripsi' => $deskripsi,
'file' => $image
);
}else{
$data = array(
'title' => $title,
'kategori' => $kategori,
'seo' => $seo,
'deskripsi' => $deskripsi
);
}
Use $files->hasFile('') to check whether file exist. And then check other file properties as mentioned below.
$files = $this->request->getFiles();
if ($files->hasFile('imagefile'))
{
$file = $files->getFile('imagefile');
// Generate a new secure name
$name = $file->getRandomName();
// Move the file to it's new home
$file->move('/path/to/dir', $name);
echo $file->getSize(); // 1.23
echo $file->getExtension(); // jpg
echo $file->getType(); // image/jpg
}
You need to check if the file is set before trying to call file methods. It seems that the file isn't being sent over your request. As you said, it works with smaller files so please check the php.ini file to see your max_upload_size settings and post_max_size settings. Change the maximum upload file size
Otherwise, to ensure your code won't fail on posts, you can do this:
if (!empty($file) && $file->getSize() > 0){
$image=$file->getRandomName();
$file->move('./uploads/peta/',$image);
$data = array(
'title' => $title,
'kategori' => $kategori,
'seo' => $seo,
'deskripsi' => $deskripsi,
'file' => $image
);
}else{
$data = array(
'title' => $title,
'kategori' => $kategori,
'seo' => $seo,
'deskripsi' => $deskripsi
);
}
This will check if there is a file before trying to use it.
I'm building an Restful API using Laravel 5 and MongoDB.
I'm saving avatar image for users.
It's working fine but I'm trying to create a Folder for every User. For example: "app/players/images/USERID"
I've tried to do something like this in different ways but I always get Driver [] is not supported.
\Storage::disk('players'.$user->id)->put($image_name, \File::get($image));
UploadImage:
public function uploadImage(Request $request)
{
$token = $request->header('Authorization');
$jwtAuth = new \JwtAuth();
$user = $jwtAuth->checkToken($token, true);
$image = $request->file('file0');
$validate = \Validator::make($request->all(), [
'file0' => 'required|image|mimes:jpg,jpeg,png'
]);
if ( !$image || $validate->fails() )
{
$data = array(
'code' => 400,
'status' => 'error',
'message' => 'Image uploading error-'
);
}
else
{
$image_name = time().$image->getClientOriginalName();
\Storage::disk('players')->put($image_name, \File::get($image));
$user_update = User::where('_id', $user->id)->update(['imagen' => $image_name]);
$data = array(
'code' => 200,
'status' => 'success',
'user' => $user->id,
'imagen' => $image_name
);
}
return response()->json($data, $data['code']);
}
filesystems.php:
'players' => [
'driver' => 'local',
'root' => storage_path('app/players/images/'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
I expect the user avatar image saves on User ID folder.
The disk call, tells Laravel which filesystem to use, let's assume you have an user with Id one, with your code it will access the filesystem playeers1.
What usually is done is to put these files in folder structures for the different users, so instead you could do. This will put your image file, in the folder 1.
\Storage::disk('players')->put($user->id . '/' . $image_name, \File::get($image));
I had a similar problem, check if the lines can change what you want to achieve.
\Storage::disk('players')->put("{$user->id}/{$image_name}", \File::get($image));
I relied on the laravel guide: File Storage - File Uploads
I hope it helps you. A cordial greeting.
I am trying to upload multiple images using guzzlehttp client. I have a form in which other type of data('id', 'date','name' e.t.c..) and images are there.
I want to save other data along with image upload through an Api Request.
I am able to save other data, but i am getting problem in uploading images.
In the API i am accessing my image file by
$request->file('images')
but it is showing empty.
My code for calling the API
$images = $request->file('images');
foreach ($images as $image)
{
$body[] = [
'Content-type' => 'multipart/form-data',
'name' => $image->getClientOriginalName(),
'contents' => fopen($image->getRealPath(), 'r')
];
}
$data = $request->all();
$client = new Client();
$response = $client->request('POST', $url, [
'multipart' => $body,
'json' => $data
]);
I'm handling the Api for uploading image below
if ($request->hasFile('images'))
{
$images = $request->file('images');
foreach ($images as $image)
{
$imageRules = [
'file' => 'mimes:png,jpeg,jpg,JPG|max:1024'
];
$imageMessages = [
'file.mimes' => 'One of the images/video is not valid. (only .png, .jpeg, .jpg, .mp4, .x-flv, .x-mpegURL, .MP2T, .3gpp, .quicktime, .x-msvideo, .x-ms-wmv are accepted)',
'file.max' => 'Image size cannot br more than 1 MB'
];
$imageValidator = Validator::make(['file' => $image], $imageRules, $imageMessages);
if ($imageValidator->fails())
{
return response()->json(['success' => false, 'error' => $imageValidator->messages()->first(), 'dashRedirectUrl' => $redirectRoute]);
}
}
$directPath = '/ticket/' . $ticket->id . '/mapping/' . $mappingId . '/images/';
foreach ($images as $image)
{
$option = ['isWatermark' => false];
$imageName = $this->uploadImageToServer($image, $directPath, $option);
$imgInsertData = [
'url' => $imageName,
'title' => $this->getImageTitle($image),
'ticket_mapping_id' => $mappingId,
'type_id' => 1,
];
TicketMappingGallery::create($imgInsertData);
}
}
Note :: My funciton uploadImageToServer() is custom function for uploading the images..
Any help would be appreciated. Drop comment if anything is not clear.
Try this one,
foreach ($image as $img) {
$body[] = [
'name' => 'image[]',
'image_path' => $img->getPathname(),
'image_mime' => $img->getmimeType(),
'image_org' => $img->getClientOriginalName(),
'contents' => fopen($img->getRealPath(), 'r')
];
}
$requestOptions = ['query' => $data, 'multipart' => $body
];
I refer to http://samsonasik.wordpress.com/2012/08/31/zend-framework-2-creating-upload-form-file-validation/ and follow this, I can upload 1 file successfully by using rename filter in ZF2.
However when I use this way to upload 2 files, it goes wrong. I paste my code as following:
$this->add(array(
'name' => 'bigpicture',
'attributes' => array(
'type' => 'file'
),
'options' => array(
'label' => 'Big Pic'
)
));
$this->add(array(
'name' => 'smallpicture',
'attributes' => array(
'type' => 'file'
),
'options' => array(
'label' => 'Small Pic'
)
));
<div class="row"><?php echo $this->formRow($form->get('smallpicture')) ?></div>
<div class="row"><?php echo $this->formRow($form->get('bigpicture')) ?></div>
$data = array_merge(
$request->getPost()->toArray(),
$request->getFiles()->toArray()
);
$form->setData($data);
if ($form->isValid()) {
$product->exchangeArray($form->getData());
$picid = $this->getProductTable()->saveProduct($product);
$pathstr = $this->md5path($picid);
$this->folder('public/images/product/'.$pathstr);
//move_uploaded_file($data['smallpicture']['tmp_name'], 'public/images/product/'.$pathstr.'/'.$picid.'_small.jpg');
//move_uploaded_file($data['bigpicture']['tmp_name'], 'public/images/product/'.$pathstr.'/'.$picid.'_big.jpg');
$fileadaptersmall = new \Zend\File\Transfer\Adapter\Http();
$fileadaptersmall->addFilter('File\Rename',array(
'source' => $data['smallpicture']['tmp_name'],
'target' => 'public/images/product/'.$pathstr.'/'.$picid.'_small.jpg',
'overwrite' => true
));
$fileadaptersmall->receive();
$fileadapterbig = new \Zend\File\Transfer\Adapter\Http();
$fileadapterbig->addFilter('File\Rename',array(
'source' => $data['bigpicture']['tmp_name'],
'target' => 'public/images/product/'.$pathstr.'/'.$picid.'_big.jpg',
'overwrite' => true
));
$fileadapterbig->receive();
}
the above are form,view,action.
using this way, only the small picture uploaed successfully. the big picture goes wrong.
a warning flashed like the following:
Warning:move_uploaded_file(C:\WINDOWS\TMP\small.jpg):failed to open stream:Invalid argument in
E:\myproject\vendor\zendframework\zendframework\library\zend\file\transfer\adapter\http.php
on line 173
Warning:move_uploaded_file():Unable to move 'C:\WINDOWS\TMP\php76.tmp'
to 'C:\WINDOWS\TEMP\big.jpg' in
E:\myproject\vendor\zendframework\zendframework\library\zend\file\transfer\adapter\http.php
on line 173
Who can tell me how to upload more than 1 file in this way. you know, the rename filter way similar to above. thanks.
I ran into the same problem with a site i did. The solution was to do the renaming in the controller itself by getting all the images and then stepping through them.
if ($file->isUploaded()) {
$pInfo = pathinfo($file->getFileName());
$time = uniqid();
$newName = $pName . '-' . $type . '-' . $time . '.' . $pInfo['extension'];
$file->addFilter('Rename', array('target' => $newName));
$file->receive();
}
Hope this helps point you in the right direction.
I encountered the same problem and i managed to make it work using the below code;
$folder = 'YOUR DIR';
$adapter = new \Zend\File\Transfer\Adapter\Http();
$adapter->setDestination($folder);
foreach ($adapter->getFileInfo() as $info) {
$originalFileName = $info['name'];
if ($adapter->receive($originalFileName)) {
$newFilePath = $folder . '/' . $newFileName;
$adapter->addFilter('Rename', array('target' => $newFilePath,
'overwrite' => true));
}
}