whereHas filter query issue on laravel - php

hello guys i want result like i have many products and in products have many supplier and one customer so when i search product description than display all product but i want output like product display but match with customer id
$pi = Product::where('customer_id',$customerId)
->whereHas('supplier', function (Builder $query) use($search) {
$query->where('sys_state', '!=', '-1')
->orWhere('name','LIKE','%' . $search . '%');
})
->where('sys_state','!=','-1')
->orWhere('prd_our_item_no', 'LIKE', '%' . $search . '%')
->orWhere('prd_supplier_item', 'LIKE', '%' . $search . '%')
->orWhere('prd_description','LIKE','%' . $search . '%')
->get();
i try this query but all the product display when i search customer id where condition not work

i try to wrap orwhere but noting can search on it
$pi = Product::where('customer_id', $customerId)
->where('sys_state', '!=', '-1')
->whereHas('supplier', function (Builder $query) use ($search) {
$query->where('sys_state', '!=', '-1')
->orWhere(function ($query) use ($search) {
$query->where('name', 'LIKE', '%' . $search . '%')
->where('sys_state','!=','-1');
});
})
->orWhere(function ($query) use ($search, $customerId) {
$query->where('prd_description', 'LIKE', '%' . $search . '%')
->where('sys_state', '!=', '-1')
->where('customer_id',$customerId);
})
->orWhere(function($query) use($search, $customerId){
$query->where('prd_supplier_item', 'LIKE', '%' . $search . '%')
->where('sys_state', '!=', '-1')
->where('customer_id',$customerId);
})
->orWhere(function($query) use($search, $customerId){
$query->where('prd_our_item_no', 'LIKE', '%' . $search . '%')
->where('sys_state', '!=', '-1')
->where('customer_id',$customerId);
})
->get();

Related

I want to filter single value or multiple value in Laravel controller

I want to filter one value or multiple values in the Laravel controller
$news_paper_machine_ads = newsPaperMachineAds::join('news_paper_district', 'news_paper_district.idnews_paper_district', '=', 'news_paper_machine_ads.news_paper_district_id')
->join('news_paper_city', 'news_paper_city.idnews_paper_city', '=', 'news_paper_machine_ads.news_paper_city_id')
->join('news_paper_machine_field', 'news_paper_machine_field.idnews_paper_machine_field', '=', 'news_paper_machine_ads.news_paper_machine_field_id')
->where('district', 'LIKE', '%' . $district . '%')
->where('news_paper_city', 'LIKE', '%' . $city . '%')
->where('machine_field', 'LIKE', '%' . $machine_field .'%')
->get();
I want to filter this query past district value(only district data)
city = only city data
machine field = only machine field data
pass district and city = only district and city data
pass district and machine field= only district and machine field data
pass district, city and machine field = only district, city and machine field data
Please help me solve this problem.
$news_paper_machine_ads = newsPaperMachineAds::join('news_paper_district', 'news_paper_district.idnews_paper_district', '=', 'news_paper_machine_ads.news_paper_district_id')
->join('news_paper_city', 'news_paper_city.idnews_paper_city', '=', 'news_paper_machine_ads.news_paper_city_id')
->join('news_paper_machine_field', 'news_paper_machine_field.idnews_paper_machine_field', '=', 'news_paper_machine_ads.news_paper_machine_field_id')
->where(function($query) use($district,$city,$machine_field){
if($district){
$query->where('district', 'LIKE', '%' . $district . '%');
}
if($city){
$query->where('news_paper_city', 'LIKE', '%' . $city . '%');
}
if($machine_field){
$query->where('machine_field', 'LIKE', '%' . $machine_field . '%');
}
})
->get();
use when and OrWhere query like this
$news_paper_machine_ads = newsPaperMachineAds::join('news_paper_district', 'news_paper_district.idnews_paper_district', '=', 'news_paper_machine_ads.news_paper_district_id')
->join('news_paper_city', 'news_paper_city.idnews_paper_city', '=', 'news_paper_machine_ads.news_paper_city_id')
->join('news_paper_machine_field', 'news_paper_machine_field.idnews_paper_machine_field', '=', 'news_paper_machine_ads.news_paper_machine_field_id')
->when($district, function ($query) use ($district) {
return $query->orWhere('district', 'LIKE', '%' . $district . '%');
})
->when($city, function ($query) use ($city) {
return $query->orWhere('news_paper_city', 'LIKE', '%' . $city . '%');
})
->when($machine_field, function ($query) use ($machine_field) {
return $query->orWhere('machine_field', 'LIKE', '%' . $machine_field .'%');
})->get();
$district = $request->district;
$city = $request->city;
$machine_field = $request->machine_field;
$data_arry = array();
if ($district != "Select") {
$data_arry["district"] = $district;
}
if ($city != "Select") {
$data_arry["city"] = $city;
}
if ($machine_field != "Select") {
$data_arry["machine_field"] = $machine_field;
}
$news_paper_machine_ads = newsPaperMachineAds::join('news_paper_district', 'news_paper_district.idnews_paper_district', '=', 'news_paper_machine_ads.news_paper_district_id')
->join('news_paper_city', 'news_paper_city.idnews_paper_city', '=', 'news_paper_machine_ads.news_paper_city_id')
->join('news_paper_machine_field', 'news_paper_machine_field.idnews_paper_machine_field', '=', 'news_paper_machine_ads.news_paper_machine_field_id')
->where(function ($query) use ($data_arry) {
if (isset($data_arry['district'])) {
$query->where('district', $data_arry['district']);
}
if (isset($data_arry['city'])) {
$query->where('news_paper_city', $data_arry['city']);
}
if (isset($data_arry['machine_field'])) {
$query->where('machine_field', $data_arry['machine_field']);
}
})
->get();

