Intervention \ Image \ Exception \ ImageNotWritableException using Laravel 4 - image

I am using Laravel 4. I am not sure why I am getting this error when everything seems to be correct. Also, the product is not updating to the database.
Error: Intervention \ Image \ Exception \ ImageNotWritableException
Can't write image data to path [/img/products/1396668877.jpg]
Snippet of ProductsController where product object is created:
public function postCreate() {
$validator = Validator::make(Input::all(), Product::$rules);
if ($validator->passes()) {
$product = new Product;
$product->category_id = Input::get('category_id');
$product->title = Input::get('title');
$product->description = Input::get('description');
$product->price = Input::get('price');
$image = Input::file('image');
$filename = time() . '.' . $image->getClientOriginalExtension();
Image::make($image->getRealPath())->resize(468, 249)->save('/img/products/'.$filename);
$product->image = 'img/products/'.$filename;
$product->save();
return Redirect::to('admin/products/index')
->with('message', 'Product Created');
}
return Redirect::to('admin/products/index')
->with('message', 'Something went wrong')
->withErrors($validator)
->withInput();
}
product object passed to view
#foreach($products as $product)
<li>
{{ HTML::image($product->image, $product->title, array('width'=>'50')) }}
{{ $product->title }} -
{{ Form::open(array('url'=>'admin/products/destroy', 'class'=>'form-inline')) }}
{{ Form::hidden('id', $product->id) }}
{{ Form::submit('delete') }}
{{ Form::close() }} -
{{ Form::open(array('url'=>'admin/products/toggle-availability', 'class'=>'form-inline'))}}
{{ Form::hidden('id', $product->id) }}
{{ Form::select('availability', array('1'=>'In Stock', '0'=>'Out of Stock'), $product->availability) }}
{{ Form::submit('Update') }}
{{ Form::close() }}
</li>
#endforeach
Products Model
<?php
class Product extends Eloquent {
protected $fillable = array('category_id', 'title', 'description', 'price', 'availability', 'image');
public static $rules = array(
'category_id'=>'required|integer',
'title'=>'required|min:2',
'description'=>'required|min:20',
'price'=>'required|numeric',
'availability'=>'integer',
'image'=>'required|image|mimes:jpeg,jpg,bmp,png,gif'
);
public function category() {
return $this->belongsTo('Category');
}
}
products table in the database
public function up()
{
Schema::create('products', function($table){
$table->increments('id');
$table->integer('category_id')->unsigned();
$table->foreign('category_id')->references('id')->on('categories');
$table->string('title');
$table->text('description');
$table->decimal('price', 6, 2);
$table->boolean('availability')->default(1);
$table->string('image');
$table->timestamps();
});
}

Make sure the public/img/products folder exists and it's writable and also try to use absolute path if necessary, like this:
$filename = time() . '.' . $image->getClientOriginalExtension();
$path = public_path('img/products/' . $filename);
Image::make($image->getRealPath())->resize(468, 249)->save($path);

replace :
Image::make($image->getRealPath())->resize(468, 249)->save('/img/products/'.$filename);
with:
Image::make($image->getRealPath())->resize(468, 249)->save('public/img/products/'.$filename);
you must specify the public folder for the save method.

Related

laravel controller and view issue

I need a get field value total sum. But I can't and don't know where the problem is.
controller code:
public function index()
{
$user1 = Auth::user();
$user2 = $user1->client_id;
$withdraws = Withdraw::where('client_id', $user2)->get();
$deposits = Deposit::where('client_id', $user2)->get();
return view('home')->with(compact('deposits', 'withdraws', ));
}
view code:
#foreach($deposits as $deposit)
<td id="count-data-td">{{ $deposit->amount }}</td>
#endforeach
return view('home')->with('transfers', array('deposits'=>$deposits, 'withdraws'=>$withdraws));
and view code
#foreach($transfers['deposits']) as $deposit)
{{ $deposit->amount }}
#endforeach
but if you need the sum you can always do this:
{{ $transfers['deposits']->sum('amount') }}
in your case :
{{ $deposits->sum('amount') }}
CONTROLLER
public function index()
{
$user1 = Auth::user();
$user2 = $user1->client_id;
$withdraws = Withdraw::where('client_id',$user2)->get();
$deposits = Deposit::where('client_id', $user2)->get();
return view('home')->with(['deposits' => $deposits, 'withdraws',$withdraws]);
}
VIEW
{{ $deposits->sum('amount') }}
{{ $withdraws->sum('amount') }}
NB: You don't need to run the foreach loop to get the sum

I want to use images of products that I register in the database - Laravel

