Duplicating data in Controller Laravel - php

I am trying to duplicate data with a click of a button, in better terms, trying to reorder a previous order. This is my code
$order = Order::find($id);
$order_details = OrderDetail::where('order_id', $id)->get();
$reorder = $order->replicate();
$reorder_details = $order_details->replicate();
$reorder->save();
$reorder_details->save();
The $order data replicates fine, however the $order_details data doesnt, as I get this error Method Illuminate\Database\Eloquent\Collection::replicate does not exist.
Is there a way to duplicate without using replicate()?

It's because $order = Order::find($id); returns the first instance (a model) and $order_details = OrderDetail::where('order_id', $id)->get(); returns a collection. Just have to change it to $order_details = OrderDetail::where('order_id', $id)->first(); and it will work fine.
To handle multiple order details:
$order_details = OrderDetail::where('order_id', $id)->get()->each(function($item) use($reorder){
$newItem = $item->replicate();
$newItem->order_id = $reorder->id; //If needed, be sure to pass $order if you do
$newItem->save();
});

You can use the __clone() method which you can implement inside the order class,
Then you can use it like this
$order = Order::find($id);
$newOrder = clone $order;
$newOrder->save();

Related

Laravel "Skip" WhereIn when request not Filled or null?

I have controller with request like below
$product = $request->product; //array
$product_category = $request->product;
if($request->filled('product')){
$product = product()::whereIn('product',$product)
->where('product_category',$product_category)
->get();
}else {
$product = product()::where('product_category',$product_category)
->get();
}
how do i skip or make the eloquent still worked if $product request was not filled or null?
Currently i used the if for that query is remove where on product, but that will make me create alot of eloquent with more request
But I think this is not the best or right think to do, what is my better option for doing that where without writing a lot of if-elseing?
Use when function provided by laravel:
Product::when($request->product, function($query, $product) {
$query->whereIn($product);
})->where("product_category", $product_category)->get();

I have a problem with foreach understanding laravel 5.6

I have a persistent problem with all my project and I need help understanding how to make it work.
In my view =
URL = mysite.com/product/40 so here the product ID is 40
On the view I am doing a foreach loop to show all merchants that have this product. we have many merchants having many products so it is a many to many relationship.
Now on my controller
$product = Product::find($id); // to find the product
$users = $product->users; // here the user is the merchant that have the product
$store = Store::where('user_id', $user->id)->value('social');
Here i get the error :
Trying to get property of non-object
So I do want to access the store of each of the merchants in the controller how do I do this ? Because now $user is a collection.
Please first verify if the store is giving object or not by using var_dump. After that you can have a look into https://laravel.com/docs/5.6/queries for more details.
1) Firstly you can use Injection to avoid this line: $product = Product::find($id);
public function your_controller_methon(Product $product) {}
Laravel will automatically do the trick for you and $product will already contain Product object.
2) If you have relationship, you should do something similar to this:
$product->stores - to retrieve all stores which contains particular product in product_id column. And you could do: $product->stores()->pluck('social'); to retrieve list of socials from all merchants which have particular product.
About relationships you could read here: https://laravel.com/docs/5.7/eloquent-relationships
You can refactor your code to use the whereIn() query builder method since you have many users to a product. You will have something like:
$product = Product::find($id); // to find the product
$users = $product->users->pluck('id');
$stores = Store::whereIn('user_id', $users->all())->value('social');
This mean your $stores variable will contain those stores owned by the users.
PS: Be sure to check if $users is not empty or null so you don't encounter unexpected errors
According to you code, Here $user is a single value, not a collection.
Change:
$store = Store::where('user_id', $user->id)->value('social');
To
$store = Store::where('user_id', $user);
It will works.
To make the $user as a collection, execute such query so that it will return array such as:
$product = Product::find($id);
$user = Product::where('user', $product->user)->get();
This will return the collection of users of this product.
Then execute foreach loop:
foreach($user as $rowdata){
$store = Store::where('user_id', $rowdata->id)->get();
}
You should try this:
$product = Product::find($id);
$user = Product::where('user', $product->user)->get();
foreach($user as $rowdata){
$store = Store::where('user_id', $rowdata->id)->get();
}

How to get last inserted id through save() method in laravel