Multiple when() clauses in Laravel

I have a request('name') and request('surname') that I need to search respectively in 2 columns with this logic:
If request('name'):
request('name') in column name_kanki or in column name_romaji
And if request('surname'):
request('surname') in column surname_kanki or in column surname_romaji.
I only could write the following code to perform the search:
->when($nameSearch, function ($query, $nameSearch) {
return $query->where('name', 'LIKE', '%' . $nameSearch . '%')
->orWhere('name_kanji', 'LIKE', '%' . $nameSearch . '%');
})
->when($surnameSearch, function ($query, $surnameSearch) {
return $query->where('surname', 'LIKE', '%' . $surnameSearch . '%')
->orWhere('surname_kanji', 'LIKE', '%' . $surnameSearch . '%');
})
Now the problem is that the first when() and the second when() seem to be connected to each other by OR logic, while I need AND logic.
At present when I insert for example only the name field, the search works fine, but if I insert both name and surname I get the results added to each other (OR logic).
How can I change this relationship to an AND logic (2 filters) that works if both name and surname fields have been compiled by the user?
Thanks in advance.
Hope this will help you to achieve you AND condition result. instead of when I try with where method.
->where(function ($query) use($nameSearch, $surnameSearch) {
if(isset($nameSearch)){
return $query->where('name', 'LIKE', '%' . $nameSearch .
'%')
->orWhere('name_kanji', 'LIKE', '%' . $nameSearch .
'%');
}else{
return $query->where('surname', 'LIKE', '%' .
$surnameSearch . '%')->orWhere('surname_kanji',
'LIKE', '%' . $surnameSearch . '%');
}
})

How to add brackets to a Where Closure within a When Clause for Laravel Eloquent

