Laravel 4 - Too much logic in my view template? - php

i created a search functionality within my Laravel project - the user can search for teamnames or usernames - the result is created and returned like this:
$teams_obj = Team::where('teamname', 'LIKE', '%'.Input::get('searchterm').'%')->get();
$persons_obj = User::where('name', 'LIKE', '%'.Input::get('searchterm').'%')->orWhere('vorname', 'LIKE', '%'.Input::get('searchterm').'%')->get();
return View::make("team.search-content", array('resp' => 'resultlist', 'teams_obj' => $teams_obj, 'persons_obj' => $persons_obj))->with('user', User::find(Auth::user()->id));
Now its getting a little more complicated. I have a database table "relation" which stores if a user is a member of a team via an entry containing user_id and team_id. Laravel knows this relation.
If the search result is displayed within the view, i have to make a distinction if the current user is already a member in the respective team which is displayed in the current row. If the user is already a member within the team he should not be able to apply, otherwise he should have the option to apply.
I solved it with this:
#foreach($teams_obj as $team_obj)
<li data-teamid="{{ $team_obj->id }}">
<span>{{ $team_obj->teamname }}</span>
<?php
$data = ['user_id' => $user->id, 'team_id' => $team_obj->id];
$res = $team_obj->whereHas('Relation', function($q) use ($data) {
$q->where('team_id', '=', $data['team_id']);
$q->where('user_id', '=', $data['user_id']);
})->get();
if (count($res) == 0) {
echo'apply fct available';
}
?>
</li>
#endforeach
I fetch the relation and check if the relation of team_id and user_id is existent. But i have a strange feeling doing this within my view template. What do you think? How can i improve this?
Additionally i think it is strange that i have to make $q->where('team_id'), as I already do $team_obj-> ... but otherwise it is not working correctly.
Any help is appreciated. Thanks!

Do you have any need to show teams that your user cannot apply ? if not you can simply modify your code to get teams that your user is not a member. If you need you can do some checkup in the controller in order to get that information.
I suggest making a foreach for the every team and checking if they have relationship with the user. You can set an attribute in a team to check in the view.
Controller:
foreach($teams_obj as $team_obj){
$res = $team_obj->whereHas('Relation', function($q) use ($data) {
$q->where('team_id', '=', $data['team_id']);
$q->where('user_id', '=', $data['user_id']);
})->get();
if(count($res) == 0)
$team_obj->isApplyableByUser = true;
else
$team_obj->isApplyableByUser = false;
// You can do the same code above in one line, but it's not that compreensive
$team_obj->isApplyableByUser = count($res) == 0;
}
View:
if($team_obj->isApplyableByUser) echo'apply fct available';

Yes, too much logic for a view (in terms of best practices)
Do you have relationships set up for these? Assuming Team hasMany('User')... Why not just eager load your User models?
$teams = Team::with(['users' => function($query){
$query->where('name', 'LIKE', '%'.Input::get('searchterm').'%')
->orWhere('vorname', 'LIKE', '%'.Input::get('searchterm').'%')
}])where('teamname', 'LIKE', '%'.Input::get('searchterm').'%')
->get();
return View::make('your.view', ['teams' => $teams]);
// And in your view.
#foreach($teams as $team)
<li data-teamid="{{ $team->id }}">
<span>{{ $team->teamname }}</span>
#if(!$team->users->count())
apply fct available
#endif
</li>
#endforeach

Related

I need to make a multiple-search on Laravel