I programmed a product registration. The registration for the database is working correctly. My problem is that I can't show the images that I registered in the database. I created an imput where the name of the image is inserted. This name is saved in the database and the image is saved with the same name, however it is saval in public. The images are inside the public / storage / products folder.
Controller:
public function index()
{
$products = Product::paginate(10);
return view('products.index', [
'products' => $products,
]);
}
public function store(Request $request)
{
// Create registration
$data = $request->only('name', 'price', 'imageName');
Product::create($data);
// Image
if($request->file('imageProduct')->isValid()){
$nameFile = $request->imageName . '.' . $request->file('imageProduct')->getClientOriginalExtension();
$request->file('imageProduct')->storeAs('products', $nameFile);
return redirect()->route('ProductControllerIndex');
}
}
view:
<div>
#foreach ($products as $product)
<p>
Id: {{ $product->id }}
</p>
<p>
Nome do produto: {{ $product->name }}
</p>
<p>
Preço: {{ $product->price }}
</p>
<p>
{{ $product->imageName }}
</p>
<p>
<img src="{{ asset('storage/products/'.$product->imageName) }}" alt="">
</p>
<hr>
#endforeach
</div>
The core issue here is that your Image's extension is not being saved to the database, so $product->imageName, when used in the asset() helper, doesn't generate a complete URL for the image. You'll need to refactor your code a little to get it to save:
public function store(Request $request) {
$nameFile = $request->input('imageName', '');
if($request->file('imageProduct')->isValid()){
$nameFile .= '.' . $request->file('imageProduct')->getClientOriginalExtension();
$request->file('imageProduct')->storeAs('products', $nameFile);
}
$request->merge(['imageName' => $nameFile]);
$data = $request->only('name', 'price', 'imageName');
Product::create($data);
return redirect()->route('ProductControllerIndex');
}
In the above code, the value for $nameFile is defaulted to the value in $request->input('imageName'), or an empty string '' if nothing is supplied. Next, if a valid image is uploaded, the $nameFile variable is appended with the extension. Lastly, the $request variable is updated with the name value for imageName. The remainder of the code creates the new Product with the data supplied (using the ->only() modifier) and redirect as required.
The rest of your code should be ok, as long as the file exists in the correct directory after ->storeAs() and the fully-qualified image name is saved to the database.
Note: If for whatever reason Product::create() doesn't work with this approach, you can use the new Product() ... $product->save() approach: (there might be an issue with $request->merge() using an existing key, as I can't actually test that)
$product = new Product();
$product->name = $request->input('name');
$product->price = $request->input('price');
$product->imageName = $fileName;
$product->save();

How to update a product in Laravel 5.8