I'm trying to figure out how to put generate outer brackets on a Combination of OR statements within a WHEN condition with Laravel Eloquent.
$calls = DB::table('incoming_calls')
->leftJoin('scripts', 'SCRIPTID', '=', 'scripts.RECID')
->select('incoming_calls.RECID','INCOMING_DATE','INCOMING_TIME','SCRIPT_NAME AS MYINFO','MSG_FROM')
->when( (strlen(trim($searchterm))>0), function($query) use ($searchterm)
{
return $query->where('MSG_FROM', 'LIKE', '%'.$searchterm.'%')
->orWhere('MSG_TEL', 'LIKE', '%'.$searchterm.'%')
->orWhere('MSG_MOBILE', 'LIKE', '%'.$searchterm.'%')
->orWhere('MSG_COMPANY', 'LIKE', '%'.$searchterm.'%')
->orWhere('incoming_calls.INFOTXT', 'LIKE', '%'.$searchterm.'%')
->orWhere('MSG_ADDRESS', 'LIKE', '%'.$searchterm.'%')
->orWhere('MSG_EMAIL', 'LIKE', '%'.$searchterm.'%');
})
->when($bid>0, function($query) use ($bid)
{
return $query->where('incoming_calls.COMPANYID', "=", $bid);
})
This is generating the following SQL:
select [incoming_calls].[RECID], [INCOMING_DATE], [INCOMING_TIME], [SCRIPT_NAME] as [MYINFO], [MSG_FROM] from [incoming_calls] left join [scripts] on [SCRIPTID] = [scripts].[RECID] where [MSG_FROM] LIKE ? or [MSG_TEL] LIKE ? or [MSG_MOBILE] LIKE ? or [MSG_COMPANY] LIKE ? or [incoming_calls].[INFOTXT] LIKE ? or [MSG_ADDRESS] LIKE ? or [MSG_EMAIL] LIKE ? and [incoming_calls].[COMPANYID] = ? order by [INCOMING_DATE] desc, [INCOMING_TIME] desc
Now what I need is Brackets around the OR Clauses:
select [incoming_calls].[RECID], [INCOMING_DATE], [INCOMING_TIME], [SCRIPT_NAME] as [MYINFO], [MSG_FROM] from [incoming_calls] left join [scripts] on [SCRIPTID] = [scripts].[RECID] where ( [MSG_FROM] LIKE ? or [MSG_TEL] LIKE ? or [MSG_MOBILE] LIKE ? or [MSG_COMPANY] LIKE ? or [incoming_calls].[INFOTXT] LIKE ? or [MSG_ADDRESS] LIKE ? or [MSG_EMAIL] LIKE ?) and [incoming_calls].[COMPANYID] = ? order by [INCOMING_DATE] desc, [INCOMING_TIME] desc
I understand how to do closures stand-alone and could write this using Raw SQL but I;m wanting to figure how do it with Eloquent within the ->when conditionals. Anyone managed to achieve this?
You can do it via parameter grouping like this:
$calls = DB::table('incoming_calls')
->leftJoin('scripts', 'SCRIPTID', '=', 'scripts.RECID')
->select('incoming_calls.RECID','INCOMING_DATE','INCOMING_TIME','SCRIPT_NAME AS MYINFO','MSG_FROM')
->when( (strlen(trim($searchterm))>0), function($query) use ($searchterm) {
return $query->where(function ($query) {
$query->where('MSG_FROM', 'LIKE', '%' . $searchterm . '%')
->orWhere('MSG_TEL', 'LIKE', '%' . $searchterm . '%')
->orWhere('MSG_MOBILE', 'LIKE', '%' . $searchterm . '%')
->orWhere('MSG_COMPANY', 'LIKE', '%' . $searchterm . '%')
->orWhere('incoming_calls.INFOTXT', 'LIKE', '%' . $searchterm . '%')
->orWhere('MSG_ADDRESS', 'LIKE', '%' . $searchterm . '%')
->orWhere('MSG_EMAIL', 'LIKE', '%' . $searchterm . '%');
})
})
->when($bid>0, function($query) use ($bid)
{
return $query->where('incoming_calls.COMPANYID', "=", $bid);
})
you can do this with one where combined with multiple orwhere
$calls = DB::table('incoming_calls')
->leftJoin('scripts', 'SCRIPTID', '=', 'scripts.RECID')
->select('incoming_calls.RECID','INCOMING_DATE','INCOMING_TIME','SCRIPT_NAME AS MYINFO','MSG_FROM')
->when( (strlen(trim($searchterm))>0), function($query) use ($searchterm)
{
return $query->where(funtion($query) use ($searchterm){
$query->where('MSG_FROM', 'LIKE', '%'.$searchterm.'%')
->orWhere('MSG_TEL', 'LIKE', '%'.$searchterm.'%')
->orWhere('MSG_MOBILE', 'LIKE', '%'.$searchterm.'%')
->orWhere('MSG_COMPANY', 'LIKE', '%'.$searchterm.'%')
->orWhere('incoming_calls.INFOTXT', 'LIKE', '%'.$searchterm.'%')
->orWhere('MSG_ADDRESS', 'LIKE', '%'.$searchterm.'%')
->orWhere('MSG_EMAIL', 'LIKE', '%'.$searchterm.'%');
})
})
->when($bid>0, function($query) use ($bid)
{
return $query->where('incoming_calls.COMPANYID', "=", $bid);
})

Where on multiple whereHas

