I have 2 lines of code here but i want to combine all 2 lines into 1
// How to combine these 2 lines here
$product = $this->productService->searchProduct($request);
$product = Product::paginate(9);
Controller:
public function searchProduct(SearchProductRequest $request)
{
$search = $request->search;
$min_price = $request->min_price;
$max_price = $request->max_price;
$product = Product::query('products')
->where('name', 'like', "%{$search}%")
->where('price', [$min_price])
->orWhere('price',[$max_price])
->orderBy('id');
return $product;
}
you can try :
$product = $this->productService->searchProduct($request)->paginate(9);
take a look at your view blade, have you added links();
like this
<div class="float-left mr-3 mb-1">
{{ $product->links() }}
</div>
$product = !empty($this->productService->searchProduct($request)?Product::paginate(9):'';
Try this
public function searchProduct(SearchProductRequest $request)
{
$products = Product::select('id', 'name', 'price')
->when($request->input('search'), function($q){
$q->where('name', 'like', '%' . request()->input('search') . '%');
})
->when($request->input('min_price'), function($q){
$q->where('price', request()->input('min_price'));
})
->when($request->input('max_price'), function($q){
$q->orWhere('price', request()->input('max_price'));
})
->orderBy('id')
->paginate(9);
return $products;
}
Related
We've made a search system on our website, with a brands table being made. There are some brands that have spaces in their names and some that don't.
We have for example
"Turtle Wax"
What I'd like to do, is when a user searches for say Turtlewax my search looks for both versions...
Turtle Wax
TurtleWax
Is this even possible?
My current code is as follows...
$products = Product::select('product.*')
->join('brand', 'product.brand_id', '=', 'brand.id')
->join('child_product', 'product.id', '=', 'child_product.product_id')
->leftJoin('tax_rates', 'tax_rates.id', '=', 'child_product.tax_rate_id')
->with('brand', 'categories', 'childProducts', 'childProducts.attributeValues', 'images')
->where('product.active', true)
->where('brand.active', true)
->where(function ($query) use ($search_term)
{
$query->whereLike('product.name', $search_term)
->orWhereLike('product.description', $search_term)
->orWhere('brand.slug', str_slug($search_term, ''))
->orWhereLike('brand.slug', str_slug($search_term, '-'))
->orWhereLike('brand.name', str_replace(' ', '', $search_term))
->orWhere('brand.name', 'LIKE', '%'. $search_term);
})->get();
I have made 2 query scopes for the WhereLike and orWhereLike
public function scopeWhereLike($query, $column, $value)
{
return $query->where($column, 'like', '%'.$value.'%');
}
public function scopeOrWhereLike($query, $column, $value)
{
return $query->orWhere($column, 'like', '%'.$value.'%');
}
If they're using PascalCase ("TurtleWax"), you can do the following:
public function scopeWhereLike($query, $column, $value)
{
return $query
->where($column, 'like', '%'.implode(' ', preg_split('/(?=[A-Z])/', $value)).'%') // "word/space case"
->orWhere($column, 'like', '%'.ucwords(strtolower($value)).'%') // Titlecase
->orWhere($column, 'like', '%'.$value.'%'); // PascalCase
->orWhere("REPLACE(".$column.", ' ', '')", 'like', '%'.$value.'%'); // fallback
}
Im trying to figure out why my query is ignoring everything except the title and the description. The search button leading to the controller, is for filtering different type of ads , by category, by region, by price.
For example if now i search for existing ad and its found by title / keyword -> will always show, even if i choose a different region / category/ price range
Im trying to use something that will save me a lot of if statements to check if they exist in the request. Maybe other option si to use https://github.com/mohammad-fouladgar/eloquent-builder to build my query
public function index(Request $request)
{
$keyword = $request['keyword'];
$category_id = $request['category_id'];
$type_id = $request['type_id'];
$region_id = $request['region_id'];
$min_price = $request['min_price'];
$max_price = $request['max_price'];
$result = Ad::when($keyword, function ($q) use ($keyword) {
return $q->where('title', 'like', '%' . $keyword . '%')->orWhere('description', 'like', '%' . $keyword . '%');
})
->when($category_id, function ($q) use ($category_id) {
return $q->where('category_id', $category_id);
})
->when($region_id, function ($q) use ($region_id) {
return $q->where('region_id', '=', $region_id);
})
->when($type_id, function ($q) use ($type_id) {
return $q->where('adtype_id', '=', $type_id);
})
->when($min_price, function ($q) use ($min_price) {
return $q->where('price', '>=', $min_price);
})
->when($max_price, function ($q) use ($max_price) {
return $q->where('price', '<=', $max_price);
})
->paginate(8);
My get param url looks like that:
search?keyword=&category_id=0®ion_id=0&type_id=0&min_price=&max_price=
The produced query in mysql when i search for existing ad by its name and i look for a different category is:
select * from `ads` where `title` like '%test test%' or `description` like '%test test%' and `category_id` = '2' limit 8 offset 0
The ad is found, but the actual category is 1, not 2, same for all others optimal parameters.
You can edit your query to look for specific relations, using whereHas. This method will allow you to add customized constraints to a relationship constraint, such as checking the content of a comment.And to check max/min price, use where method. So, you can use it like this:
$result = Ad::when($keyword, function ($q) use ($keyword) {
return $q->where('title', 'like', '%' . $keyword . '%')->orWhere('description', 'like', '%' . $keyword . '%');
})
->whereHas('category_relation_name', function ($q) use ($category_id) {
return $q->where('category_id', $category_id);
})
->whereHas('region_relation_name', function ($q) use ($region_id) {
return $q->where('region_id', $region_id);
})
->whereHas('type_relation_name', function ($q) use ($type_id) {
return $q->where('adtype_id', $type_id);
})
->where('price', '>=', $min_price);
->where('price', '<=', $max_price);
->paginate(8);
My code here is working fine but I need it to be short. I'm using if statement so Select if I will use user_id or Guest_ip.
But I get a long code, any help?
if (Auth::guest()) {
$Task = Enrollee::with('path.ProgrammingField')->with(['path.pathtags' => function ($q) use ($TagArray)
{
$q->with(['Tasks' => function ($q) use ($TagArray)
{$q->has('tasktags', '=', 2)->orderBy('id', 'ASC') ->whereDoesntHave('tasktags',
function ($query) use ($TagArray) {
$query->whereNotIn('name', $TagArray);
}
)
->with('tasktags');
}]
)->orderBy('id', 'ASC');
}])
->where( 'user_id' , '=' , Auth::user()->id )
->where('Path_id', $Path->id) ->get();
$Tasks = $Task[0]->path;
$Subs = Enrollee::where( 'user_id' , '=' , Auth::user()->id )->where('Path_id', $Path->id)->get();
$AllSubs = [];
foreach($Subs as $sub){
$AllSubs[] = $sub->task_id;
}
$AllSubTasks = implode(" ",$AllSubs);
$SubTasks = explode(",", ($AllSubTasks));
}
else {
$Task = Enrollee::
with('path.ProgrammingField')
->with(['path.pathtags' => function ($q) use ($TagArray)
{
$q->with(['Tasks' => function ($q) use ($TagArray)
{$q->has('tasktags', '=', 2)->orderBy('id', 'ASC')
->whereDoesntHave('tasktags',
function ($query) use ($TagArray) {
$query->whereNotIn('name', $TagArray);
}
)
->with('tasktags');
}]
)->orderBy('id', 'ASC');
}])
->where( 'guest_ip' , '=' , '127.0.0.1' )
->where('Path_id', $Path->id) ->get();
$Tasks = $Task[0]->path;
$Subs = Enrollee::where( 'guest_ip' , '=' ,'127.0.0.1') ->where('Path_id', $Path->id)->get();
$AllSubs = [];
foreach($Subs as $sub){
$AllSubs[] = $sub->task_id;
}
$AllSubTasks = implode(" ",$AllSubs);
$SubTasks = explode(",", ($AllSubTasks));
}
Can I Use
if (Auth::guest()) {
->where( 'guest_ip' , '=' , '127.0.0.1' )
}
I need to be one code and change if I use guest_ip or user id Using if statement
Hope this will help you.
$ObjTask = Enrollee::with('path.ProgrammingField')
->with(['path.pathtags' => function ($q) use ($TagArray) {
$q->with(['Tasks' => function ($q) use ($TagArray) {
$q->has('tasktags', '=', 2)->orderBy('id', 'ASC')
->whereDoesntHave('tasktags', function ($query) use ($TagArray) {
$query->whereNotIn('name', $TagArray);
}
)
->with('tasktags');
}]
)->orderBy('id', 'ASC');
}])
->where('Path_id', $Path->id);
$Subs = null;
if (Auth::guest()) {
$Task = $ObjTask->where('user_id', '=', Auth::user()->id)->get();
$Subs = Enrollee::where('user_id', '=', Auth::user()->id)->where('Path_id', $Path->id)->get();
}
else {
$Task = $ObjTask->where('guest_ip', '=', '127.0.0.1')->get();
$Subs = Enrollee::where('guest_ip', '=', '127.0.0.1')->where('Path_id', $Path->id)->get();
}
$Tasks = $Task[0]->path ?? null;
$AllSubs = [];
$AllSubTasks = $SubTasks = null;
if (!empty($Subs)) {
foreach ($Subs as $sub) {
$AllSubs[] = $sub->task_id;
}
$AllSubTasks = implode(" ", $AllSubs);
$SubTasks = explode(",", ($AllSubTasks));
}
After properly indenting the code (like #castis correctly advised) , you can start extracting the bits within the statements into methods. That's called refactoring.
From wikipedia:
Code refactoring is the process of restructuring existing computer code—changing the factoring—without changing its external behavior.
It will look something like this:
if(true) {
doWhateverNeedsToBeDone();
} else {
doTheOtherThing();
}
And you copy all code and paste into the body of these new methods.
I want to make a filter with different parameters. One of parameter is $article_title. But it can be empty . My problem is even if its not empty i get null in return $comments. That is because this part of code:
$q->where('language_id', $default_language_id)->where('title','like',$article_title);
This is my function
public function getResultCommentsWithArticle($comment,$user_firstname,$article_title,$orderBy){
$default_language = Languages::where('default',1)->first();
$default_language_id = $default_language->id;
$comments = ArticleComments::orderBy($orderBy,'desc')
->with(['user', 'article', 'article.translations' => function($q) use($default_language_id,$article_title) {
$q->where('language_id', $default_language_id)->where('title','like',$article_title);
}])->paginate(10);
return $comments;
}
EDIT:
I also tried like this:
$comments = ArticleComments::orderBy($orderBy,'desc')
->with(['user', 'article', 'article.translations' => function($q) use($default_language_id,$article_title) {
$q->where([
['language_id', '=', $default_language_id],
['title', 'like', '%'. $article_title .'%'],
]);
}])->paginate(10);
But i get all comments and not comments with title="something"
$comments = ArticleComments::orderBy($orderBy,'desc')
->with(['user', 'article'])
->whereHas('article.translations', function($q)
use($default_language_id,$article_title) {
$q->where('language_id', $default_language_id)
->where('title','like',$article_title);
})->paginate(10);
Try this:
$comments = ArticleComments::orderBy($orderBy, 'desc')
->with(['user', 'article' => function ($q) use($default_language_id, $article_title) {
$q->with('translations')
->whereHas('translations', function ($q) use($default_language_id, $article_title) {
$q->where('language_id', $default_language_id)->where('title','like',$article_title);
});
}])->paginate();
This will select all comments and it will attach to it articles that match the translation.title and default language id.
In case you want to filter the comments instead of articles you would do this:
$comments = ArticleComments::orderBy($orderBy, 'desc')
->with(['user', 'article.translation'])
->whereHas('article', function ($q) use($default_language_id, $article_title) {
$q->whereHas('translations', function ($q) use($default_language_id, $article_title) {
$q->where('language_id', $default_language_id)->where('title','like',$article_title);
});
})->paginate();
return $comments;
All I want is to have an if statement that exceeds number of absences and show the message.
Here's the SQL query
public function countAbsent()
{
$absent = Attendances::select(DB::raw('count(status)'))
->where('student_id', '=', Auth::user()->id)
->where('status', '=', 'absent')
->where('section_name', 'like', Input::get('section_name'))
->where('subject_code', 'like', Input::get('subject_code'))
->count();
return View::make('student.view_absent')
->with('absent', $absent);
}
You can pass another variable to view:
public function countAbsent()
{
$absent = Attendances::select(DB::raw('count(status)'))
->where('student_id', '=', Auth::user()->id)
->where('status', '=', 'absent')
->where('section_name', 'like', Input::get('section_name'))
->where('subject_code', 'like', Input::get('subject_code'))
->count();
$absent_message = 'Students are not exceeding the absence threshold';
$threshold = 10; //whatever you like
if ($absent > $threshold)
{
$absent_message = 'Students are exceeding the absence threshold';
}
return View::make('student.view_absent')
->with('absent', $absent)
->with('absent_message', $absent_message);
}
And echo the $absent_message in the View student.view_absent.