Displaying feeds and blogs according to the created time - laravel

I'm having a home page where all the feeds along with comments and blogs are being displayed. Right now it is showing first all the feeds and then the blog. But I want it should be displayed according to the created time, mixer of feeds and blog not like first feed will come and then the blog. Can anyone tell me how to acheive that. This is my index.blade.php
#extends('layouts/default')
{{-- Page title --}}
#section('title')
Home
#parent
#stop
{{-- page level styles --}}
#section('header_styles')
<!--page level css starts-->
<link rel="stylesheet" type="text/css" href="{{ asset('assets/css/frontend/action.css') }}">
<link rel="stylesheet" type="text/css" href="{{ asset('assets/css/frontend/tabbular.css') }}">
<link rel="stylesheet" type="text/css" href="{{ asset('assets/css/frontend/jquery.circliful.css') }}">
<link rel="stylesheet" type="text/css" href="{{ asset('assets/vendors/owl.carousel/css/owl.carousel.css') }}">
<link rel="stylesheet" type="text/css" href="{{ asset('assets/vendors/owl.carousel/css/owl.theme.css') }}">
<!--end of page level css-->
#stop
{{-- content --}}
#section('content')
<div class="row">
<div class="column col-md-1 col-xs-1 col-sm-1"></div>
<div class="column col-md-3 col-xs-3 col-sm-3"><!--gm-editable-region--> </div>
<div class="column col-md-4 col-xs-4 col-sm-4">
#include ('action.partials.form')
#include ('action.partials.error')
#include ('action.partials.feed')
#include ('action.partials.blogfeed')
</div>
<div class="column col-md-3 col-xs-3 col-sm-3"><!--gm-editable-region--></div>
<div class="column col-md-1 col-xs-1 col-sm-1"></div>
#stop
{{-- footer scripts --}}
#section('footer_scripts')
<!-- page level js starts-->
<script type="text/javascript" src="{{ asset('assets/js/frontend/jquery.circliful.js') }}"></script>
<script type="text/javascript" src="{{ asset('assets/vendors/owl.carousel/js/owl.carousel.min.js') }}"></script>
<script type="text/javascript" src="{{ asset('assets/js/frontend/carousel.js') }}"></script>
<script type="text/javascript" src="{{ asset('assets/js/frontend/index.js') }}"></script>
<!--page level js ends-->
#stop
This is action.partials.feed
#foreach($feeds as $feed)
<article class="media">
<div class="well">
<div class="pull-left">
<img class="profile" src="{{ URL::to('/uploads/users/'.$feed->user->pic) }}" class="img-responsive" alt="Image" style="width:48px;height:48px;padding-right : 10px;padding-bottom: 5px;">
</div>
<strong>{{ $feed->user->first_name }}
{{ $feed->user->last_name }}
<small> posted </small>
</strong>
{{ $feed->created_at->diffForHumans() }}<br><hr>
{{ $feed->feed_content }}
<hr>
{!! Form::open(['url' => 'home/{storecomment}']) !!}
<div><input type="hidden" name="feed_id" value="{{ $feed->feed_id }}" /></div>
<div class="form-group">
{!! Form::text('comment', null, ['class'=>'form-control', 'rows'=>3, 'placeholder'=>"Comment"]) !!}
</div>
<div class="form-group feed_post_submit">
{!! Form::submit('Comment', ['class' => 'btn btn-default btn-xs']) !!}
</div>
{!! Form::close() !!}
#foreach($feed->comments as $comment)
<div class="pull-left">
<img class="profile" src="{{ URL::to('/uploads/users/'. $comment->user->pic) }}" class="img-responsive" alt="Image" style="width:48px;height:48px;padding-right : 10px;padding-bottom: 5px;">
</div>
{{ $comment->user->first_name }}
{{ $comment->created_at->diffForHumans() }}
{{ $comment->comment }}<hr>
#endforeach
</div>
</article>
#endforeach
action.partials.blogfeed
#foreach($blogs as $blog)
<article class="media">
<div class="well">
<div class="pull-left">
<img class="media-object" src="{{ URL::to('/uploads/users/'.$blog->user->pic) }}" class="img-responsive" alt="Image" style="width:48px;height:48px;padding-right : 10px;padding-bottom: 5px;">
</div>
<strong>{{ $blog->user->first_name }}
{{ $blog->user->last_name }}
<small> posted blog</small>
</strong>
{{ $blog->created_at->diffForHumans() }}<br><hr>
<h4>{{ $blog->title }}</h4>
<div class="featured-post-wide thumbnail">
#if($blog->image)
<img src="{{ URL::to('/uploads/blog/'.$blog->image) }}" class="img-responsive" alt="Image">
#endif
</div>
</div>
</article>
#endforeach
This is my feedcontroller
<?php
namespace App\Http\Controllers;
use Request;
use Auth;
use Sentinel;
use App\Feed;
use App\Http\Requests;
use App\Blog;
use App\Http\Controllers\Controller;
use App\Comment;
class FeedsController extends Controller
{
public function index() {
// $comments = Comment::latest()->get();
$feeds = Feed::with('comments', 'user')->where('user_id', Sentinel::getUser()->id)->latest()->get();
$blogs = Blog::latest()->simplePaginate(5);
$blogs->setPath('blog');
return view('action.index', compact('feeds', 'blogs'));
}
public function store(Requests\CreateFeedRequest $request)
{
$request->merge( [ 'user_id' => Sentinel::getuser()->id] );
Feed::create($request->all());
return redirect('home');
}
public function storecomment(Requests\CommentRequest $request, Feed $feed)
{
$comment = new Comment;
$comment->user_id =Sentinel::getuser()->id;
$comment->feed_id = $request->feed_id;
$comment->comment = $request->comment;
$comment->save();
return redirect('/home');
}
}
Can any one tell me how to display feeds and blogs according to the published time.