I have a product that I want to edit. Please see the following code.
public function update(ProductRequest $request, Product $product)
{
$product->user_id = auth()->user()->id;
$product->title = $request->title;
$product->body = $request->body;
$product->price = $request->price;
if ($request->has('image')) {
$image = $request->file('image');
$filename = $image->getClientOriginalName();
$image->move(public_path('images/products'), $filename);
$product->image = $request->file('image')->getClientOriginalName();
}
$product->update();
$product->categories()->sync($request->category);
return redirect()->route('products.index');
}
product.blade.php
<form class="form-horizontal" action="{{ route('products.update', $product->id) }}" method="post" enctype="multipart/form-data">
{{ csrf_field() }}
{{ method_field('PATCH') }}
.
.
.
Everything changes except the image. I tried it, but, I did not succeed. What's the solution? I want to update the image in the database.
OK, I go to database now, I changed in image to picture, then I go my project, and I tested this again.
But it did not event for me.
I changed
public function update(ProductRequest $request, Product $product)
To
public function update(Request $request, Product $product)
To update a model, you should retrieve it, set any attributes you wish to update, and then call the save method. See the updates section in the documentation.
public function update(ProductRequest $request, Product $product)
{
$product->user_id = auth()->user()->id;
$product->title = $request->title;
$product->body = $request->body;
$product->price = $request->price;
if ($request->has('image')) {
$image = $request->file('image');
$filename = $image->getClientOriginalName();
$image->move(public_path('images/products'), $filename);
$product->image = $request->file('image')->getClientOriginalName();
}
$product->save();
$product->categories()->sync($request->category);
return redirect()->route('products.index');
}
Update 1
Assuming you have debugged the above and $request->file('image')->getClientOriginalName() is returning the expected value, it's possible that you are using field whitelisting on your model and haven't added the image field to the whitelist. Make sure that image is in the $fillable array on your model.
class Product extends Model
{
protected $fillable = [
'user_id',
'title',
'body',
'price',
...
'image'
];
Update 2
If $request->file('image') is returning null then that would suggest your form is not submitting the files. Ensure your <form> element has the enctype="multipart/form-data" attribute included in the tag.
Update 3
If your already including the required enctype="multipart/form-data" tags in the <form> element then I would suggest doing the following.
Place dd($request->all()); at the top of your update(ProductRequest $request, Product $product) method. Post the form and check the output.
If the file is not included in the output, change from using ProductRequest $request to the default Request $request (Illuminate\Http\Request) and try it again. There could be something in your ProductRequest class that is causing a problem.
As a small critique, you could improve your code in the following ways.
・Use hasFile() instead of has().
・Use $product-image = $filename instead of $product->image = $request->file('image')->getClientOriginalName();.
public function update(ProductRequest $request, Product $product)
{
$product->user_id = auth()->user()->id;
$product->title = $request->title;
$product->body = $request->body;
$product->price = $request->price;
if ($request->hasFile('image')) {
$image = $request->file('image');
$filename = $image->getClientOriginalName();
$image->move(public_path('images/products'), $filename);
$product->image = $filename;
}
$product->save();
$product->categories()->sync($request->category);
return redirect()->route('products.index');
}
make sure your has
enctype="multipart/form-data"
property

How to automatic slug when i press the submit button

I want to create slug by using value of $item->name = $request->input('name'); before $item->save();
//use Illuminate\Support\Str;
private function saveItem(Request $request, $item){
$item->name = $request->input('name');
$item->slug = Str::title($item->name,"-");
$item->save();
}
When the $item->name = $request->input('name') value is Hello World,
Then after slug the output will be Hello-World
Please help.
You can generate a slug using the Str::slug() method:
private function saveItem(Request $request, $item){
$item->name = $request->input('name');
$item->slug = Str::slug($item->name);
$item->save();
}

Laravel 5.7 - Pivot table attach()

I cannot get attach() to work in my setup.
Each User can have many Orders which can have many Products.
User.php
public function orders()
{
return $this->hasMany(Order::class);
}
Order.php
public function users()
{
return $this->belongsTo(User::class);
}
public function products()
{
return $this->belongsToMany(Product::class)
->withTimestamps()
->withPivot('qty');
}
Product.php
public function orders()
{
return $this->belongsToMany(Order::class)
->withTimestamps()
->withPivot('qty');
}
I have a create.blade.php which is meant to show all available products and the quantity for each can be chosen, this is to be saved on the pivot table.
create.blade.php
{{ Form::open(array('url' => '/orders/store')) }}
#foreach ($products as $product)
<div>
<span class="mealname">{{ $product->name }}</span>
<hr>
<p>{{ $product->description }}</p>
</div>
<div class="qty">
{{ Form::text( 'qty', 0, [ 'type' => 'tel' ]) }}
</div>
#endforeach
{{ Form::select('delivery_day', ['M' => 'Monday', 'W' => 'Wednesday'],
null, ['placeholder' => 'Delivery Day'])
}}
{{ Form::submit('Place Order') }}
{{ Form::close() }}
When I submit the request only the fields to the Order table are saved,
public function store(Request $request)
{
// Validate
$request->validate([
'qty'=> 'integer',
]);
# Create New Order
$order = new Order;
$id = Auth::user()->id;
$order->user_id = $id;
// passed in parameters of form (not qty)
auth()->user()->orders()->save($order); // save order
# Pivot attach()
HERE I AM LOST
return redirect('complete')->with('success', 'Order has been created');
}
I believe it is the fact that I am trying to pass multiple products in one form, (which I believe i should be able to just pass as an arry while I use attach().
I have tried various solutions and I am still unable to ever get the pivot table to populate.
My last attempt was to pass the product_id through a hidden field and then running this.
$attach_data = [];
for ($i = 0; $i < count($product_ids); $i++);
$attach_data[$product_ids[$i]] = ['qty' => $qtys[$i]];
$order->product_ids()->attach($attach_data);
However, this did not work.
According to the docs (https://laravel.com/docs/5.7/eloquent-relationships#updating-many-to-many-relationships) this is one way to attach multiple items:
$user->roles()->attach([
1 => ['expires' => $expires],
2 => ['expires' => $expires]
]);
So you have to modify this:
# Create New Order
$order = new Order;
$id = Auth::user()->id;
$order->user_id = $id;
$order->save();
// change this for your array of ids
$products_to_sync_ids = [1,3,23];
$sync_data = [];
$qty = 1; <----- I dont know if you are inserting them with the same qty
for($i = 0; $i < count($products_to_sync_ids); $i++))
$sync_data[$products_to_sync_ids[$i]] = ['qty' => $qty];
$order->products()->sync($sync_data);
Try and check if the products are inserting correctly on the pivot table and then modify the code to insert every code with his quantity.

Resources