Laravel | How to perform search with multiple attributes - php

I am creating property website and i am doing search with number of attributes, but the problem is that in search controller i have very large code and its very difficult to handle, is there any other solution exist in laravel?
$list_property = Listing_property::where([
['property_type', $request['property_type']],
['city', $request['city']],
['location', $request['location']],
['property_area_type', $request['property_area_type']],
['property_size', $request['property_size']],
['price', $min],
['price', $max]
])
->orderBy('updated_at', 'DESC')
->paginate(21);

The easiest way to search multiple column :
public function search(Request $request){
$query = $request->search;
$users = DB::table('users');
if($query){
$users = $users->where('name', 'LIKE', "%$query%");
}
if($request->city){
$users = $users->where('city',$request->city);
}
if($request->town){
$users = $users->where('town', $request->town);
}
if($request->unit){
$users = $users->where('unit', $request->unit);
}
$users->get();
return view('users.index')->with('users', $users);
}

Related

Laravel if request not empty add orWhere

public function index(Request $request) {
if ($request->has('deleted')) {
$assistants = Assistant::onlyTrashed()->where(1);
if ($request->has('firstName'))
$assistants = $assistants->orWhere('firstname', 'LIKE', $request->firstName.'%');
if ($request->has('lastName'))
$assistants = $assistants->orWhere('lastname', 'LIKE', $request->lastName.'%');
if ($request->has('email'))
$assistants = $assistants->orWhere('email', 'LIKE', $request->email.'%');
} else {
$assistants = Assistant::all()->where(1);
if ($request->has('firstName'))
$assistants = $assistants->orWhere('firstname', 'LIKE', $request->firstName.'%');
if ($request->has('lastName'))
$assistants = $assistants->orWhere('lastname', 'LIKE', $request->lastName.'%');
if ($request->has('email'))
$assistants = $assistants->orWhere('email', 'LIKE', $request->email.'%');
}
return $this->showAll($assistants);
}
I am trying to check if firstName, lastName or email is not empty, add to query with LIKE command.
But it returns an error :
Type error: Too few arguments to function
Illuminate\Support\Collection::where(), 1 passed
in Laravel 5.6.
You have multiple problems.
where(1) is not a valid Query Builder call. You also don't seem to need this.
You don't need to repeat all of these request->has() calls, put them below the if ... else ...
Assistants::all() will actually run a query and return all rows in a collection. Use Assistants::query() to return a Query Builder instance.

Putting order by inside with(), in Laravel

I have a controller that filters the columns in it's table based on the variable received in the get query, then it returns it with another table's value based on the id of the variable gotten, But now for the $filter_by_name condition I want to filter by the first_name column in the users table, please how can i do that, i.e I want to return the users table ordered by their first_name column
DB-STRUCTURE
COMPANY-USERS TABLE
id company_id user_id role created modified active department_level
USERS TABLE
id
first_name
last_name
email
password
active_company
profile_photo_id
verified
active
remember_token
created
modified
Company-users Controller
public function getCompanyUsers($companyId)
{
$filter = strtolower(Input::get('filter'));
if($filter && $filter === 'on' ){
$filter_by_date = strtolower(Input::get('filter_by_date'));
$filter_by_name = strtolower(Input::get('filter_by_name'));
$filter_by_role = strtolower(Input::get('filter_by_role'));
if($filter_by_date){
if($filter_by_date == 'oldest'){
$users = CompanyUser::where('company_id', $companyId)->orderBy('created', 'DESC')
->with(['user','user.userDepartments','user.userDepartments.department'])->get();
return $users;
}else{
$users = CompanyUser::where('company_id', $companyId)->orderBy('created', 'ASC')
->with(['user','user.userDepartments','user.userDepartments.department'])->get();
return $users;
}
}elseif ($filter_by_name){
if($filter_by_name == 'ascending'){
$users = CompanyUser::where('company_id', $companyId)->orderBy('first_name', 'ASC')
->with(['user','user.userDepartments','user.userDepartments.department'])->get();
return $users;
}else{
$users = CompanyUser::where('company_id', $companyId)->orderBy('first_name', 'DESC')
->with(['user','user.userDepartments','user.userDepartments.department'])->get();
return $users;
}
}elseif($filter_by_role){
if($filter_by_role == 'member'){
$users = CompanyUser::where(['company_id' => $companyId,'role'=>'Member'])->with(['user','user.userDepartments','user.userDepartments.department'])->get();
// dd($users);
return $users;
}elseif($filter_by_role == 'manager'){
$users = CompanyUser::where(['company_id' => $companyId,'role'=>'Manager'])->with(['user','user.userDepartments','user.userDepartments.department'])->get();
return $users;
}else
$users = CompanyUser::where(['company_id' => $companyId,'role'=>'Admin'])->with(['user','user.userDepartments','user.userDepartments.department'])->get();
return $users;
}
}
$users = CompanyUser::where('company_id', $companyId)->
with(['user','user.userDepartments','user.userDepartments.department'])->get();
//dd($users);
return $users;
}
you can pass closer functions when eager loading to add constrains like that, see more on laravel docs:
$users = CompanyUser::with(['user'=> function ($query) {
$query->orderBy('first_name', 'desc');
}
])
->where('company_id', $companyId)
->get();
You have to do orderBy on a relational model like below:
$users = CompanyUser::where('company_id', $companyId)
->with(['user' => function($subQuery){
$subQuery->orderBy('first_name', 'ASC');
}])
->with(['user.userDepartments','user.userDepartments.department'])
->get();
return $users;
One way is to add column 'first_name' in the 'COMPANY-USERS' TABLE
And now you can do order by ('first_name','ASC').
I think its not the best way but no other idea comes in my head.