In your controller index method, try something like this:
public function index() {
// $feeds = Feed::with('comments', 'user')->where('user_id', Sentinel::getUser()->id)->latest()->get();
// $blogs = Blog::latest()->simplePaginate(5);
// $blogs->setPath('blog');
$feeds = Feed::with('comments', 'user')->where('user_id', Sentinel::getUser()->id)->latest()->get();
$blogs = Blog::latest()->paginate(5);
$feeds = $feeds->merge($blogs)->sortByDesc('created_at');
return view('action.index', compact('feeds'));
}
The biggest problem you're going to have is that your Feed object is likely different than your Blog object. Meaning each will have unique column names that the other doesn't have. This is going to make doing the foreach a bit of a mess...
Remove #include ('action.partials.blogfeed'). This is not longer relevant for us.
In action.partials.feed...we'll output it all (hopefully without too many "hacks" and conditionals):
#foreach($feeds as $feed)
<article class="media">
<div class="well">
<div class="pull-left">
<img class="profile" src="{{ URL::to('/uploads/users/'.$feed->user->pic) }}" class="img-responsive" alt="Image" style="width:48px;height:48px;padding-right : 10px;padding-bottom: 5px;">
</div>
<strong>
{{ $feed->user->first_name }}
{{ $feed->user->last_name }}
<small> posted </small>
</strong>
// We'll use #if(isset($feed->title)) to check if it's a blog post, aka ugly hack.
#if(isset($feed->title))
{{ $blog->created_at->diffForHumans() }}
<br><hr>
<h4>{{ $blog->title }}</h4>
<div class="featured-post-wide thumbnail">
#if($blog->image)
<img src="{{ URL::to('/uploads/blog/'.$blog->image) }}" class="img-responsive" alt="Image">
#endif
</div>
#else
{{ $feed->created_at->diffForHumans() }}<br><hr>
{{ $feed->feed_content }}
<hr>
{!! Form::open(['url' => 'home/{storecomment}']) !!}
<div><input type="hidden" name="feed_id" value="{{ $feed->feed_id }}" /></div>
<div class="form-group">
{!! Form::text('comment', null, ['class'=>'form-control', 'rows'=>3, 'placeholder'=>"Comment"]) !!}
</div>
<div class="form-group feed_post_submit">
{!! Form::submit('Comment', ['class' => 'btn btn-default btn-xs']) !!}
</div>
{!! Form::close() !!}
#foreach($feed->comments as $comment)
<div class="pull-left">
<img class="profile" src="{{ URL::to('/uploads/users/'. $comment->user->pic) }}" class="img-responsive" alt="Image" style="width:48px;height:48px;padding-right : 10px;padding-bottom: 5px;">
</div>
{{ $comment->user->first_name }}
{{ $comment->created_at->diffForHumans() }}
{{ $comment->comment }}<hr>
#endforeach
#endif
</div>
</article>
#endforeach

Because Illuminate\Database\Eloquent extends Illuminate\Support\Collection, we can easily merge them together. Because both $feeds and $blogs are an Eloquent Collection, we can easily merge them into one collection:
$feeds_and_blogs = collect($feeds->toArray(), $blogs->toArray());
Now you will have a combination of both. Because you've used $table->timestamps() in your migration to get your columns, we can easily perform a comparison against the created_at timestamp to get the sorting that you want:
$sorted_feeds_and_blogs = $feeds_and_blogs->sortBy(function($item){
return $item->created_at;
});
However, you likely want them to be sorted by newest first. Thankfully, collections have a sortByDesc function which will do exactly what we want.
Although in the grand scheme of things you probably really want a Polymorphic relationship.