I want to make a filter who find some things like status of a work order, employee, month (here I must separate month from the rest of date)
Ok I´m working alone on this project so I need some help.
I´ve got relations on my DB like
employee.employee_id inner join main.employee_id_created (I've made it directly on phpmyadmin)
So I want to search by name of employee but it´s on the other table so when I wanna show results it send me an error
public function()
{
if($request)
{
$query = trim($request->get('searchBy'));
}
$searchByName = MaintenanceTasks::select('Employee_Id_created')
->join('employee', 'employee.Employee_Id', '=', 'maintenance_tasks.Employee_Id_created')
->where('Employee_name','like','%'.$query.'%')
->get();
}
blade.php
#foreach($searchByName as $otList)
<td>{{$otList->getTaskId()}}</td>
#foreach($machine as $machineData)
#if($otList->Machine_Id == $machineData->Machine_Id)
#foreach($employee as $employeeData)
#if($machineData->Employee_Id == $employeeData->Employee_Id)
<td>{{$employeeData->getEmployeeName()}}</td>
#endif
#endforeach
#endif
#endforeach //and so on
I would like to make a multiple search using when, but it´s not working
you are just selecting Employee_Id_created so there is no other data than Employee_Id_created in your query result.
Add more columns to select.
create multi search
if (!empty($req1)) {
$serach= $serach->where('col', 'like', '%'.$req1.'%');
}
if (!empty($req2)) {
$serach= $serach->where('col', 'like', '%'.$req2.'%');
}
$serach= $serach->get();
other option
->where([
['col1', 'like', '%'.$req2.'%'],
['col2', 'like', '%'.$req2.'%'],
])

How to pass an array from a query inside a foreach

I have the following query that will bring all Auth user friends :
$usrusrmembs = DB::table('usrusrs')
->where('accepted', 1)
->where('user_id', $u_id)
->orwhere('friend_id', $u_id)
->pluck('friend_id', 'user_id');
Next is a foreach to loop the ids received from the above query, get the posts of all Ids, and then sending the result to a blade :
foreach($usrusrmembs as $key => $val){
$rec_users = ($key == $u_id) ? $val : $key;
$f_usrs_psts = DB::table('posts')
->where('posts.user_id', $rec_users)
->get();
}
return view('updates', ['f_posts' => $f_usrs_psts] );
The output in the blade shows only posts of one friend , while ignores the others. I feel there is a problem in the posts query, where it only sends to the blade the last processed ID. If this is the problem, then how can I solve it ?
This is where Laravel really shines. Take advantage of the relationships and do this all in one query with eager loading. I don't know what your model relations are, but something like this:
$usrusrmembs = \App\UserUserModel::where('accepted', 1)
->where('user_id', $u_id)
->orwhere('friend_id', $u_id)
->with('posts')
->get();
If you want more control, you can use a combination of closures and whereHas, but this above should get you close. Then, in your view you can loop on the posts for each:
#foreach($usrusrmembs as $usr)
echo $usr-name // etc
#foreach ($usr->posts as $post)
echo $post->whatever
#endforeach
#endforeach
This is not going to give you exactly what you need, but the idea should help you to work through it and you can skip the whole n+1 issue by removing the foreach loop in your controller.

Get datas from relation table (with()) with a condition

I have an 'implementation' table that contains relationships to retrieve projects and scores.
The scores table contains a" user_id "field.
I would like to collect all the implementations but with only the score which contains the user_id.
My original query.
public function getImplementations($id, $student)
{
$data = Implementation::where('event_id', $id)->where('student_id', $student)->with('project', 'score')->get();
return response()->json($data);
}
My test for get only the score from specific user (only one score per user per implementation, so no conflict possible)
$data = Implementation::where('event_id', $id)
->where('student_id', $student)->with('project', 'score')
->whereHas('score', function ($query) {
$query->where('user_id', Auth::user()->id);
})->get();
But that does not give the expected result. This is not the right method and I do not know the right one.
Thanks for your help
I am not sure if there's a need to eager-load and constrain a relationship simultaneously. Does the following provide you with the expected result?
$data = Implementation::where('event_id', $id)
->with([
'project',
'score' => function ($query) {
$query->where('user_id', Auth::id());
}
])
->where('student_id', $student)
->get();

Routing with parameters in laravel 5

I've got a results page for my website that outputs a list of users.
#extends('templates.default')
#section('content')
<h3>Results for "{{ Request::input('query') }}"</h3>
#if (!$users->count())
<p>No results found, sorry.</p>
#else
<div class="resultRow">
<div class="">
#foreach ($users as $user)
#include('user/partials/userblock')
#endforeach
{!! $users->appends(Request::except('page'))->render() !!}
</div>
</div>
#endif
#stop
with a fairly standard search controller:
class SearchController extends Controller {
public function getResults(Request $request) {
$query = $request->input('query');
$users = User::where(DB::raw("CONCAT(first_name, ' ', last_name)"), 'LIKE', "%{$query}%")->where('role', '=', 2)
->orWhere('username', 'LIKE', "%{$query}%")->where('role', '=', 2)
->orWhere('profile_text', 'LIKE', "%{$query}%")->where('role', '=', 2)
->orWhere('keywords', 'LIKE', "%{$query}%")->where('role', '=', 2)
->orWhere('tagline', 'LIKE', "%{$query}%")->where('role', '=', 2)
->simplePaginate(1);
return view('search.results')->with('users', $users);
}
}
Now, this works fine and well. If I search for "Jack", I get all the Jacks.
What I want to know now is, would it be possible to have a route with a predefined parameter or query string?
For example, say, on my front page I had a link to all the plumbers in my users.
<a id="plumbers" href="{{ route('search.results')->withQueryOfPlumbers }}">Plumbers</a></li>
Would this be possible? Or should I be outputting my data another way?
If you are just using GET parameters, the route() helper allows you to pass parameters as a second parameter such as: route('search.results', ['user-type, => 'plumbers'])
This will output: http://www.example.com/search/results?user-type=plumbers
You can add a column to your User called profession, then you'd do something like this:
$plumbers = User::where(['profession'=>'plumber', /*other WHERE options*/])->get();
This will return all of the users that are plumbers.
If you're hard coding the id and text of the a link, then you could just do
<a id="plumbers" href="{{ route('search.results') }}/plumbers">Plumbers</a>
And then match the keyword of plumbers in your routing table, see Laravel docs on routing parameters for more info.
Your route would look something like this:
Route::get('/search/{trade?}', ['uses' =>'SearchController#getResults', 'as' => 'search.results']);
You should be able to then inject the $trade variable into your controller. A small aside, I would avoid using raw queries in controllers as much as possible from a design and maintenance perspective and make a "search" helper function in your Eloquent model for users (See Eloquent query scopes).

Laravel 4 Multiple Search Fields

I am creating a search function in my Laravel 4 Application.
It is working great, in the fact that it is functioning well, the only thing that when I search for example in my postcode field and click search.
I want the value that I search to stay in the text input. Exactly like setting the value to be a php variable in standard PHP/HTML.
I have included my controller function and a text input field for you to see below. Any help would be greatly appreciated, thanks.
public function postSearch()
{
$search_order_from_date = Input::get('search_order_from_date');
$search_order_to_date = Input::get('search_order_to_date');
$search_order_type = Input::get('search_order_type');
$search_order_status = Input::get('search_order_status');
$search_order_agent = Input::get('search_order_agent');
$search_order_assessor = Input::get('search_order_assessor');
$search_order_postcode = Input::get('search_order_postcode');
$orders = DB::table('orders')
// ->where('order_date', '>=', $search_order_from_date, 'and', 'order_date', '<=', $search_order_to_date, 'or')
->orWhere('type', '=', $search_order_type)
->orWhere('epc_status', '=', $search_order_status)
->orWhere('agent', '=', $search_order_agent)
->orWhere('assessor', '=', $search_order_assessor)
->orWhere('postcode', '=', $search_order_postcode)
->orderBy('order_date', 'DESC')
->paginate();
Session::put('search', 'search query');
$users = User::all();
$userType = Session::get('type');
$perms = DB::table('permissions')->where('user_type', $userType)->first();
$this->layout->content = View::make('orders.index', compact('orders'), compact('perms'));
}
{{ Form::text('search_order_postcode', null, array('class'=>'form-control', 'placeholder'=>'Order Postcode')) }}
You can pass search_order_postcode to your view.
$this->layout->content = View::make('orders.index', compact('orders', 'search_order_postcode'), compact('perms'));
Add this in your index view or where ever the initial search form view is created, so you dont get an error if it does not exists.
Edit: Also pass it to your search view from you controller.
$search_order_postcode = (isset($search_order_postcode) && $search_order_postcode !== '') ? $search_order_postcode : null;
Then in your view:
// Search_order_postcode is either the value it was given or null
{{ Form::text('search_order_postcode', $search_order_postcode, array('class'=>'form-control', 'placeholder'=>'Order Postcode')) }}
Rinse repeat for other inputs, or store them in an array so you dont bloat your view::make, but this is personal preference.

Categories