Laravel search by optionals items - php

i would like to create simple ability for my users to search database table as an optional items, for example search by name or mobile or email. to create this ability i'm created this simple controller:
class SearchTransactionController extends Controller
{
public function search(Request $request)
{
$query = BuyCard::select('*');
foreach ($request->only(['name', 'mobile', 'email']) as $key => $value) {
if (strlen($value) > 0) {
$query->where($key, 'LIKE', "%$value%");
}
}
$query->orderBy('id', 'DESC');
$data = $query->paginate(15);
return view('report_buycard_transactions.index')
->with('info', $data);
}
}
all name,mobile,email is optional for search but my code dont correct search in database and return all columns

it's because adding multiple ->where() calls mean it attempts to find only rows where the search string is in all 3 of those columns, try doing this:
class SearchTransactionController extends Controller
{
public function search(Request $request)
{
$query = BuyCard::select('*');
$first = true;
foreach ($request->only(['name', 'mobile', 'email']) as $key => $value) {
if (strlen($value) > 0) {
if($first){
$query->where($key, 'LIKE', "%$value%");
$first = false;
} else {
$query->orwhere($key, 'LIKE', "%$value%");
}
}
}
$query->orderBy('id', 'DESC');
$data = $query->paginate(15);
return view('report_buycard_transactions.index')
->with('info', $data);
}
}

Related

Laravel many to many that match all data from array

I have products which have a many to many relationship with filters
The user may choose multiple filters and I want to display all products that match the selected filters. But by matching them I mean containing all of them (not only some of them). Here's an example to explain what I mean, let's say that the user is on the cars category page and he wants to filter all cars that are from year 2013 AND have 4x4. Now if the user selects those filters it will show all the cars that are from year 2013 OR have 4x4.
Here's my code in the controller:
public function showFilteredProducts(Request $request)
{
$products = collect([]);
$this->request = $request;
foreach ($request->filters as $filter_id => $active) {
$this->filter_id = $filter_id;
$queriedProducts = Product::whereHas('filters', function($query) {
$query->where('filters.id', $this->filter_id);
})
->whereHas('category', function($query) {
$query->where('slug', $this->request->category_slug);
})
->get();
foreach ($queriedProducts as $product) {
if (!$products->contains($product)) {
$products[] = $product;
}
}
}
return response()->json($products->chunk(3));
}
As i explained this now returns the products if they match only one of the filters, but I want them to match all of them.
try this
public function showFilteredProducts(Request $request)
{
$filters = $request->filters;
$query = Product::query();
foreach ($filters as $filter_id => $active) {
$query = $query->whereHas('filters', function($query) use ($filter_id) {
$query->where('filters.id', $filter_id);
});
}
$query = $query->whereHas('category', function($query) use ($request) {
$query->where('slug', $request->category_slug);
})
$products = $query->get();
return $products->chunk(3);
}
alternatively, based on your previous code, you can use array_intersect like this:
public function showFilteredProducts(Request $request)
{
$products = collect([]);
$this->request = $request;
foreach ($request->filters as $filter_id => $active) {
$this->filter_id = $filter_id;
$queriedProducts = Product::whereHas('filters', function($query) {
$query->where('filters.id', );
})
->whereHas('category', function($query) {
$query->where('slug', $this->request->category_slug);
})
->get();
$products = array_intersect($queriedProducts, $products);
}
return response()->json($products->chunk(3));
}
I think you want to use orWhereHas() instead of whereHas() on the second table that you are checking against.

Laravel Eloquent Relationship with 3 tables

I need to get contact name using laravel Eloquent
I have table stucture below :
CallLogs Table :
id,user_id,PhoneNumber
Phone Table :
id,PhoneNumber,contact_id
contact table :
id,Name
//CallLogs Model :
public function phone()
{
return $this->hasManyThrough('\App\Models\Phone','\App\Models\Contact','id','phoneNumber','phoneNumber');
}
// phone Model :
public function contact()
{
return $this->belongsTo(Contact::class);
}
// Contact Model:
public function phones()
{
return $this->belongsTo(Phone::class, 'contact_id');
}
Join Query :
Please look with->(['phone']) in below query
$data = CallLogs::select('*')->where('call_type', '=', '1')
->when($q, function ($query) use ($q) {
return $query->where(function ($query) use ($q) {
/** #var Builder $query */
$preparedQ = '%' . $q . '%';
$num = 0;
foreach (
[
'to_call',
'from_call',
'callcost',
'created_at'
] AS $field
) {
if ($num) {
$query = $query->orWhere($field, 'LIKE', $preparedQ);
} else {
$query = $query->where($field, 'LIKE', $preparedQ);
}
$num++;
}
return $query;
});
});
//dd($data);exit;
$outgoingcalls = $this->CallLogsFilter->applyFilter($request->get('filter', []), $data);
//$outgoingcalls = $data->paginate($count, ['*'], 'page', $pageNumber);
// Here I am using getting Name
$outgoingcalls = $outgoingcalls->with(['phone'])
->sortable()
->paginate($count, ['*'], 'page', $pageNumber);
$links = $outgoingcalls->appends(Input::except('page', 'table_only'))->links();
$filter = $request->get('search');
return compact('outgoingcalls', 'links','filter');

Laravel filters system with multi checkbox