Related

Laravel Pagination not working in Blade file with Tailwind CSS

I'm trying to use Laravel pagination. The issue is that when I use the links() method in the Blade file, it gives an error. For example, when I use the URL "http://127.0.0.1:8000/tournaments?page=3," it works fine, but it gives an error in the Blade file, as explained below.
Controller
public function index()
{
return view('front.tournaments', [
'seriesdata' => $this->tournamentList()
]);
}
public function tournamentList()
{
return Series::leftJoin('team_squads as ts', 'ts.id_series', 'series.id')
->leftJoin('series_team_squads as sts', 'sts.id_series', 'series.id')
->leftJoin('admins as a', 'a.adminable_id', 'series.id')
->where('series.lang', 'en')
->orderBy('series.id', 'asc')
->groupBy('series.id')
->select('series.*')
->paginate(10)
->append([
'logo_url',
'location'
]);
}
Blade
#foreach($seriesdata as $series)
<div class="flex flex-inline xs:flex-col sm:flex-row">
<div class="w-full border-b">
<div class="flex justify-center items-start">
<div class="py-2 mx-auto sm:bg-white xs:bg-white w-full">
<a href="{{ url('tournaments/').'/'.$series->url.'/'.$series->id }}" class="flex">
<div class="grid grid-rows-1 grid-flow-col gap-1">
<div class="row-span-1 col-span-2">
<img src="{{ $series->logo_url }}" alt="avatar" class="object-cover w-12 h-12 mx-4">
</div>
<div class="row-span-1 col-span-2">
<h1 class="font-bold text-lg">{{ $series->name }}</h1>
<p class="uppercase font-light text-sm text-grey">{{ $series->location->address }}</p>
</div>
</div>
</a>
</div>
</div>
</div>
</div>
#endforeach
{{ $seriesdata->links() }}
Error
It looks like your append() method is blocking pagination in blade. Try to remove it from tournamentList() in controller.
When you do ->append() after the ->paginate(), you are transforming what ->paginate() returns (basically a LenghtAwarePaginator) into a Collection, and Collection does not have a ->links() method. You can see this as the error shows you are trying to call links method in Illuminate\Database\Eloquent\Collection, that is how I know what ->append() is returning.

Laravel query return wrong data

QUERY:
$recent_posts = Blog::join("categories",'categories.id', '=', 'blogs.category_id')
->where('categories.status', 1)
->orderBy('blogs.id', 'desc')
->take(3)
->get();
Both tables had a created_at column.
At frontend im using this to retrieve the data:
<div class="row justify-content-center">
#foreach ($recent_posts as $recent_post)
<div class="col-md-6 col-lg-4 latest-blog-resp">
<div class="blog-item">
<div class="blog-img">
<a href="{{ url('blog/'.$recent_post->slug) }}">
#if ($recent_post->blog_image == '')
<img src="{{ asset('fibonacci/adminpanel/assets/img/dummy/no_image.jpg') }}" class="img-fluid round-item" alt="blog image">
#else
<img src="{{ asset('fibonacci/adminpanel/assets/img/blog/thumbnail1/'.$recent_post->blog_image) }}" class="img-fluid round-item" alt="blog image">
#endif
</a>
</div>
<div class="blog-inner">
<div class="blog-meta">
<span class="mr-2">
<i class="mdi mdi-calendar-account-outline"></i>{{ __('frontend.by_admin') }}
</span>
<span>
<i class="mdi mdi-calendar-range"></i>{{Carbon\Carbon::parse($recent_post->created_at)->isoFormat('MMMM')}} {{Carbon\Carbon::parse($recent_post->created_at)->isoFormat('DD')}}
</span>
</div>
<h5 class="blog-title">
{{ $recent_post->title }}
</h5>
<p class="blog-desc">{{ $recent_post->short_description }}</p>
<a href="{{ url('blog/'.$recent_post->slug) }}" class="blog-more-link">
{{ __('frontend.read_more') }} <i class="fa fa-angle-right ml-2"></i>
</a>
</div>
</div>
</div>
#endforeach
#if (count($recent_posts) === 3)
<div class="col-12 text-center margin-top-30">
<div class="btn-group">
<a href="{{ url('blog') }}" class="default-button">
{{ __('frontend.view_all') }}
</a>
</div>
</div>
#endif
</div>
THE PROBLEM:
$recent_post->created_at returns the category table creation (created_at) date but we expect to receive the blog table result as created_as (like a post creation data).
Thanks in advance!
Specify your fields in a select clause.
$recent_posts = Blog::select(
'blogs.slug',
'blogs.blog_image',
'blogs.title',
'blogs.short_description',
'blogs.created_at'
)
->join('categories', 'categories.id', 'blogs.category_id')
->where('categories.status', 1)
->orderByDesc('blogs.id')
->take(3)
->get();

