Laravel 8 using group by in view/blade by foreach - php

I have this code in my controller:
public function videoGallery()
{
$videoLinksRecord = VideoLinks::all()->sortBy('video_category_id')->groupBy('video_catetgory_id');
return view('video.gallery')->with('videoLinksRecord', $videoLinksRecord);
}
which return this query:
{
"1": [
{"id":1,"video_category_id":1,"name":"Laszlo - Supernova","link":"PKfxmFU3lWY","description":"one loud banger!","home_video":null,"created_at":"2020-12-31T14:12:13.000000Z","updated_at":"2020-12-31T14:12:13.000000Z","deleted_at":null},
{"id":2,"video_category_id":1,"name":"Subtact - Restart","link":"M5A46A2txC4","description":"one loud banger!","home_video":null,"created_at":"2020-12-31T14:12:13.000000Z","updated_at":"2020-12-31T14:12:13.000000Z","deleted_at":null},
{"id":3,"video_category_id":1,"name":"Sushi Killer & Kevin Villeco - Anime Bae","link":"YHHjfYxLyuA","description":"one loud banger!","home_video":null,"created_at":"2020-12-31T14:12:13.000000Z","updated_at":"2020-12-31T14:12:13.000000Z","deleted_at":null},
{"id":4,"video_category_id":1,"name":"Hyper Potions & Subtact - Adventures","link":"TKZUhs9Gcdo","description":"one loud banger!","home_video":null,"created_at":"2020-12-31T14:12:13.000000Z","updated_at":"2020-12-31T14:12:53.000000Z","deleted_at":null}
],
"2": [
{"id":5,"video_category_id":2,"name":"Laszlo - Supernova","link":"PKfxmFU3lWY","description":"one loud banger!","home_video":null,"created_at":"2020-12-31T14:12:13.000000Z","updated_at":"2020-12-31T14:12:13.000000Z","deleted_at":null},
{"id":6,"video_category_id":2,"name":"Subtact - Restart","link":"M5A46A2txC4","description":"one loud banger!","home_video":null,"created_at":"2020-12-31T14:12:13.000000Z","updated_at":"2020-12-31T14:12:13.000000Z","deleted_at":null},
{"id":7,"video_category_id":2,"name":"Sushi Killer & Kevin Villeco - Anime Bae","link":"YHHjfYxLyuA","description":"one loud banger!","home_video":null,"created_at":"2020-12-31T14:12:13.000000Z","updated_at":"2020-12-31T14:12:13.000000Z","deleted_at":null}
]
}
I want to display the result grouped by its video category similar to this blade:
{{-- name of the category --}}
<h2 class="poppins-medium text-lg text-darkergreen text-center">Video Category Name Here</h2>
<div class="container-fluid">
<div class="row">
<div class="col-4"></div>
<div class="col-4 borderline-darkergreen-md"></div>
<div class="col-4"></div>
</div>
</div>
{{-- loop for each result sharing the same "video_category_id" --}}
<div class="container-fluid">
<div class="row d-flex justify-content-center px-0">
<div class="col col-lg-2 d-none d-lg-block d-xl-none"></div>
<div class="col col-xl-2 d-none d-xl-block"></div>
{{-- video --}}
<div class="col-12 col-md-6 col-lg-4 container-fluid d-flex justify-content-center spacer-md">
<div class="row d-flex justify-content-center">
<div class="col-12 d-flex justify-content-center container-fluid px-0">
{{-- video border --}}
<div class="video-box-border position-relative spacer-md">
<a href="">
{{-- video card image --}}
<div class="video-image position-absolute"></div>
{{-- video card background --}}
<div class="video-card"></div>
</a>
</div>
</div>
<div class="container-fluid">
<div class="row">
<div class="col-2 px-0"></div>
<div class="col-8 borderline-darkergreen-sm px-0"></div>
<div class="col-2 px-0"></div>
</div>
</div>
{{-- video name--}}
<p class="poppins-normal text-md text-gray text-center">Video Name Here
</p>
</div>
</div>
</div>
</div>
How should I use the $videoLinksRecord in a foreach logic to display it by its groupBy logic? This is my first time grouping query result so I do not know how to construct the logic for the said desired result.
Edit the code below is the relationship code in the model:
VideoLinks Model:
public function categories()
{
return $this->hasMany(VideoCategories::class);
}
VideoCategories Model:
public function links()
{
return $this->belongsTo(VideoLinks::class);
}

