Retrieving data from database using multiple ids - Laravel - php

I have list of clients in my database with with unique ids. I am trying to retrieve these customers using these unique ids like this .
I want to get each clients name and phone and so i can process a message to them respectively. But with my query, i am only getting only one client and not all of my clients.
PS: when i return $explode, i am able to get all the ids i have selected.
public function getCustomers(Request $request)
{
$ids = $request->ids;
$explode = explode(",",$ids);
if(request()->ajax())
{
$clients = Client::whereHas('product', function($find_clients)use($explode)
{
$find_clients->where('id',$explode);
})->get();
$get_customer_name = [];
$get_customer_phone = [];
foreach($clients as $key => $client)
{
$get_customer_name[] = $client->name;
$get_customer_phone [] = $client->phone;
return ['success' => $explode];
}
}
}
SMS query
$query = "?key=$api_keyto=$implode(',',$$get_customer_phone)&msg=Dear ".$implode(',',$$get_customer_name)."Thank you";

To find clients with an array of ids, try using whereIn instead of where.
Like so:
$find_clients->whereIn('id',$explode);

Try using whereIn instead of where
$find_clients->whereIn('id', $explode);

Related

Why the name of trucks are same in 2nd and 3rd record of company data retrieval?

My data in database:
My objective is to retrieve all data of company collection (MongoDB) data from the database. The company collection holds one or many trucks. I have implemented one-to-many reference between company and trucks collection. That is working fine.
I am using query builder to get all the data. But, my code is not giving me all the Trucks of the specific company. It is retrieving only one truck name for specific documents.
My API code is checking the length of the truck's array and storing the name for the truck on ta[] array. Code is not written nicely as I have tried so many methods and I am frustrated now.
How can I retrieve my data?
My API:
/**
* #Route("/koco/get/company/query", name="queryToGetCompany")
* #Template()
*/
public function queryForCompanyAction()
{
$checkarray = array();
$dm = $this->get('doctrine_mongodb')->getManager();
$qb = $dm->createQueryBuilder(Company::class);
$qb->find(Company::class);
$query = $qb->getQuery();
$comapnies = $query->execute();
foreach ($comapnies as $company)
{
$objectId = $company->getId();
$objectName = $company->getName();
$objectAddress = $company->getAddress();
// for length
$len = count($company->getTrucks());
echo $len;
// For trucks
$Trucks = $company->getTrucks();
foreach ($Trucks as $truckname)
{
$ta = array();
for($i=0;$i< $len;$i++){
$object = new Truck();
$object = $truckname->getName();
$ta[] = $object;
}
}
$checkarray[] = array(
'Id' => $objectId,
'Name' =>$objectName,
'Address' =>$objectAddress,
'Trucks' => $ta,
);
}
$data = [
'Comapnies' => $checkarray,
];
return new JsonResponse($data);
}
My results from the API:
The 2nd and third companies are giving me the same records for the name of trucks, but in my database the truck names are different.
Your foreach and your for loop are colliding, in conjunction with your array being emptied inside the foreach loop. If you reset your array before the foreach loop, not inside, and also just use a foreach without the for, I think this is what you want.
What is happening in your code as presented in the question is that the array is wiped out between trucks, so you only get the last truck. Additionally, because of the manually counted for loop, the number of copies of the last truck is equal to the total number of trucks associated with each company.
This is my suggestion based on what you have shown, replacing the entire foreach loop with this code.
$ta = array();
foreach ($Trucks as $truckname)
{
$object = new Truck();
$object = $truckname->getName();
$ta[] = $object;
}

Improve performance of multiple row insertions in Laravel