Else Statement returned Blank in Laravel

I want to implement a simple search on my Laravel Application
public function search()
{
$search = request()->query('search');
if ($search) {
$books = Book::where('name', 'LIKE', "%{$search}%")->simplepaginate(12);
}
else {
echo "<h2>Book Not Found, please try using another search term</h2>";
$books = Book::orderBy('created_at', 'desc')->simplepaginate(12);
}
return view('search')->with('books', $books);
}
But the else returned a blank screen when the search terms can't be found
UPDATE
Here is my view file
<div class="container">
<div class="row">
<div class="col-sm-12 col-md-10 offset-md-1">
<div class="row">
#foreach($books as $book)
<div class="col-md-3">
<div class="home-catalog-image">
<a href="{{ route('book', $book->id) }}" target="_blank">
<!-- <img src="{{ $book->image }}" alt="trending image" /> -->
<img src="{{ $book->image_url }}" class="img-responsive" alt="{{$book->image_url}}">
</a>
</div>
<p class="author">{{ $book->author->name }}</p>
<h1 class="book-title">{{str_limit($book -> name, 20) }}</h1>
</div>
#endforeach
</div>
<p style="text-align:center;>"> {!! $books->render() !!} </p>
</div>
</div>
</div>
Check how to use the request() helper to get the input.
Also you can use when() method for conditional clauses instead if else.
public function search()
{
$search = request('search', null);
$books = Book::when($search, function ($query, $search) {
return $query->where('name', 'LIKE', "%{$search}%");
})
->orderBy('created_at', 'desc')
->simplePaginate(12);
return view('search')->with('books', $books);
}
Then in Blade you can use #forelse directive to loop the collection, or if it's empty, show the message.
<div class="container">
<div class="row">
<div class="col-sm-12 col-md-10 offset-md-1">
<div class="row">
#forelse ($books as $book)
<div class="col-md-3">
<div class="home-catalog-image">
<a href="{{ route('book', $book->id) }}" target="_blank">
<!-- <img src="{{ $book->image }}" alt="trending image" /> -->
<img src="{{ $book->image_url }}" class="img-responsive" alt="{{$book->image_url}}">
</a>
</div>
<p class="author">{{ $book->author->name }}</p>
<h1 class="book-title">{{str_limit($book -> name, 20) }}</h1>
</div>
#empty
<h2>Book Not Found, please try using another search term</h2>
#endforelse
</div>
<p style="text-align:center;>"> {!! $books->render() !!} </p>
</div>
</div>
</div>
To solve my problem, I use forelse instead of foreach a
#forelse($books as $book)
<div class="col-md-3">
<div class="home-catalog-image">
<a href="{{ route('book', $book->id) }}" target="_blank">
<!-- <img src="{{ $book->image }}" alt="trending image" /> -->
<img src="{{ $book->image_url }}" class="img-responsive" alt="{{$book->image_url}}">
</a>
</div>
<p class="author">{{ $book->author->name }}</p>
<h1 class="book-title">{{str_limit($book -> name, 20) }}</h1>
</div>
#empty
<h2>Book Not Found, please try using another search term</h2>
#endforelse
In my controller, I used
public function search()
{
$search = request('search', null);
$books = Book::when($search, function ($query, $search) {
return $query->where('name', 'LIKE', "%{$search}%");
})
->orderBy('created_at', 'desc')
->simplePaginate(12);
return view('search')->with('books', $books);
}

Using 2 Controller Functions in a View in Laravel