I know to get the last id I can use insertGetId() but I want to know how can I get the last inserted id through save() method.
order = new Store_order;
$order->invoice_id = $signed['invoice_id'];
$invoice = $order->save()['so_id'];
I used this but it returns null value
After $order->save(), $order->so_id should be the last id inserted. Your code should be as below.
$order = new Store_order;
$order->invoice_id = $signed['invoice_id'];
$order->save();
$invoice = $order->so_id;
You can get it by like below :
$order = new Store_order;
$order->invoice_id = $signed['invoice_id'];
$invoice = $order->save();
echo $invoice->so_id;
in this case you no need to store in one variable and then access it, You can get the inserted records by calling the model object itself :
$order = new Store_order;
$order->invoice_id = $signed['invoice_id'];
$order->save();
// echo $order; => will return entire stored last record.
echo $order->so_id;
Make sure so_id is autoincrement.
Try this once it worked for me where $mode->save(); was only returning true.
$mylastid = DB::getPdo()->lastInsertId();
In case of you did overwride the name of primary key in the model as in next case:
protected $primaryKey = 'your_table_id_name';
use:
$id = $your_variable_save->your_table_id_name
if not:
$id = $your_variable_save->id
You can get the last inserted id by the following codes.
Using Laravel Eloquent
$order = new Store_order();
$order->invoice_id = $signed['invoice_id'];
$order->save();
$lastInsertedId = $order->so_id; //now getting Last inserted id
echo $lastInsertedId;
Provided that $order->so_id means last inserted id of the given object where so_id is the primary key of the table.
$ObjTable->nane = $name;
$ObjTable->save();
echo $ObjTable->id;
this will be display last inserted id.

Laravel 5.2 Eloquent foreach loop

I'm in a controller for Laravel 5.2 and am trying to iterate through an eloquent collection of invoice_items, which would translate to something like order items. So, the invoice would act as the order, have it's ordered items (invoice_item), and the invoice_items would list all of the products ordered (product).
Here's what I have:
$id = $value; //from param
$invoice = Invoice::where('id', $id)->get();
$invoice_items = Invoice_item::all()->where('invoice_id', $invoice[0]->id);
$contact = Contact::where('id', $invoice[0]->contact_id)->get();
foreach($invoice_items as $item) {
$products = Product::all()->where('id', $item->product_id);
}
I'm attempting to pull all of the products from that specific invoice (via invoice items), which in this specific case should be two, different products.
What's happening, is when I iterate through using that loop, it's adding the same product twice, whereas it should be adding each product once. Is my logic just wrong here? Or do I need to look at my relationships again or something?
Change your queries to:
$invoice = Invoice::where('id', $id)->get();
$invoice_items = Invoice_item::where('invoice_id', $invoice[0]->id)->get();
$contact = Contact::where('id', $invoice[0]->contact_id)->get();
foreach($invoice_items as $item) {
$products = Product::where('id', $item->product_id)->get();
}
An easier way may be to add a items relation to the InvoiceItems model. E.g.:
public function items()
{
$this->hasOne('Items');
}
Then you can get all the Items from Invoice_item using:
return $invoice_items->items;
You can also try:
$invoice = Invoice::where('id', $id)->get();
$invoice_items = Invoice_item::where('invoice_id', $invoice[0]->id)->get()->lists('product_id');
$contact = Contact::where('id', $invoice[0]->contact_id)->get();
$products = Product::whereIn('id', $invoice_items)->get();
Hopefully, $products will then contain a collection of products for that invoice. No need for a foreach loop.

How can I get recent entris to first as deault in cakephp

i'm very new on cakephp.I have 35 tables in my data base and want to edit default index.ctp views to get recent entry first and also in other search results I want to put recent entries first. So, I'm try to edit find() function using 'beforeFind()' callback. I wrote following function and put it to 'AppController', but it didn't work. Is there any error in this code or I put it on wrong place.Does anyone help me to find mistake ? Thanks
function beforeFind($queryData) {
if (!isset($queryData['order'])) {
$queryData['order'] = array();
}
$queryData['order'][$model->alias.'.id'=> 'DESC'];
return $queryData;
}
Use cakephp model attribute
The default ordering of data for any find operation. Possible values include:
$order = "field"
$order = "Model.field";
$order = "Model.field asc";
$order = "Model.field ASC";
$order = "Model.field DESC";
$order = array("Model.field" => "asc", "Model.field2" => "DESC");
refer cakephp documentation
So in AppModel just define the following
public $order = "id desc";

Categories