I am using laravel 5.4 and I want to filter search. its my front-end
my code looks like this
class DeviceFilterController extends Controller
{
public function filter(Feature $feature){
$marks = isset($_POST["mark"]) ? $_POST["mark"] : null;
$feature = $feature->newQuery();
if(isset($marks ))
{
foreach ($marks as $value)
{
$feature->where('device_mark', $value);
}
}
return $feature->get();
}
}
that result just one entry
You could take a different approach using whereIn(), assuming you mark input is an array of IDs like [1, 4, 8, 22].
public function filter(Request $request)
{
$features = Feature::when($request->has('mark'), function($query) use ($request) {
return $query->whereIn('device_mark', $request->mark); //Assuming you are passing an array of IDs
})->get();
return $features;
}
when() closure will only executes when you are sending 'mark' input. Doing it without when would look like this
public function filter(Request $request)
{
$features = [];
if ( $request->has('mark') && $request->mark != '' ) {
$features = Feature::whereIn('device_mark', $request->mark)->get();
} else {
$features = Feature::get();
}
return $features;
}

Laravel Pages with Categories Route Parameters

based on the example from here https://scotch.io/tutorials/simple-and-easy-laravel-routing#blog-pages-with-categories-route-parameters
I want to show entries for specific categories.
By calling this Route:
Route::get('menues/{city?}', 'PagesController#menue');
I want to show all entries for a specific city.
This is my Controller:
public function menue($city = null) {
if ($city) {
$restaurants = User::with(['articles' => function ($q){
$q->nowpublished();
}])->where('city', '=', $city)->get();
} else {
$restaurants = User::with(['articles' => function ($q){
$q->nowpublished();
}])->where('city', '!=', $city)->get();
}
return view('pages.menues')
->withRestaurants($restaurants)
->withCity($city);
}
The only thing that doesn't work is, by calling a url with a {city} that doesn't exist in the DB I want to display all entries.
With the code above this doesn't happen. I get a blank page.
How can I fix this? My guess was that the code inside my else statement displays all entries, but this isn't the case.
Do the following:
public function menue($city = null) {
$restaurants = User::with(['articles' => function ($q){
$q->nowpublished();
}]);
if(if(!is_null($city) && !is_null(City::where('name', $city)->first())) {
$restaurants->where('city', '=', $city);
}
$restaurants = $restaurants->get();
return view('pages.menues')
->withRestaurants($restaurants)
->withCity($city);
}
->where('city', '!=', $city) is the problem. If you want to get all articles, remove the condition.
Change the condition to:
if(!is_null($city) && !is_null(City::where('name', $city)->first())
Use Requests $request
public function menue(Request $request) {
if ($request->has('city')) {
I would do something like:
public function menue($city = null) {
if ($city) {
$restaurants = User::with(['articles' => function ($q){
$q->nowpublished();
}])->where('city', '=', $city)->get();
if (restaurants->count() == 0) {
$restaurants = User::with(['articles' => function ($q){
$q->nowpublished();
}])->get();
}
} else {
$restaurants = User::with(['articles' => function ($q){
$q->nowpublished();
}])->where('city', '!=', $city)->get();
}
return view('pages.menues')
->withRestaurants($restaurants)
->withCity($city);
}

searching in belongsToMany relationship in laravel 5

Actually i want to search those question which user want to search after select any subject or course.
if a remove either whereHas from subject or course its works but with both its not working.
Please give a better solution for searching in belongsToMany realtionship.
i have a question table with Question model class
class Question extends Model{
public function courses(){
return $this->belongsToMany('App\Models\Course','course_questions');
}
public function subjects(){
return $this->belongsToMany('App\Models\Subject','subject_questions');
}
}
and in my searchController
public function index(Request $request){
$questions = Question::with(['user','courses','branches','subjects','years','universities','question_type'])
->where("status","=",1)
->where(function($query) use($request){
$q = $request->q;
if(isset($q) && !is_null($q)){
$query->where("question","LIKE","%$q%");
}
})
->whereHas('subjects',function($query) use($request){
$subjects = $request->subject;
if(isset($subjects)){
$_subjects = explode(" ",$subjects);
$query->whereIn("slug",$_subjects)
->orWhereIn("subject_name",$_subjects);
}
})
->whereHas('courses',function($query) use($request){
$course = $request->course;
if(isset($course)){
$_course = explode(" ",$course);
$query->whereIn("slug",$_course)
->orWhereIn("course",$_course);
}
})
->paginate();
if($request->ajax()){
$returnHTML = view('questions.question_list')->with('questions', $questions)->render();
return response()->json(array('success' => true, 'pageContent'=>$returnHTML));
}
You should build your query probably this way - you should verify conditions before adding any constraints to your query:
$query = Question::with(['user','courses','branches','subjects','years','universities','question_type'])
->where("status","=",1);
$q = $request->q;
if(isset($q) && !is_null($q)) {
$query = $query->where("question","LIKE","%$q%");
}
$subjects = $request->subject;
if (isset($subjects)) {
$query = $query->whereHas('subjects',function($query) use($subjects){
$_subjects = explode(" ",$subjects);
$query->whereIn("slug",$_subjects)
->orWhereIn("subject_name",$_subjects);
});
}
$course = $request->course;
if (isset($course)) {
$query = $query->whereHas('courses',function($query) use($course ){
$_course = explode(" ",$course);
$query->whereIn("slug",$_course)
->orWhereIn("course",$_course);
});
}
$questions = $query->paginate();
$products = Product::query()->
WhereHas('categories', function ($q) use ($keyword) {
$q->where('products.name', $keyword)
->orWhere('categories.name', $keyword);
})->get();
This is how I have used in my project

Categories