I want to have two loops in my view, so I wrote these two functions
public function index()
{
$books = Book::orderBy('created_at', 'desc')->take(10)->get();
return view('bookpage')->with('books', $books);
}
public function loggedin()
{
$books = Book::orderBy('RAND()')->take(1)->get();
return view('bookpage')->with('books', $books);
}
In the view I have
<!--First Loop -->
#foreach($books as $book)
<div class="col-md-6">
<div class="out-box">
<h2>{{ $book->name }}</h2>
<h3>{{ $book->author->name }}</h3>
<br>
Start Reading<br><br>
<img src="assets/img/cart-buy.png" width="13px"/> Buy
</div>
</div>
</div>
</div>
<div class="col-md-6">
<input id="aboutbook" type="radio" name="tabs" checked>
<label for="aboutbook" class="aboutbook">About This Book</label>
<input id="bookreview" type="radio" name="tabs">
<label for="bookreview" class="bookreview">Reviews</label>
<hr style="background-color:black;">
<section style="padding-top:5px;" id="bookabout" >
<div class="row">
<div class="col-md-12">
<p>{{ $book -> about }}</p>
<h1>About the Author</h1>
</div>
</div>
<div class="row">
<div class="col-sm-4 col-md-3 col-6">
<img src="assets/img/Ellipse.png" class="rounded-circle" width="120px">
</div>
<div class="col-sm-4 col-md-4 col-6">
<h1>{{ $book->author->name }}</h1>
<h4>{{ $book->author->about }}</h4>
</div>
<div class="col-sm-4 col-md-5">
<div id="learnbtn">
Learn More
</div>
</div>
</div>
</section>
<section style="padding-top:5px;" id="bookabout1" >
jjjjjjj
</section>
</div>
</div>
</div>
#endforeach
</section>
<!--Second Loop -->
#foreach($books as $book)
#if($book->recommended === 1)
<div class="col-1-5">
<div class="home-catalog-image">
<a href="{{ $book->image_url }}" target="_blank">
<!-- <img src="{{ $book->image }}" alt="trending image" /> -->
<img src="{{ $book->image_url }}" class="img-responsive" alt="{{ $book->image_url }}">
</a>
<!-- <img src="{{ asset('/books/'.$book->image) }}" alt="trending image" /> -->
</div>
<p class="author">{{ $book->author->name }}</p>
<h1 class="book-title">{{str_limit($book -> name, 20) }}</h1>
</div>
#endif
#endforeach
In my web.php
Route::get('/', 'WelcomeController#index')->name('welcome');
I want to call another function in the view, although I know the method is wrong, I don't know how to go about it.
You don't have to create two different method for logged in user just use
public function index()
{
if(auth()->user()) {
$books = Book::orderBy('RAND()')->take(1)->get();
} else $books = Book::orderBy('created_at', 'desc')->take(10)->get();
return view('bookpage')->with('books', $books);
}
in view file use
#auth
//code for logged in user
#else
//code for guest user
#endauth
I was able to solve my problem like this
public function loggedin()
{
$data = array();
$data['recommends'] = Book::where('recommended', 1)->take(10)->get();
$data['latests'] = Book::orderBy('created_at', 'desc',)->where('recommended', 0)->take(10)->get();
$data['logged'] = Book::all()->random(1);
return view('index-logged', compact("data"));
}
In my view, I did
#foreach($data['logged'] as $log)
<h1>{{ $log->author->name }}</h1>
<h4>{{ $log->author->about }}</h4>
#endforeach
#foreach($data['recommends'] as $recommend)
<p class="author">{{ $recommend->author->name }}</p>
<h1 class="book-title">{{str_limit($recommend -> name, 20) }}</h1>
#endforeach
#foreach($data['latests'] as $latest)
<p class="author">{{ $latest->author->name }}</p>
<h1 class="book-title">{{str_limit($latest -> name, 20) }}</h1>
#endforeach

Laravel replace/convert #foreach loop to vue v-for loop with database relationship

Im making a laravel SPA and I recently learned how to use vue and I know how v-for works for vue using my components. I only know how to loop only in a single table without relation thats why I'm having a difficult time changing it. I have two tables which are news and comments, and this table news hasMany comments in it.
my blade file for now.
#foreach($news->comments as $comment)
<div class="comment" style="background-color: #f6efef;" >
<div class="author-info">
<img src={{"https://www.gravatar.com/avatar/" . md5(strtolower(trim($comment->email))) . "?s=50&d=retro" }} class="author-image" id="image">
<div class="author-name">
<h4>{{$comment->name}} </h4>
<p class="author-time"> {{ date('jS F, Y - g:iA' ,strtotime($comment->created_at)) }}</p>
</div>
</div>
<div class="comment-content">
{{$comment->comment}}
</div>
</div>
#endforeach
your component goes like this in vue2.0
**block.vue**
<template>
<div class="comment" style="background-color: #f6efef;" v-for="comment in
news.comments" >
<div class="author-info">
<img :src="comment.author_image" }} class="author-image" id="image">
<div class="author-name">
<h4>{{ comment.name }} </h4>
<p class="author-time"> {{ comment.time }}</p>
</div>
</div>
<div class="comment-content">
{{ comment.comment }}
</div>
</div>
</template>
<script>
export default {
name: "block",
props: [ "news" ], //or
data() => ({ news: [] })
}
</script>

Resources