#foreach ($videoLinksRecords as $video_category_id => $videoLinks)
{{ $video_category_id }}
#foreach ($videoLinks as $videoLink)
{{ $videoLink->id }}
{{ $videoLink->video_category_id }}
{{ $videoLink->name }}
{{ $videoLink->link }}
{{ $videoLink->description }}
{{ $videoLink->home_video }}
{{ $videoLink->created_at }}
{{ $videoLink->updated_at }}
{{ $videoLink->deleted_at }}
#endforeach
#endforeach
Your relationship between the VideoLinks and VideoCategory models should be as follows
# VideoLinks model
public function category()
{
// 2nd parameter is optional if you follow the naming conventions
return $this->belongsTo(VideoCategory::class, 'video_category_id');
}
In your query eager load the relationship using with('category') but then group by the category's name and finally replace all() with get().
$videoLinksRecord = VideoLinks::with('category')->get()->sortBy('video_category_id')->groupBy('category.name');
#foreach ($videoLinksRecords as $category_name => $videoLinks)
{{ $category_name }}
#foreach ($videoLinks as $videoLink)
...

Related

statamic / bootstrap problem with vertical align

im newbie about statamic,
im try to solve this code :
<div class="container">
<div class="intro">
<div class="row">
<div class="col-md-12">
<h2 class="title-uppercase text-white">{{ section_three_title }}</h2>
<div class="row-project-box row">
{{ relate:section_three_categories }}
{{ entries }}
<div class="col-project-box col-sm-6 col-md-4 col-lg-3">
<a href="{{ url }}" class="project-box">
<div class="project-box-inner">
<h5>{{ title }}</h5>
</div>
</a>
</div>
{{ /entries }}
{{ /relate:section_three_categories }}
</div>
view all projects <i class="icon icon-chevron-right"></i>
</div>
</div>
</div>
</div>
the code provide this :
i want to align these box
direzionale operativo dirigenziale not in horizonatal but in vertical like this:
direzionale
operativo
dirigenziale
i think that is a bootstrap configuration but i dont know about the statamic world
anyone can help me ?
thanks a lot
The problem here seems that you are using responsive breakpoints on your columns,
so if you want to set the boxes one below the other all the times you have to set the .col-project-box always be full-width adding this class col-12 and set the .row-project-box horizontal alignment center adding this class justify-content-center to it.
<div class="container">
<div class="intro">
<div class="row">
<div class="col-md-12">
<h2 class="title-uppercase text-white">{{ section_three_title }}</h2>
<div class="row-project-box row justify-content-center">
{{ relate:section_three_categories }}
{{ entries }}
<div class="col-project-box col-12">
<a href="{{ url }}" class="project-box">
<div class="project-box-inner">
<h5>{{ title }}</h5>
</div>
</a>
</div>
{{ /entries }}
{{ /relate:section_three_categories }}
</div>
view all projects <i class="icon icon-chevron-right"></i>
</div>
</div>
</div>

Ordering by count in Laravel