I have a controller API method where I insert many rows (around 4000 - 8000), before inserting a new row I also check if a venue with the same ame was added already in the zone sothat's another Elouent call, my issue is I usually get timeout errors becuase the row inserting takes too much, I use set_time_limit(0) but this seems too hacky.
I think the key is the validation check I do before inserting a new row.
//Check if there is a venue with same name and in the same zone already added
$alreadyAdded = Venue::where('name', $venue['name'])->whereHas('address', function ($query) use ($address){
$query->where('provinceOrState' , $address['provinceOrState']);
})->orWhere('venueId',$venue['venueId'])->first();
Is there a way I can improve the performance of this method ? This is my complete method call:
public function uploadIntoDatabase(Request $request)
{
set_time_limit(0);
$count = 0;
foreach($request->input('venuesToUpload') as $index => $venue)
{
//Check if there is a venue with same name and in the same zone already added
$alreadyAdded = Venue::where('name', $venue['name'])->whereHas('address', function ($query) use ($address){
$query->where('provinceOrState' , $address['provinceOrState']);
})->orWhere('venueId',$venue['venueId'])->first();
if(!$alreadyAdded)
{
$newVenue = new Venue();
$newVenue->name = $venue['name'];
$newVenue->save();
$count++;
}
}
return response()->json([
'message' => $count.' new venues uploaded to database',
]);
}
use only one request to add the venues
$newVenues = [];
$count = 0;
foreach($request->input('venuesToUpload') as $index => $venue) {
//Check if there is a venue with same name and in the same zone already added
$alreadyAdded = Venue::where('name', $venue['name'])->whereHas('address', function ($query) use ($address){
$query->where('provinceOrState' , $address['provinceOrState']);
})->orWhere('venueId',$venue['venueId'])->count();
if(!$alreadyAdded) {
$newVenues [] = ['name' => $venur['name'];
}
}
if ($newVenues) {
$count = count($newVenues);
Venue::insert($newVenues);
}
As for the verification part, change the first to count cause you dont need to recover the data, just the information that it exists. And since you're verifying with both name and id, you can do some custom query that verifies all values in one query using a static table made from the request inputs and joining on the existing venues table where venues.id = null.

Laravel/Lumen api filter

recently I'am trying to make my api filtering work. I need to filter my products like this: http://localhost/search?feature_id=1,2,3,4,5...
Everything is fine if I'm sending only 1 id. But how to make it work in this way?
This is my controller:
public function search2(\Illuminate\Http\Request $request) {
$query = DB::table('tlt_product_features');
if ($request->has('feature_id') ) {
$query = $query->whereIn('feature_id', [$request->get('feature_id')]);
}
$products = $query->get();
return response()->json([
'products' =>$products
]);
}
Use explode() to make arrays of id.
$ids = explode(",",$request->get('feature_id'));
$query = $query->whereIn('feature_id', $ids);
To get an array out of the box on the Laravel / Lumen side, you have to send the array this way :
http://localhost/search?feature_id[]=1&feature_id[]=2&feature_id[]=3...
In a weak typed languages like PHP, the [] is actually being used as an internal work around in order to be able to get multi valued parameters. You could also specify an index :
http://localhost/search?feature_id[0]=1&feature_id[1]=2&feature_id[2]=3...
You could then use in you controller :
if ($request->filled('feature_id')) {
// You could also check that you have a php array : && is_array($request->input('feature_id'))
// And that it's not an empty array : && count($request->input('feature_id'))
$query = $query->whereIn('feature_id', $request->input('feature_id'));
}

Laravel, copy row to another table with eloquent relationship

I want to get the data form database table and create a new row in another table.
Which 1 PO have many PoProducts.
$_getPO = Order::find($id);
$_getPOProducts= OrderProducts::where('order_id', $id)->get();
$order_no = $_getPO->order_no;
$eta = $_getPO->eta;
$_Order = new DeliveryOrders();
$_Order->order_no = $order_no;
$_Order->eta = $eta;
$_Order->save();
$POProduct = array();
foreach($_getPOProducts as $i => $_getPOProduct)
{
$POProduct[] = new DeliveryOrderProducts();
$POProduct[] = $_getPOProduct->order_id;
$POProduct[] = $_getPOProduct->item_id;
$POProduct[] = $_getPOProduct->qty;
$POProduct->save();
}
But, this output an error.
Call to a member function save() on array
Please help me. Thanks.
If you wish to copy records from one table to another or just duplicate a record in the same table you could simply use the repliacate() method.
$user = User::findOrFail($id);
// replicate (duplicate) the data
$staff = $user->replicate();
// make into array for mass assign.
//make sure you activate $guarded in your Staff model
$staff = $staff->toArray();
Staff::firstOrCreate($staff);
Note: in case you're only duplicating on the same table replace Staff with User on this example.
You are trying to run the save method on the array but what you want is to use it on the array index instead.
Change your foreach to this and it should work (assuming columns are the same).
foreach($_getPOProducts as $i => $_getPOProduct)
{
$POProduct[$i] = new DeliveryOrderProducts();
$POProduct[$i]->order_id = $_getPOProduct->order_id;
$POProduct[$i]->item_id = $_getPOProduct->item_id;
$POProduct[$i]->qty = $_getPOProduct->qty;
$POProduct[$i]->save();
}
You can shorten this by using forceCreate.
foreach($_getPOProducts as $i => $_getPOProduct)
{
$POProduct[$i] = (new DeliveryOrderProducts())->forceCreate($_getPOProduct->only(['order_id', 'item_id', 'qty']));
}

Laravel - $query->where all the ids in an are matched

I am working on an API endpoint that returns a list of users that have all of the given services ID's.
In my case:
Users can have many services
Tables: 'users', 'services', 'service_user'
I am passing an array via Vue JS to my end point for example:
/endpoint/32,35,38
My query is currently:
$servicesArray = explode(',', $services);
$users = User::whereHas('services', function ($query) use ($servicesArray) {
foreach ($servicesArray as $key => $value) {
$query->where('id', $value);
}
})
->get();
The issue is that it seems to return now results, even if a user does have the correct services. My relationship is fine, and if I only pass one service to the endpoint it correctly returns a user that has that service assigned. I used whereIn before, but I need to only show users that have ALL of the services specified in the endpoint array.
Any obvious reason why what I have is not working as expected?
I would try something like this:
$q = User::query();
foreach ($servicesArray as $key => $value) {
$q->whereHas('services', function ($query) use ($value) {
$query->where('id', $value);
});
}
$users = $q->get();
You can also use laravel hasmany realationship function for getting multiple records from other table.
Example:
---In your Controller use query like.
$users = User::with('services')->where('id', $value)->get();
---And in your model's class use function services like this.
function services(){
return $this->hasMany('App\Service','user_id','id');
}

Categories