I have a small search form that allow user search for his clients by id or by first_name,last_name.
In my DB fist_name and last_name are in two separate column so when I try to search client by name I need to use a query that check both the column.
Here my code:
//Recupero l'utente corrente
$current_user = Auth::user()->id;
//Preparo la query
$query = DB::table('clients');
//Recupero l'eventuale nome e ID di ricerca cliente
$client_id = Input::get('client_id');
$client_name = Input::get('client_name');
//Controllo se devo fare una ricerca per ID
if( is_numeric($client_id) )
{
$query->where('id', '=', $client_id);
}
elseif( trim($client_name) != "" )
{
//Controllo se invece ho il nome
$query->where('nome', 'LIKE', "%$client_name%")->orWhere('cognome', 'LIKE', "%$client_name%");
}
//Recupero i clienti
$data['clients'] = $query->where('id_agente', $current_user)->paginate(10);
The first if will check if the users select the client by ID while the second need to check the name and last_name.
The problem is that in the second case the last where is ignored and return all the result in the table that match the input, so I can see data of other users.
How can I modify my code so the where('id_agente', $current_user) will always considered?
In your elseif section just replace the following line:
$query->where('nome', 'LIKE', "%$client_name%")->orWhere('cognome', 'LIKE', "%$client_name%");
With this:
$query->where(function($q) use ($client_name) {
$q->where('nome', 'LIKE', "%$client_name%")
->orWhere('cognome', 'LIKE', "%$client_name%");
});
Pass a closure to where() in your elseif.
elseif( trim($client_name) != "" )
{
$query->where(function($subQuery) use ($client_name){
$subQuery->where('nome', 'LIKE', "%$client_name%");
$subQuery->orWhere('cognome', 'LIKE', "%$client_name%");
}};
}
$data['clients'] = $query->where('id_agente', $current_user)->paginate(10);
Or.. simplify the whole script:
$client_id = trim(Input::get('client_id'));
$client_name = trim(Input::get('client_name'));
if(empty($client_id) && empty($client_id))
return false;
$data['cleints'] = DB::table('clients')
->where((!empty($client_id)) ? function($q) use ($client_id){
$q->where('id', '=', $client_id)->first();
} : function($q) use ($client_name) {
$q->where('nome', 'LIKE', "%$client_name%");
$q->orWhere('cognome', 'LIKE', "%$client_name%");
})->where('id_agente', Auth::user()->id)
->paginate(10);
Related
I have a GET form with three filters.
make
Year
country
I need to get all posts from db. But filter the results based on these three filters.
If a country is selected, get posts for that country only or all countries.
if a make is selected, get posts for that make only or all makes
if a year is selected, get posts for that year only or all years
how to write one query that filters all these three options. What I have done is used if and else statements and written different queries for each scenario. That's 9 queries to get one information. Can we make it dynamic and just have one query?
My Example query:
public function search(Request $request)
{
$search=$request->input('search');
if($request->input('country') == "all")
{
$posts = Post::where('status','Published')->orderBy('status_change','DESC')
->where('status','Published')
->where(function($query) use ($search){
$query->where('title','LIKE','%'.$search.'%');
$query->orWhere('model','LIKE','%'.$search.'%');
$query->orWhere('notes','LIKE','%'.$search.'%');
$query->orWhere('description','LIKE','%'.$search.'%');
})
->paginate(25);
}
else
{
$posts = Country::where('country_name', $request->input('country'))->first()->posts()->orderBy('status_change','DESC')
->where('status','Published')
->where(function($query) use ($search){
$query->where('title','LIKE','%'.$search.'%');
$query->orWhere('model','LIKE','%'.$search.'%');
$query->orWhere('notes','LIKE','%'.$search.'%');
$query->orWhere('description','LIKE','%'.$search.'%');
})
->paginate(25);
}
return view('welcome')
->with('published_posts',$posts)
;
}
I think something like this would work:
/**
* #param Request $request
*/
function search(Request $request)
{
$postsQuery = Post::where('status', 'Published');
if ($request->has('country')) {
$country = $request->country;
// assuming relationships are setup correclty
$postsQuery->whereHas('country', function ($query) use ($country) {
$query->where('country_name', 'LIKE', $country);
});
}
if ($request->has('search')) {
$postsQuery->where(function ($query) use ($search) {
$query->where('title', 'LIKE', '%' . $request->search . '%');
$query->orWhere('model', 'LIKE', '%' . $request->search . '%');
$query->orWhere('notes', 'LIKE', '%' . $request->search . '%');
$query->orWhere('description', 'LIKE', '%' . $request->search . '%');
});
}
$postsQuery->orderBy('status_change', 'DESC')->paginate(25);
return view('welcome')->with('published_posts', $result);
}
I used 'when' method.
$make = null;
$year = null;
$country = null;
if($request->filled('make')){
$make = $request->query('make');
}
if($request->filled('year')){
$year = $request->query('year');
}
if($request->filled('country')){
$country = $request->query('country');
}
$posts = DB::table('posts')
->when($make, function($query, $make){
return $query->where("make", "=", $make);
})
->when($year, function($query, $year){
return $query->whereYear("year", "=", $year);
})
->when($country, function($query, $country){
return $query->where('country', "like", $country);
})
->get();
Check out the Laravel Docs:
Check out an article here
I want to find a data from two tables based on the name contained in the users, but I am having problems.
This is the users table containing the id, and name.
This is the student table that contains the id, and user_id.
Where user_id student = id users.
public function search(Request $request)
{
$keywords = trim($request->input('keywords'));
if (!empty($keywords)) {
$id_class = $request->input('id_class');
//Query
$query = User()
->leftjoin('student', 'users.id', '=', 'student.user_id')
->where('users.name', 'LIKE', '%' . $keywords . '%');
(!empty($id_class)) ? $query->Kelas($id_class) : '';
$data_student = $query->paginate(10);
//URL link pagination
$pagination = (!empty($id_class)) ? $pagination = $data_student->appends(['id_class' => $id_class]) : '';
$pagination = $data_student->appends(['keywords' => $keywords]);
$amount_data = $=data_student->total();
return view('student.index', compact('data_student', 'keywords', 'pagination', 'amount_data', 'id_class'));
}
return redirect('student');
}
Call to undefined function App\Http\Controllers\User()
As mentioned previously you need to correctly refer to the User class with namespace, you also need to change thew following:
$query = User()
->leftjoin('student', 'users.id', '=', 'student.user_id')
->where('users.name', 'LIKE', '%' . $keywords . '%');
to:
$query = User::leftjoin('student', 'users.id', '=', 'student.user_id')
->where('users.name', 'LIKE', '%' . $keywords . '%');
You must call the first method on the class as static with ::.
Also another potential typo you join the table student should it be plural; students?
I have the following function
public function index(Request $request)
{
$results = Service::whereHas('conditions', function ($query) use ($request){
$query->whereIn('id', $request->conditions);
})
->whereHas('locations', function ($query) use ($request){
$ran = false;
foreach($request->locations as $location)
{
if(!$ran)
{
$query->Where('town', 'like', '%'.$location.'%')
->orWhere('city', 'like', '%'.$location.'%');
}
else
{
$query->orWhere('town', 'like', '%'.$location.'%')
->orWhere('city', 'like', '%'.$location.'%');
}
$ran = true;
}
})
->with('types', 'contacts', 'locations.datetimes')->toSql();
dd($results);
}
which produces
select * from `services` where exists
(select * from `conditions` inner join `condition_service` on `conditions`.`id` = `condition_service`.`condition_id` where `services`.`id` = `condition_service`.`service_id` and `id` in (13, 14) and `conditions`.`deleted_at` is null)
and exists
(select * from `service_locations` inner join `service_location_service` on `service_locations`.`id` = `service_location_service`.`service_location_id` where `services`.`id` = `service_location_service`.`service_id` and
(`town` like 'manchester' or `city` like 'manchester' or `town` like 'crewe' or `city` like 'crewe')
and `service_locations`.`deleted_at` is null) and `services`.`deleted_at` is null
The problem is the whereHas on locations brings back all results, whereas I only want the result where the town/city is a match. Whats the best way to achieve this?
i think you need to group your location query using the callback which wraps the query in () and just process the first location directly remove it from array and iterate over loop. so below code should work in your case.
$results = Service::whereHas('conditions', function ($query) use ($request){
$query->whereIn('id', $request->conditions);
})
->whereHas('locations', function ($query) use ($request){
$locations = $request->locations;
$query->where(function($builder) use($locations){
$builder->where('town', 'like', '%' . $locations[0] . '%')
->orWhere('city', 'like', '%'.$locations[0].'%');
unset($locations[0]); //remove first item as it is processed
foreach($locations as $location) {
$builder->orWhere('town', 'like', '%'.$location.'%')
->orWhere('city', 'like', '%'.$location.'%');
}
});
});
let me know if you find any problem with it. :)
I managed to figure it out late last night.
I moved the with() to the top of the query and made a callback on locations.
public static function newGetSearchResults($request)
{
return Service::with(['types', 'contacts', 'locations.datetimes', 'locations' => function($query) use($request) {
$ran = false;
foreach($request->locations as $location)
{
if(!$ran)
{
$query->Where('town', 'like', '%'.$location.'%')
->orWhere('city', 'like', '%'.$location.'%');
}
else
{
$query->orWhere('town', 'like', '%'.$location.'%')
->orWhere('city', 'like', '%'.$location.'%');
}
$ran = true;
}
}])
->whereHas('conditions', function ($query) use ($request){
$query->whereIn('id', $request->conditions);
})->get();
}
I currently have a search function on my website, I need it to search 3 fields - appid, mobilenumber, email .
Right now once the user enters the data in the search box it searches all 3 but its not working.
Data is collected using GET.
Here is my query
http://www.example.com?id=1&searchall=07853637362
$mobile = INPUT::get('searchall');
$email = INPUT::get('searchall');
$appid = INPUT::get('searchall');
$data = DB::table('leads')
->when($mobile, function($query) use ($mobile){
return $query->where('MobilePhone', $mobile);
})
->when($email, function($query) use ($email){
return $query->where('Email', $email);
})
->when($appid, function($query) use ($appid){
return $query->where('AppID', $appid);
})
->get();
So I need it to search each field until it finds the correct field value.
$mobile = INPUT::get('searchall');
$email = INPUT::get('searchall');
$appid = INPUT::get('searchall');
$data = DB::table('leads')
->when($mobile, function($query) use ($mobile){
return $query->orWhere('MobilePhone', $mobile);
})
->when($email, function($query) use ($email){
return $query->orWhere('Email', $email);
})
->when($appid, function($query) use ($appid){
return $query->orWhere('AppID', $appid);
})->get();
To search data try with like
->when($mobile, function($query) use ($mobile){
return $query->where('MobilePhone', 'like', '%'. $mobile . '%');
})
to actually search each field, use orWhere
$keywords = Input::get('searchall');
$data = DB::table('leads')
->where('mobilephone', '=', $keywords)
->orWhere('email', '=', $keywords)
->orWhere('AppID', '=', $keywords)
->get();
I don't understand why you need the same value from the user using 3 variables, so the following is the simplified version:
$searched = Input::get('searchall');
$matched = DB::table('leads')
->where('MobilePhone', $searched)
->orWhere('Email', $searched)
->orWhere('AppID', $searched)
->get();
I have an eloquent models as,
User : users(id, username, password, email, status)
Profile : profiles(id, user_id, first_name, last_name, gender, dob)
In the controller logic, I am eagerly loading the Profile model.
I can do this,
$user = User::with('Profile')->get();
or
$user = User::with('Profile')->where('status', '1')->get();
but how to do something like,
$user = User::with('Profile')->where('status', '1')->where('gender', 'Male')->get();
That's where whereHas comes in handy:
$user = User::with('Profile')->where('status', 1)->whereHas('Profile', function($q){
$q->where('gender', 'Male');
})->get();
Basically it adds the condition that the user needs to have a profile with gender = Male
If you want to search multiple columns in relation model.
$searchText = 'test text';
Product::with('owner')->where(function($query) use ($searchText)
{
$query->where('product_name', 'LIKE', '%' . $searchText . '%');
$columns = ['product_code', 'place_location', 'remark'];
foreach ($columns as $column ) {
$query->orWhere($column, 'LIKE', '%' . $searchText . '%');
}
$query->orWhereHas('owner', function($q) use ($searchText) {
$q->where(function($q) use ($searchText) {
$q->where('name', 'LIKE', '%' . $searchText . '%');
$q->orWhere('company_name', 'LIKE', '%' . $searchText . '%');
});
});
});
Let's say you've multiple relations
and you want to search records based on multiple relational columns value
User::with('associate')
->where('name', 'like', '%' . $input . '%')
->orWhere(function ($query) use ($input) {
$query->whereHas('associate', function ($q) use ($input) {
$q->where('first_name', 'like', '%' . $input . '%');
});
})
->orWhere(function ($query) use ($input) {
$query->with('roles')->whereHas('roles', function ($q) use ($input) {
$q->where('display_name', 'like', '%' . $input . '%');
});
})
->get();
Suppose, Your search input field name is q.
function name(Request $request){
$query = User::select();
if($request->q && $request->q !=''){
// if you search
$keyword = $request->q;
$query = User::with('Profile')->whereHas('Profile', function($q) use
($keyword){
$q->where('gender', 'like', "%{$keyword}%" );
});
}
$query->latest('id')->paginate();
}