Laravel 5.1 Order by multiple times - php

I'm trying to make something 'like facebook'...
Now, I want to order the posts using the created_at table. But also, if the post has a comment, order it by the comments. So actually, the posts need to be ordered by the comment and if the post doesn't have a comment, then it needs to order by the post (acting as a fallback).
To make it all clear, I have made some screenshots:
So this is just one post, nothing to mention about it.
But when I add a second post with 456 as content, that post needs to be on top, wich works:
All good, but now, when I add a comment, the message with the comment needs to be on top (since it has a newer post). This is my problem, it doesn't work:
So here is my code:
Controller:
public function index()
{
$getallposts = DB::table('social_posts')->select('users.*', 'social_posts.created_at as PostAt', 'social_posts.description', 'users_images.*', 'social_posts.id as PostID')
->join('users', 'social_posts.user_id', '=', 'users.id')
->join('users_images', 'social_posts.user_id', '=', 'users_images.user_id')
->orderBy('social_posts.created_at', 'DESC')
->whereNull('social_posts.deleted_at')
->get();
//var_dump($getallposts);
$getallcomments = DB::table('social_comments')->select('users.*', 'social_comments.created_at as PostAt', 'social_comments.description', 'social_comments.post_id', 'users_images.*')
->join('users', 'social_comments.user_id', '=', 'users.id')
->join('users_images', 'social_comments.user_id', '=', 'users_images.user_id')
->orderBy('social_comments.created_at', 'ASC')
->whereNull('social_comments.deleted_at')
->get();
//var_dump($getallposts);
$getrandomusers = DB::table('users')->select('users.*', 'users.id as UID', 'users_images.*')
->join('users_images', 'users.id', '=', 'users_images.user_id')
->orderByRaw('RAND()')
->where('users.id', '!=', Auth::id())
->take(16)
->get();
return view('dashboard', ['posts' => $getallposts, 'comments' => $getallcomments, 'randomuser' => $getrandomusers]);
}
View:
#foreach($posts as $post)
<div class="row row-sm">
<div class="col-sm-12">
<div class="card">
<div class="card-heading">
<a href class="pull-left w-32 m-r" href="{!! url(Auth::user()->slug) !!}">
<img src="{!! asset('avatars/'.$post->image) !!}" class="w-full img-circle">
</a>
<div class="clear">
{!! ucwords($post->firstname) !!} {!! ucwords($post->lastname) !!}
<div class="text-xxs font-thin text-muted">{!! \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', $post->PostAt)->diffForHumans() !!}</div>
</div>
</div>
<div class="card-body">
<p>
{!! nl2br(e($post->description)) !!}
</p>
<p style="color:grey;font-size:10px;">Aantal likes - {!! \Cussion\SocialReaction::where('post_id', $post->PostID)->count() !!} {!! (\Cussion\SocialReaction::where('post_id', $post->PostID)->count() == 1) ? 'reactie' : 'reacties' !!} </p>
<p style="font-size:14px;">Leuk vinden</p> <!-- KNOP OM STATUS TE LIKEN -->
</div>
<div class="list-group no-radius no-border" style="background-color:#F5F5F5;">
#foreach($comments as $comment)
#if($comment->post_id == $post->PostID)
<div class="md-list-item">
<div class="md-list-item-left">
<img src="{!! asset('avatars/'.$comment->image) !!}" class="w-full circle">
</div>
<div class="md-list-item-content">
<small class="font-thin">{!! ucwords($comment->firstname) !!} {!! ucwords($comment->lastname) !!}</small>
<div class="text-xxs font-thin text-muted" style="font-size:12px;">{!! nl2br(e($comment->description)) !!}</div>
<div class="text-xxs font-thin text-muted" style="font-size:10px;">{!! \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', $comment->PostAt)->diffForHumans() !!}</div>
</div>
</div>
#endif
#endforeach
<div class="md-list-item">
<form action="{!! url('/dashboard') !!}" method="post" role="form">
{!! csrf_field() !!}
<div class="input-group">
<input type="text" class="form-control" name="message" placeholder="Wat wil je reageren?">
<input type="hidden" name="post_id" value="{!! $post->PostID !!}">
<span class="input-group-btn">
<button class="btn btn-default" type="submit">Reageer</button>
</span>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
#endforeach
And my database structure:
Demo can be found on http://cussion.org

You can easily use the concept of "touching parent timestamps", read more about it here https://laravel.com/docs/5.1/eloquent-relationships#touching-parent-timestamps
But here is a simple explanation, since the comments are related to posts, you can instruct the comments model to update the updated_at field of the parent post whenever a comment is added or even edited, so now you have the post's updated_at always up-to-date.

I would defer the sorting to your PHP script. Writing that kind of sorting algorithm in MySQL could get very complicated and hard to read. Instead, I would store the results in a collection and then sort using a custom function. Something like this:
$getallposts = DB::table('social_posts')
->select('users.*', 'social_posts.created_at as PostAt', 'social_posts.description', 'users_images.*', 'social_posts.id as PostID')
->join('users', 'social_posts.user_id', '=', 'users.id')
->join('users_images', 'social_posts.user_id', '=', 'users_images.user_id')
->whereNull('social_posts.deleted_at')
->get();
$getallcomments = DB::table('social_comments')
->select('users.*', 'social_comments.created_at as PostAt', 'social_comments.description', 'social_comments.post_id', 'users_images.*')
->join('users', 'social_comments.user_id', '=', 'users.id')
->join('users_images', 'social_comments.user_id', '=', 'users_images.user_id')
->orderBy('social_comments.created_at', 'ASC')
->whereNull('social_comments.deleted_at')
->get();
//add comments to their posts and put post
foreach($getallposts as $post){
$post->comments = [];
foreach($getallcomments as $comment){
if($comment->post_id == $post->PostID){
$post->comments[] = $comment;
}
}
}
$getallposts->sortBy(function($item, $key){
//run your sorting logic here based on comments and created_at date
});
Even better yet, convert your sql queries to Eloquent objects and this gets MUCH MUCH easier.

Related

How to get a specific value from a table in a view when you have conflicting names[Laravel]

Im making an application for a non-profit organisation for a school project and we are using laravel, the first time for me
I tried {{$instructiekaart->instructiekaarten.name}} but I get an error message when using this code
Controller
$instructiekaarten = DB::table('instructiekaarten')
->join('instructiekaart_set', 'instructiekaart_set.instructiekaart_id' ,'=', 'instructiekaarten.id')
->join('sets', 'sets.id' ,'=', 'instructiekaart_set.set_id')
->join('instructiekaart_stap', 'instructiekaart_stap.instructiekaart_id' ,'=', 'instructiekaarten.id')
->join('stappen', 'stappen.id' ,'=', 'instructiekaart_stap.stap_id')
->join('instructiekaart_user', 'instructiekaart_user.instructiekaart_id' ,'=', 'instructiekaarten.id')
->join('users', 'users.id' ,'=', 'instructiekaart_user.user_id')
->join('instructiekaart_niveau', 'instructiekaart_niveau.instructiekaart_id' ,'=', 'instructiekaarten.id')
->join('niveaus', 'niveaus.id' ,'=', 'instructiekaart_niveau.niveau_id')
->select('sets.name','instructiekaarten.name', 'stappen.name', 'niveaus.name')
->get();
return view('instructiekaarten.index')->with('instructiekaarten', $instructiekaarten);
View
#if(count($instructiekaarten) > 0)
#foreach($instructiekaarten as $instructiekaart)
<div class="card">
<a href="/instructiekaarten">
<h5 class="card-header">{{$instructiekaart->instructiekaarten.name}}</h5>
</a>
<div class="card-body">
<h5 class="card-title"></h5>
<p class="card-text"></p>
</div>
</div>
#endforeach
#else
<p>Geen instructiekaarten gevonden</p>
#endif
This is the error message I get when using {{$instructiekaart->instructiekaarten.name}}
Undefined property: stdClass::$instructiekaarten (View:
D:\wamp64\www\TZC\resources\views\instructiekaarten\index.blade.php)
Try Giving alias
->select('sets.name AS sets_name','instructiekaarten.name AS instru_name', 'stappen.name AS stappen_name', 'niveaus.name AS niveaus_name')
& then
{{ $instructiekaart->instru_name }}

Laravel 5.7 Comment count for different posts

I am stucked at point where i got comment count for posts but it shows count of all comments of all posts on every post. I would like to know how to output in blade comment count for post ID
here is controller:
$posts = $posts->orderBy("posted_at", "desc")
->paginate(config("blogetc.per_page", 10));
$comments = BlogEtcComment::all();
return view("blogetc::index", [
'posts' => $posts,
'title' => $title,
'comments' => $comments,
]);
blade:
#foreach($posts as $post)
<section class="blog_area p_120">
<div class="container">
<div class="row">
<div class="col-lg-8">
<div class="blog_left_sidebar">
<article class="blog_style1">
<div class="blog_img">
<img class="img-fluid" src="blog_images/{{$post->image_large}}" alt="">
</div>
<div class="blog_text">
<div class="blog_text_inner">
<div class="cat">
<a class="cat_btn" href="{{$post->url()}}">{{$post->slug}}</a>
<i class="fa fa-calendar" aria-hidden="true"></i>{{$post->created_at}}
<i class="fa fa-comments-o" aria-hidden="true"></i> {{count($comments)}}
</div>
<h4>{{$post->title}}</h4>
<p>{!! $post->generate_introduction(400) !!}</p>
<a class="blog_btn" href="{{$post->url()}}">Lasīt vairāk</a>
</div>
</div>
</article>
</div>
</div>
</div>
</div>
</section>
#endforeach
//Quickfix:
//assuming your posts table is called posts and that in your blogetccomments table //you have a post_id column pointing to the original post. Try something like
$posts = DB::table('posts')
->leftJoin('blogetccomments', 'posts.id', '=', 'blogetccomments.post_id')
->selectRaw('posts.*, count(blogetccomments.post_id) as commentcount')
->groupBy('posts.id')
->get();
In your blade template, Access the comments count for each post, as follows..
#foreach($posts as $post)
...
{{$post->title}}...
{{$post->commentcount}}
...
#endforeach
You can use withCount() to get count of comments for a specific post :
$posts = $posts->withCount('comments')
->orderBy("posted_at", "desc")
->paginate(config("blogetc.per_page", 10));
Above would require you to have comments relation on your Post Model :
Post Model :
public function comments()
{
return $this->hasMany(BlogEtcComment::class);
}
BlogEtcComment Model :
public function post()
{
return $this->belongsTo(Post::class);
}
And then in blade :
#foreach($posts as $post)
<p>Post : $post->id</p>
<p>Comments : $post->comments_count</p>
#endforeach

Laravel schema sql

so simply i want to select user name from table users AS created_by, but after i put this {{ $result->created_by }} in blade tamplate it shows this error "Undefined property: stdClass::$created_by (View: /var/www/hots/resources/views/builds.blade.php)". Please help me.
Schema
public function index() {
$builds = DB::table('Build_Talents')
->join('Builds', 'Builds.BuildID', '=', 'Build_ID')
->join('BuildTalents', 'BuildTalents.TalentsID', '=', 'Talents_ID')
->join('Heroes', 'Builds.hero', '=' ,'Heroes.HeroID')
->join('users', 'Builds.created_by', '=', 'users.id')
->select('Heroes.icon', 'Heroes.name',
DB::RAW('Builds.name AS build', 'users.name AS created_by')
)
->get();
return view('builds', compact('builds'));
}
Blade
#extends('home')
#section('content')
#if($builds)
#foreach($builds as $result)
<div class="col-md-12">
<div class="builds">
<img src="{{ $result->icon }}" alt="Build icon" />
<h2>{{ $result->name }}-{{ $result->build }}</h2>
<i>{{ $result->created_by }}</i>
</div>
</div>
#endforeach
#else
<p>Nic nenalezeno</p>
#endif
#endsection
Instead this:
DB::RAW('Builds.name AS build', 'users.name AS created_by')
use this:
DB::raw('Builds.name AS build, users.name AS created_by')
raw() has only one parameter and you are using two -
Api.

Slug not work properly

I am try create slug with laravel on admin its work but on front-end view its work too except one problem, i have four article and work nice on admin but when on view front end its always open same article even-tough slug is different URL.
Controller code
public function singleArticle($slug){
Article::where('slug', '=', $slug)->increment('viewed');
$navi['country'] = Country::get();
$navi['genre'] = Genre::get();
$articles = Article::orderBy('created_at','desc')->limit(3)->get();
$latest_movies = Movie::where('type', '=', 'movie')->orderBy('created_at','desc')->limit(4)->get();
$latest_tv = Movie::where('type', '=', 'tv')->orderBy('created_at','desc')->limit(4)->get();
$most_viewed_movies = Movie::where('type', '=', 'movie')->orderBy('viewed','desc')->limit(3)->get();
$most_viewed_tv = Movie::where('type', '=', 'tv')->orderBy('viewed','desc')->limit(4)->get();
$most_viewed_article = Article::orderBy('created_at','desc')->orderBy('viewed','desc')->limit(4)->get();
$article = Article::where('slug', '=', $slug)->first();
and for view front end
#if(count($articles) > 0)
<div class="articles_list">
#foreach($articles as $article)
<div class="col-md-6">
<div class="article_item row">
<div class="article_info">
#if($article->thumb)
<a href="{{route('articles.single',$article->slug)}}"><img class="img-responsive" src="{{ url(Image::url($article->thumb,350,200,array('crop'))) }}" alt="{{$article->title}}">
#else
{{-- <img class="img-responsive" src="{{ url(Image::url($article->thumb,250,250,array('crop'))) }}" alt="{{$article->title}}"> --}}
#endif
<div class="artice_title"><h3>{{$article->title}}</h3></div>
<div class="article_time">
<span class="author">By Admin</span>
<span class="cateogry">Category</span>
<span class="time">{{date('F d, Y', strtotime($article->created_at))}} </a></span></div>
<!--<div class="article_descr">
<?php echo mb_substr($article->content, 0, 200) . ' ...'; ?>
</div>
<a class="btn btn-default read_more" href="{{route('articles.single',$article->id)}}">Read more</a> -->
</div>
</div>
</div>
#endforeach
</div>
<div class="clearfix"></div>
<div class="text-center col-xs-12">
{{$articles->links()}}
</div>
#else
<div class="col-xs-12">
Nothing found in there
</div>
#endif
For routing below code :
// Category
Route::get('category/{slug}', ['as' => 'category.index', 'uses' => 'CommonController#categoryIndex']);
// Articles
Route::get('articles', ['as' => 'articles.index', 'uses' => 'CommonController#articleIndex']);
// Specific article
Route::get('articles/{slug}', ['as' => 'articles.single', 'uses' => 'CommonController#singleArticle']);
thanks before.
It is just issue of naming convention.Please choose different names for variables.
#foreach($articles as **$article**). It is in your view which have $article variable.
**$article** = Article::where('slug', '=', $slug)->first(); It is in your controller. so it is just because of conflict.

Laravel get profile name

I'm laravel newbie and I'm making simple CMS. So i have simple question:
I wan't when click on avatar - redirect to user profile (http://example.com/profiles/nickname/id)
In DB it saves that:
as you see author_id I have, now I need to get author name from users table:
And then generate url: http://example.com/profiles/Evaldas/2 (Evaldas, because author_id is 2 in topics table)
My routes file:
Route::get('topic/{tname}/{tid}', 'viewTopic#showTopic');
My viewTopic.php Controller:
<?php
namespace App\Http\Controllers;
use DB;
use View;
class viewTopic extends Controller
{
public function showTopic($tname, $tid)
{
return View::make('posts', [
'topics' => DB::table('topics')
->where('id', $tid)
->where('seo_title', $tname)
->first(),
'posts' => DB::table('posts')
->where('topic_id', $tid)
->select()
->get()
]);
}
}
And layout:
#extends('layouts.main')
#section('content')
<div class="media">
<div class="media-left">
<a href="HERE MUST BE HREF TO PROFILE">
<img class="media-object" src="http://localhost/uploads/avatars/2.jpg" style="width: 64px">
</a>
</div>
<div class="media-body" rel="#author{{ $topics->author_id }}">
<h4 class="media-heading">{{ $topics->title }}</h4>
#if(!empty($topics->text))
{{ $topics->text }}
#else
Message empty :(
#endif
</div>
#foreach($posts as $post)
<div class="media">
<div class="media-left">
<a href="HERE MUST BE HREF TO PROFILE">
<img class="media-object" src="http://localhost/uploads/avatars/1.png" style="width: 64px">
</a>
</div>
<div class="media-body" rel="#post{{ $post->pid }}">
{{ $post->text }}
</div>
</div>
#endforeach
</div>
#stop
Thanks so much in advance :)
If you want to use the Query Builder, you can use the join() method:
DB::table('posts')
->where('topic_id', $tid)
->join('users', 'user.id', '=', 'posts.author_id')
->select()
->get()
This way, the user information will be available:
$post->nickname
You can then build your URL using a laravel helper, for exemple, if you have a profile route:
<a href="{{route('profile', ['nickname' => $post->nickname, 'id' => $post->author_id]);}}">
An other method is to create models for your tables and define relationship between them.
See this: http://laravel.com/docs/5.1/eloquent-relationships
Using this method, you will be able to write things like $post->author->nickname

Categories