Pass several columns to an orderBy method via URL

I have this code in Lumen 5.6 (Laravel microframework) and I want to have an orderBy method for several columns, for example, http://apisurl/books?orderBy=devices,name,restrictions,category also send asc or desc order.
Lumen's documentation says that we can use the orderBy like this
$books = PartnersBooks::all()->orderBy('device', 'asc')->orderBy('restrictions', 'asc')->get();
So, I made a function with a foreach to fill an array with different orderBy requests values and tried to put on eloquent queries without succeeding.
Can anybody help me?
use Illuminate\Http\Request;
public function index(Request $request)
{
$limit = $request->input('limit');
$books = PartnersBooks::where('is_direct', '=', 1)
->with('direct')
->whereHas('direct', function ($query) {
$query->enable()
->select(['id', 'book_id', 'name', 'devices', 'flow', 'restrictions', 'countries', 'targeting']);
})
->orderBy('id', 'asc')
->paginate($limit, ['id', 'category', 'description']);
$status = !is_null($books) ? 200 : 204;
return response()->json($books, $status);
}
You can do this:
// Get order by input
$orderByInput = $request->input('orderBy');
// If it's not empty explode by ',' to get them in an array,
// otherwise make an empty array
$orderByParams = !empty($orderByInput)
? explode(',', $orderByInput)
: [];
$query = PartnersBooks::where('is_direct', '=', 1)
->with('direct')
->whereHas('direct', function ($query) {
$query->enable()
->select(['id', 'book_id', 'name', 'devices', 'flow', 'restrictions', 'countries', 'targeting']);
});
// Foreach over the parameters and dynamically add an orderBy
// to the query for each parameter
foreach ($orderByParams as $param) {
$query = $query->orderBy($param);
}
// End the query and get the results
$result = $query->paginate($limit);

Return a specific column from a many-many relationship using php in laravel

