PHP MVC LARAVEL - php

how can I show a array in the view?
Controller:
$users = DB::table('users')
->join('links', 'links.UserId', '=', 'users.UserId')
->select('users.*', 'links.*')
->get();
return view('site.user', ['UserId' => $users]);
I want to do foreach in LINKS, but not in users...
VIEW (users) (WITHOUT foreach):
<h1><?=$user->UserName . ' ' . $user->UserLastName?></h1>
LINKS (foreach):
<li class="white-balloon">
<?=$user->LinkName?>
</li>

First
return view('site.user', ['UserId' => $users]);
should be
return view('site.user', ['users' => $users]);
unless you want to use the variable UserId.
To loop over a variable in blade, use:
#foreach ($users as $user)
<p>This is a link {{ $user->LinkName }}</p>
#endforeach
or in PHP
<?PHP foreach( $users AS $user)
{
echo $user->LinkName;
} ?>
Note: if you have multiple links per user, you should redefine your SQL query. This method gives allot of overhead.
Here a good tutorial about Laravel relationships

Related

Laravel 5.4: Avoid html in the Controllers and DB queries in the blade

I have a problem I can not solve. I have a foreach that prints me an HTML every time it finds value in the database, and it all works.
However, I would like to avoid putting html in the controller.php file.
At the moment I did:
$html_console='';
if($article->id_game > '0'){
$prel_console = \DB::table('info_game')
->where('id_game', '=', $article->id_game)
->get();
foreach($prel_console as $name_console)
{
$name_console_game = \DB::table('console')
->where('id', '=', $name_console->id_console)
->first();
$html_console.='<span class="label">'. $name_console_game->abb_cat.'</span>' ;
}
}
While in the blade:
{!! $html_console !!}
I tried to do this in the blade:
#foreach ($prel_console as $name_console)
<span class="label margin-top-5 font-size-10">{{ $name_console_game->abb_cat }}</span>
#endforeach
If I put the foreach in the blade, how do I deal with the query "name_console_game"
If you have a one to many relation between info_game table which should have a InfoGame model and console table with Console model then your could do something like this:
controller:
public function someMethod()
{
// assuming that you already have an $article object
$infoGame = InfoGame::where('id_game', $article->id_game)->get();
return view('some.view', compact('infoGame'));
}
view location views/some/view/blade.php
#foreach($infoGame->console as $name_console_game)
<span>{{ $name_console_game->abb_cat }}</span>
#endforeach

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).

Search query lost on pagination in laravel

I'm quite new to laravel and backend stuff altogether so this might be a newb question!
My website has a search engine which is used to look up users.
Right now I'm using a pretty simple search controller, below is the code.
class SearchController extends Controller {
public function getResults(Request $request) {
$query = $request->input('query');
if (!$query) {
return redirect()->route('home');
}
$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)
->simplePaginate(1);
return view('search.results')->with('users', $users);
}
}
And the results page:
#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)
{{ $user->username }}
#endforeach
{!! $users->render() !!}
</div>
</div>
#endif
#stop
So if I were to search "John", I'd get the result of all the Johns, with the URL being http://localhost/search?query=John .
However, if I were to click on the next page of results (http://localhost/search?page=2), the query is lost, so my search controller just sends me back to my home page.
How do I keep the query through pagination?
EDIT: I'm pretty sure my problem is that it's going through the search controller once again after it click on page 2, but I have no idea how I would fix that.
Switched
{!! $users->render() !!}
with
{!! $users->appends(Request::except('page'))->render() !!}
Works like a charm. Credit goes to : Laravel 5 route pagination url encoding issue (unrelated issue)
in your getResult function, pass a $query variable to the view
return view('search.results', ['users' => $users, 'query' => $query]);
Then in your view, appends the query or other variables you need
{{ $users->appends(['query' => $query])->links() }}
you can check more in laravel docs
You can use paginate the following way.
$users->withQueryString()->links()

Laravel Count with where inside blade

I'm trying to get the total comments the user have..
Controller:
public function index()
{
$setting = Setting::findOrFail(1);
$comments = Comment::where('published', '=', '1')->get();
$users = User::all();
return view('page.index', compact('setting', 'comments', 'users'));
}
View:
#foreach($comments as $comment)
{{ count($users->where('user_id', '=', $comment->user_id)) }}
#endforeach
The problem is that it only returns 0 and i have 2 comments there.. even using the user id to instead of "$comment->user_id" it doesnt work. still display 0.
$users is a collection, not a query. Treat it as such:
#foreach ($comments as $comment)
{{ $users->where('user_id', $comment->user_id)->count() }}
#endforeach
The collection's where method does not take an operator.
From the wording in your question it seems you actually want it the other way around:
$comments = Comment::wherePublished(1)->get()->groupBy('user_id');
Then in your view:
#foreach ($users as $user)
{{ $comments->has($user->id) ? count($comments[$user->id]) : 0 }}
#endforeach
I'm late to answer your question and Joseph already showed you the problem but you may also do it differently. You can group comments using Collection::groupBy, for example:
$comments = Comment::all()->groupBy('user_id');
Then in your view you may try this:
#foreach($comments as $user => $userComments)
// count($userComments)
// Or
#foreach($userComments as $comment)
// {{ $comment->title }}
#endforeach
#endforeach
In the first loop (#foreach($comments as $user => $userComments)), the $user is the user_id and it's value would be all comments (an array) by this user but in group.

Laravel 4 - Too much logic in my view template?

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

Categories