In my Laravel application, I have implemented Tagging of articles and events. This is accomplished by having two tables: tags and taggables. In my tag controller, I have an index method that grabs all the tags, a count of the tags and the same logic to count used tags.
It looks like this:
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
$tags = Tag::orderByDesc('name')->get();
$tagCount = count($tags);
$usedTags = Tag::has('articles')->orHas('events')->orderBy('name')->get();
$usedTagsCount = count($usedTags);
return view('pages.tags.index', compact('tags', 'usedTags', 'tagCount', 'usedTagsCount'));
}
I pass all this data to my view which looks like this:
<div class="container">
<div class="row">
<!-- Search results -->
<div class="col-md-8">
<div class="padded-content-box">
<div class="header">
<div class="row">
<div class="col-xs-12 col-md-12">
<h1 class="heading">Tags</h1>
</div>
</div>
</div>
</div>
<div class="padded-content-box">
<div class="header">
<div class="row">
<div class="col-xs-12 col-md-12">
<h2 class="sub-heading">
All Tags ({{ $tagCount }})
</h2>
</div>
</div>
</div>
<div class="content">
<div class="tag-row">
<div class="tag-words-list">
#foreach($tags as $tag)
<a class="tag-word" title="{{ $tag->name }}" href="{{ URL::action('TagController#show', $tag->slug) }}">{{ $tag->name }}</a>
#endforeach
</div>
</div>
</div>
</div>
<div class="padded-content-box">
<div class="header">
<div class="row">
<div class="col-xs-12 col-md-12">
<h2 class="sub-heading">
Tags currently in use ({{ $usedTagsCount }})
</h2>
</div>
</div>
</div>
<div class="content">
#foreach($usedTags as $tag)
<p>
<a class="tag-word" title="{{ $tag->name }}" href="{{ URL::action('TagController#show', $tag->slug) }}">{{ $tag->name }}</a>
x {{ count($tag->articles) + count($tag->events) }}
</p>
#endforeach
</div>
</div>
</div>
<div class="col-md-4"></div>
</div>
</div>
As you can see, to show a count of tags used I just add the articles and events that have a given tag.
How would I count how many times each tag is used in both events and articles, then order them by the count. Essentially if a tag has been used the most it would be at the top of a list.
Update
As suggested I have changed my controller method to look like this:
public function index()
{
$tags = Tag::orderBy('name')->get();
$tagCount = count($tags);
$usedTags = Tag::has('articles')->orHas('events')->withCount('articles', 'events')->orderByRaw('articles_count + events_count DESC')->orderBy('name')->get();
$usedTagsCount = count($usedTags);
return view('pages.tags.index', compact('tags', 'usedTags', 'tagCount', 'usedTagsCount'));
}
This ensures that the tags are in count and alphabetical order.
Then in my view I changed the count code to this:
<p>
<a class="tag-word" title="{{ $tag->name }}" href="{{ URL::action('TagController#show', $tag->slug) }}">{{ $tag->name }}</a> x {{ $tag->articles_count + $tag->events_count }}
</p>
This way I get to remove some minor logic from the view.
Use withCount():
$tags = Tag::withCount('articles', 'events')
->orderByRaw('articles_count + events_count DESC')
->get();

How to link comments to each post by id with Laravel Blade