In my database I have two models, User and Role defined as many-many relationship, I'm trying to write a code in laravel that takes the id from the roles table and gets all the user fullnames from the users table.
I have defined a route that looks like this :
Route::get('roleUser/{role}', 'RoleController#RoleNames');
in which i pass the role name with it, as you see above
In my RoleController, I defined the method roleNames to do the job
public function RoleNames($role)
{
$idrole = Role::where('name', '=', $role)->first()->id;
//$iduser = DB::table('assigned_roles')->where('role_id', '=', $idrole)->first()->id;
$iduser = DB::table('assigned_roles')->where('role_id', '=', $idrole)->get(array('id'));
$usersUnderRole = array();
foreach ($iduser as $idusers) {
$usersUnderRole = array_add($usersUnderRole, $idrole, $idusers);
$full_name = DB::table('users')->where('id', '=', $idusers)->get()->full_name;
}
return $this->respond([
'result' => $this -> roleTransformer->transform($full_name)
]);
}
This code is meant to take the role_id from the roles table and gets the appropriate user_ids by the pivot table assigned_roles, puts them in an array and fetches the correspondent full_names, but it says this error:
Object of class stdClass could not be converted to string
Any advice on how to get it to work?
This will give you all the users who belong to the given role:
$role_id = 3;
$result = DB::table('role_user')
->select('users.full_name')
->where('role_user.role_id', $role_id)
->leftJoin('users', 'users.id', '=', 'role_user.user_id')
->get();
var_dump($result);
$full_names = DB::table('users')->where('id', '=', $idusers)->lists('users.full_name');
Besides the solution #lamzazo provided, there is another way to go with the answer :
$role2 = Role::where('name', '=', $role)->first();
$idrole = Role::where('name', '=', $role)->first()->id;
//$iduser = DB::table('assigned_roles')->where('role_id', '=', $idrole);
$user = DB::table('assigned_roles')->where('role_id', '=', $idrole)->get();
// $user = DB::table('users')->where('id', '=', $iduser);
// return $this->respond($iduser[0]->user_id);
$userArray = array();
$i=0;
foreach ($user as $users) {
$iduser= $users->user_id;
$allusers = User::where('id', '=', $iduser)->get(array('id', 'full_name'));
$userArray = array_add($userArray, $i . '', $allusers);
$i++;
}
return $this->respond([
'result' => $this -> roleTransformer->testTransform($role2, $userArray)
]);

Laravel Eloquent search two optional fields

I'm trying to search two optional tables using eloquent:
$users = User::where('ProfileType', '=', 2)
->where(function($query) {
$query->where('BandName', 'LIKE', "%$artist%");
$query->or_where('Genre', 'LIKE', "%$genre%");
})->get();
This works fine for return all results when a user does an empty search, but I am not sure how to adjust this for to search for bandname when that is present and vise versa.
Just to explain what happens on answer below:
Eloquent does a tricky thing here: When you call User::where(...) it returns a Database\ Query object. This is basically the same thing as DB::table('users')->where(...), a chainable object for constructing SQL queries.
So having:
// Instantiates a Query object
$query = User::where('ProfileType', '=', '2');
$query->where(function($query) {
// Adds a clause to the query
if ($artist = Input::get('artist')) {
$query->where_nested('BandName', 'LIKE', "%$artist%", 'OR');
}
// And another
if ($genre = Input::get('genre')) {
$query->where_nested('Genre', 'LIKE', "%$genre%", 'OR');
}
});
// Executes the query and fetches it's results
$users = $query->get();
Building on Vinicius' answer here's what worked:
// Instantiates a Query object
$query = User::where('ProfileType', '=', '2');
// Adds a clause to the query
if ($artist = Input::get('artist')) {
$query->where('BandName', 'LIKE', "%$artist%");
// Temp Usernamesearch
$query->or_where('NickName', 'LIKE', "%$artist%");
}
// Genre - switch function if artist is not empty
if ($genre = Input::get('genre')) {
$func = ($artist) ? 'or_where' : 'where';
$query->$func('Genre', 'LIKE', "%$genre%");
}
// Executes the query and fetches it's results
$users = $query->get();
Turns out that the second optional field must use or_where only if $artist is not set.
Thanks for your help
I think this is what youre after. Your view would have a form to search artist/genre one or the other can be set, or both, or none.
$users = User::where('ProfileType', '=', 2);
if (Input::has('artist')) {
$users = $users->where('BandName', 'LIKE', '%'.Input::get('artist').'%');
}
if (Input::has('genre')) {
$users = $users->where('Genre', 'LIKE', '%'.Input::get('genre').'%');
}
$users = $users->get();
$query = FormEntry::with('form')->where('domain_id', $id);
$query->where(function($query) use ($search, $start, $limit, $order, $dir) {
$query->where('first_name', 'LIKE', "%{$search}%")
->orWhere('last_name', 'LIKE', "%{$search}%")
->orWhere('email', 'LIKE', "%{$search}%")
->offset($start)
->limit($limit)
->orderBy($order, $dir);
});
$entries = $query->get();
$totalFiltered = $query->count();

Categories