I need to be able to run a where query on a model and multiple of its relations at once. At the moment I am doing it like this, for a single relation
$users = $users->whereHas('contacts', function ($query) use ($request) {
$query->where('name', 'like', '%' . $request->input('filters_search') . '%')
->orWhere('contact_name', 'like', '%' . $request->input('filters_search') . '%');
);
So this searches my user.name and contact.name fields for the search input, but I need to be able to search multiple relations, not just contacts. Something like this
$users = $users->whereHas(['contacts','photos','status'], function ($query) use ($request) {
$query->where('name', 'like', '%' . $request->input('filters_search') . '%')
->orWhere('contact_name', 'like', '%' . $request->input('filters_search') . '%');
);
So that I can search through the user, contacts, photos and status tables/relations for the search input.
What is the cleanest/best way to achieve this?
If you did happen to be searching the same columns in all of your tables, you could extract the closure to a variable:
$closure = function ($query) use ($request) {
$query->where('name', 'like', '%' . $request->input('filters_search') . '%')
->orWhere('contact_name', 'like', '%' . $request->input('filters_search') . '%');
}
But you'd still have to independently query each relationship:
$users->whereHas('contacts', $closure)
->orWhereHas('photos', $closure)
->orWhereHas('status', $closure);
You should try this:
$users = $users->whereHas('photos','status', function($query) {
$query->where('name', 'like', '%' . $request->input('filters_search') . '%');
});
$users = $users->whereHas('contacts', function($query) use ($request) {
$query->where('contact_name', 'like', '%' . $request->input('filters_search') . '%');
});
OR you should try below way:
User::where('name', 'like', '%' . $request->input('filters_search') . '%')
->whereHas('contacts', function($query) use ($request) {
$query->where('contact_name', 'like', '%' . $request->input('filters_search') . '%');
})
->get();

"LIKE" query on table with Foreign Key assigned to multiple tables based upon relationship type

My issue has three tables: "comments", "users" & "company_contacts"
The "comments" table has two columns: "company_contact (INT)" & "company_contact_kind (String)"
comments.company_contact is either assigned to users.id or company_contacts.id based upon either if comments.company_contact_kind = 'contact' or if comments.company_contact_kind = 'user'
Here is my query:
$data['comments'] = Comment::join('users', 'comments.creator_id', '=', 'users.id')
->join('users AS user_contacts', 'comments.company_contact', '=', 'user_contacts.id')
->join('company_contacts', 'company_contacts.id', '=', 'comments.company_contact')
->where('comments.commentable_type', $request->type)
->where('comments.commentable_id', $request->company_id)
->where(function($query) use ($request){
$query->orWhere('body', 'LIKE', '%' . $request->q . '%')
->orWhere('users.first_name', 'LIKE', '%' . $request->q . '%')
->orWhere('users.last_name', 'LIKE', '%' . $request->q . '%')
->orWhere('user_contacts.first_name', 'LIKE', '%' . $request->q . '%')
->orWhere('user_contacts.last_name', 'LIKE', '%' . $request->q . '%')
->orWhere('company_contacts.first_name', 'LIKE', '%' . $request->q . '%')
->orWhere('company_contacts.last_name', 'LIKE', '%' . $request->q . '%')
->orWhere('comments.contact_type', 'LIKE', '%' . $request->q . '%')
->orWhere('tags', 'LIKE', '%' . $request->q . '%');
})
->orderBy('comments.created_at', 'DESC')
->select('comments.*')
->get();
My Issue:
When searching for a specific Comment Contact, because I reference both users and company contacts within my query and both equal comments.company_contact, if I search for either the first or last name of company_contacts.id, it'll return results with users.id as the comments.company_contact because comments.company_contact references both users and company_contacts.
Is there a way to set a condition within the query for something more intuitive?
Solved:
Thanks to the answer proposed by #cmerriman, I was able to tweak the answer and solve it by the following query:
$data['comments'] = Comment::join('users', 'comments.creator_id', '=', 'users.id')
->leftJoin('users AS user_contacts', function ($join) {
$join->where('comments.company_contact_kind', '=', 'user')
->on('comments.company_contact', '=','user_contacts.id');
})
->leftJoin('company_contacts', function ($join) {
$join->where('comments.company_contact_kind', '=', 'contact')
->on('comments.company_contact', '=','company_contacts.id');
})
->where('comments.commentable_type', $request->type)
->where('comments.commentable_id', $request->company_id)
->where(function($query) use ($request){
$query->orWhere('body', 'LIKE', '%' . $request->q . '%')
->orWhere('users.first_name', 'LIKE', '%' . $request->q . '%')
->orWhere('users.last_name', 'LIKE', '%' . $request->q . '%')
->orWhere('user_contacts.first_name', 'LIKE', '%' . $request->q . '%')
->orWhere('user_contacts.last_name', 'LIKE', '%' . $request->q . '%')
->orWhere('company_contacts.first_name', 'LIKE', '%' . $request->q . '%')
->orWhere('company_contacts.last_name', 'LIKE', '%' . $request->q . '%')
->orWhere('comments.contact_type', 'LIKE', '%' . $request->q . '%')
->orWhere('tags', 'LIKE', '%' . $request->q . '%');
})
->orderBy('comments.created_at', 'DESC')
->select('comments.*')
->get();
I've never used Laravel, but if I am reading the docs correctly, try changing
->join('users AS user_contacts', 'comments.company_contact', '=', 'user_contacts.id')
->join('company_contacts', 'company_contacts.id', '=', 'comments.company_contact')
to
->join('users AS user_contacts', function ($join) {
$join->on('comments.company_contact', '=','user_contacts.id')
->andOn('comments.company_contact_kind, '=', 'user'); } )
->join('companyusers AS user_contacts', function ($join) {
$join->on('comments.company_contact', '=','company_contacts.id')
->andOn('comments.company_contact_kind, '=', 'contact'); } )

Categories