I have created a Post and Comment application. I am trying to link the comments to the id of the post. I am trying to use PHP in a Blade template to do this. I get the error that the variable post_id does not exist. I want to use the #if and #foreach of Blade. The problem seems to be in the #if statement.
Here is my HTML:
<div class="col-md-9">
<div class="row">
#foreach($posts as $post)
<div class="col-md-12 post" id="post{{ $post->id }}">
<div class="row">
<div class="col-md-12">
<h4>
{{ $post->title }}
</h4>
</div>
</div>
<div class="row">
<div class="col-md-12 post-header-line">
<span class="glyphicon glyphicon-user"></span> by {{ $post->user->firstName }} {{ $post->user->lastName }} | <span class="glyphicon glyphicon-calendar">
</span> {{ $post->created_at }} | <span class="glyphicon glyphicon-comment"></span><a href="#">
3 Comments</a>
</div>
</div>
<div class="row post-content">
<div class="col-md-2">
<a href="#">
<img src="/images/random/postimg.jpg" alt="" class="img-responsive postImg">
</a>
</div>
<div class="col-md-10">
<p>
{{ $post->post }}
</p>
</div>
</div>
<div class="row add-comment">
<div class="form-group">
<input type="text" name="addComment" placeholder="Add your comment" class="form-control" v-model="comment">
</div>
<input id="addComment" type="submit" name="submitComment" value="Submit Comment" class="btn btn-default" v-on:click="submitComment" data-id="{{ $post->id }}">
</div>
#if($post->comment->post_id == $post->id)
#foreach($post->comment as $comment)
<div class="row">
<div class="col-md-12 mb-r">
<div class="card example-1 scrollbar-ripe-malinka">
<div class="card-body">
<h4 id="section1"><strong>By: {{ $comment->user->firstName }} {{ $comment->user->lastName }}</strong></h4>
<p>{{ $comment->comment }}</p>
</div>
</div>
</div>
</div>
#endforeach
#endif
</div>
#endforeach
</div>
</div>
Here is my PostController:
public function index(){
$posts = Post::with('comment', 'user')->orderBy('id', 'desc')->limit(20)->get();
return view('post.posts')->with('posts', $posts);
}
You don't need #if statement, remove it. $post->comment is a collection, that 's why your are not getting post_id. if you want to check, then check inside foreach.
#foreach($post->comment as $comment)
<div class="row">
<div class="col-md-12 mb-r">
<div class="card example-1 scrollbar-ripe-malinka">
<div class="card-body">
<h4 id="section1"><strong>By: {{ $comment->user->firstName }} {{ $comment->user->lastName }}</strong></h4>
<p>{{ $comment->comment }}</p>
</div>
</div>
</div>
</div>
#endforeach
You need to add post_id to the comments table and use the relationship:
public function comments()
{
return $this->hasMany(Comment::class);
}
Then you'll be able to load related comments:
Post::with('comments', ....
And iterate over posts and their comments:
#foreach ($posts as $post)
#foreach ($post->comments as $comment)
{{ $comment->content }}
#endforeach
#endforeach
I think if you create relationship between Post model and Comment model (post table and comments table), your #if is useless. I recommend you to check your corresponding models.
Your code should be like this,
Post.php
public function comments(){
return $this->morphMany('App\Comments','commentable');
}
Comment.php
public function commentable(){
return $this->morphTo();
}
in my app Comment model is shared by some other models also.
Eg :- User’s Questions also have comments.
Find more details in laravel:Eloquent page

Laravel 5.2 Undefined variable theme

I'm making a forum and the if the user clicks on a theme, he gets redirected to the page where all the topics are that belong to that theme. What I'm trying to do, is that the user is able to click on the topic and gets redirected to it.
The problem is, is that I get an error saying Undefined variable: theme
As you can see in the code below, I have a foreach loop in my theme.blade.php which loops all the topics that belong to the theme he/she clicked on. In the beginning of the loop there is a <a href="{{ route('showtopic', ['theme_id' => $theme->id, 'topic_id' => $topic->id]) }}"1 which is supposed to bring the user to the topic that he/she clicked on. The URL that is supposed to show is forum.dev/theme/{theme_id}/topics/{topic_id} But that doesn't work.
And it gives me that error code. All the code is below, If i miss some code, Please inform me about it and i'll update the question. Thanks in advance
theme.blade.php
<div class="col s12">
<div class="card">
<div class="card-content"><span class="card-title"> - Topics</span>
<div class="collection">
#foreach($topics as $topic)
<a href="{{ route('showtopic', ['theme_id' => $theme->id, 'topic_id' => $topic->id]) }}" class="collection-item avatar collection-link"><img src="/uploads/avatars/{{ $topic->user->avatar }}" alt="" class="circle">
<div class="row">
<div class="col s6">
<div class="row last-row">
<div class="col s12"><span class="title">Theme - {{ $topic->topic_title }}</span>
<p>{!! str_limit($topic->topic_text, $limit = 125, $end = '...') !!}</p>
</div>
</div>
<div class="row last-row">
<div class="col s12 post-timestamp">Posted by: {{ $topic->user->username }} op: {{ $topic->created_at }}</div>
</div>
</div>
<div class="col s2">
<h6 class="title center-align">Replies</h6>
<p class="center replies">{{ $topic->replies->count() }}</p>
</div>
<div class="col s2">
<h6 class="title center-align">Status</h6>
<div class="status-wrapper center-align"><span class="status-badge status-open">open</span></div>
</div>
<div class="col s2">
<h6 class="title center-align">Last reply</h6>
<p class="center-align"></p>
<p class="center-align">Tijd</p>
</div>
</div>
</a>
#endforeach
</div>
</div>
</div>
</div>
Web.php
Route::get('/', 'ThemesController#index')->name('home');
Route::get('/theme/{theme_id}/topics', 'ThemesController#show')->name('showtheme');
Route::get('/theme/{theme_id}/topics/{topic_id}', 'TopicsController#topic')->name('showtopic');
Route::group(['middleware' => 'App\Http\Middleware\AdminMiddleware'], function() {
//THEMES
Route::get('/theme/{theme_id}/edit', 'ThemesController#edit')->name('edittheme');
Route::patch('/theme/{theme_id}/edit', 'ThemesController#update')->name('updatetheme');
Route::get('/theme/create', 'ThemesController#create')->name('createtheme');
Route::post('/theme/create', 'ThemesController#save')->name('savetheme');
Route::delete('/theme/{theme_id}/delete', 'ThemesController#destroy')->name('deletetheme');
//TOPICS
Route::get('/theme/{theme_id}/topics/{topic_id}/edit', 'TopicsController#edit')->name('edittopic');
Route::patch('/theme/{theme_id}/topics/{topic_id}/edit', 'TopicsController#update')->name('updatetopic');
Route::get('/theme/{theme_id}/topics/create', 'TopicsController#create')->name('createtopic');
Route::post('/theme/{theme_id}/topics/create', 'TopicsController#save')->name('savetopic');
Route::delete('/theme/{theme_id}/topics/{topic_id}/delete', 'TopicsController#destroy')->name('deletetopic');
});
Route::get('user/profile', 'UserController#profile')->name('showprofile');
Route::post('user/profile', 'UserController#update_avatar');
TopicsController.php (Show method)
public function show($id)
{
$theme = Theme::find($id);
$topics = Topic::find($id);
return view('topics/topic')->with('topics', $topics)->with('theme', $theme);
}
I don't know if you can use the double '->with' option.
What will work is the following:
return view('topics/topic', ['topics' => $topics, 'theme'=> $theme]);
You pass an array as the second argument of the view. You can add as many keys and variables as you like.

Laravel foreach database issue

I am making a forum and when the user clicks on a theme, a page shows up with every topic that belongs to that theme. The problem is, how do I do this?
I made a for each loop which shows ALL the topics from the database instead of the topics that belong to that theme I clicked on. How can I do this?
Web.php
Route::get('/', 'ThemesController#index')->name('home');
Route::get('/theme/{id}', 'ThemesController#show')->name('showtheme');
ThemesController.php
I only show the show method because I believe that's the only one necessary here
public function show($id)
{
$topics = Topic::all($);
return view('themes/topics')->with('topics', $topics);
}
topics.blade.php
#extends('layouts.default')
#section('content')
<div class="container main-content">
<div class="row first-row">
<div class="col s12">
<div class="card">
<div class="card-content clearfix">Nieuw topic</div>
</div>
</div>
<div class="col s12">
<div class="card">
<div class="card-content"><span class="card-title"> - Topics</span>
<div class="collection">
#foreach($topics as $topic)
<a href="" class="collection-item avatar collection-link"><img src="/uploads/avatars/{{ $topic->user->avatar }}" alt="" class="circle">
<div class="row">
<div class="col s6">
<div class="row last-row">
<div class="col s12"><span class="title">Theme - {{ $topic->topic_title }}</span>
<p>{!! str_limit($topic->topic_text, $limit = 100, $end = '...') !!}</p>
</div>
</div>
<div class="row last-row">
<div class="col s12 post-timestamp">Gepost door: {{ $topic->user->username }} op: {{ $topic->created_at }}</div>
</div>
</div>
<div class="col s2">
<h6 class="title center-align">Replies</h6>
<p class="center replies">{{ $topic->replies->count() }}</p>
</div>
<div class="col s2">
<h6 class="title center-align">Status</h6>
<div class="status-wrapper center-align"><span class="status-badge status-open">open</span></div>
</div>
<div class="col s2">
<h6 class="title center-align">Laatste reply</h6>
<p class="center-align">Naam</p>
<p class="center-align">Tijd</p>
</div>
</div>
</a>
#endforeach
</div>
</div>
</div>
</div>
<div class="col s12">
<div class="card">
<div class="card-content clearfix">Nieuw topic</div>
</div>
</div>
</div>
</div>
#endsection
I believe I'm doing something obviously wrong but I can't see what.
Help will be appreciated. Thanks in advance
If I miss some code, Please inform me.
How are you defining the relationship between a theme and it's topics? You'll have to have something like a one to many or many to many established in your database for you to be able to query correctly. Do you have anything like that yet?
****edit****
public function show($id)
{
$topics = Theme::find($id)->topics;
return view('themes/topics')->with('topics', $topics);
}

Categories