Laravel - pagination sorting by created_at - laravel

So guys I add pagination to my project and I'm almost finishing it, witch by the way is my first project ever, and all I need to do right now is to set pagination by created_at.So I need to put posts from the same day on same page link. Right now it shows me posts from different days on one page. And after that I just need to show price sum of that day. If you know please help me, this would be my first project as a student, I'm still learning. Thank you !!
Here is my HomeController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
use App\Post;
use DB;
use Auth;
class HomeController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Show the application dashboard.
*
* #return \Illuminate\Contracts\Support\Renderable
*/
public function index()
{
$posts = Post::where('user_id', Auth::id())->orderBy('created_at', 'DESC')
->paginate(3);
return view('home')->with('posts', $posts);
}
}
Here is my home.blade.php
#extends('layouts.theme')
#section('content')
<style>
body{
margin: 0;
background-color: #EBEBEB;
}
</style>
<div class="mainl">
<div class="row">
<div class="columna">
<h1>{{ Auth::user()->name }}</h1>
<hr>
</div>
<div class="columns">
<a href="{{ route('logout') }}" id="logout"
onclick="event.preventDefault();
document.getElementById('logout-form').submit();">
{{ __('LOGOUT') }}
</a>
<form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
#csrf
</form>
</div>
</div>
</br></br></br>
#if(count($posts)> 0)
<table>
<thead>
<tr>
<th>BR.KESICE</th>
<th>IME I PREZIME</th>
<th>BR.TELEFONA</th>
<th>POSAO</th>
<th>CIJENA</th>
<th>PLACANJE</th>
<th>POPUST</th>
<th>DATUM PREUZ.</th>
<th>DATUM IZDAV.</th>
<th>SMJENA</th>
<th>RADNIK</th>
<th>STATUS</th>
<th>IZMIJENI</th>
</tr>
</thead>
<tbody>
#foreach($posts as $post)
<tr>
<td>{{$post->br_kesice}}</td>
<td>{{$post->ime}}</td>
<td>{{$post->br_telefona}}</td>
<td>{{$post->posao}}</td>
<td>{{$post->cijena}}</td>
<td>{{$post->placanje}}</td>
<td>{{$post->popust}}</td>
<td>{{$post->datum_preuz}}</td>
#if($post->status == 1)
<td>/</td>
#else
<td>{{$post->datum_izdav}}</td>
#endif
<td>{{$post->smjena}}</td>
<td>{{$post->radnik}}</td>
<td>
#if($post->status == 0)
<span class="label label-primary" id="statusdeaktivan">Deaktivan</span>
#elseif($post->status == 1)
<span class="label label-success" id="statusaktivan">Aktivan</span>
#elseif($post->status == 2)
<span class="label label-danger" id="statusdeaktivan">Rejected</span>
#else
<span class="label label-info" id="statusdeaktivan">Deaktivan</span>
#endif
</td>
#if($post->status == 3)
#else
<td><i class="far fa-edit"></i></td>
#endif
</tr>
#endforeach
</tbody>
<tfoot>
<tr>
<th>UKUPAN IZNOS: {{ Auth::user()->posts->sum('cijena')}}€</th>
<th>KARTICA: {{ Auth::user()->posts->where('placanje', 'Kartica')->sum('cijena')}}€</th>
<th>GOTOVINA: {{ Auth::user()->posts->where('placanje', 'Gotovina')->sum('cijena')}}€</th>
<th>VIRMAN: {{ Auth::user()->posts->where('placanje', 'Virman')->sum('cijena')}}€</th>
</tr>
</tfoot>
</table>
{{ $posts->links()}}
#else
<p>Trenutno nema unosa.</p>
#endif
</div>
#endsection
And I found something from past questions here in stack overflow and it's working but I have a problem with that, so
public function index()
{
$posts = Post::where('user_id', Auth::id())->where('created_at', '>=', \Carbon\Carbon::now()->subDays(10))->get();
return view('home')->with('posts', $posts);
}
When I add this ->where('created_at', '>=', \Carbon\Carbon::now()->subDays(10))->get(); it shows me all posts from past 10 days but after that 10 days nothing, could I use this but to sort it by all days, not to set maximum days?
I also add this code to my price sum and it is working but as I said just for past 10 days
<tfoot>
<tr>
<th>UKUPAN IZNOS: {{ Auth::user()->posts->where('created_at', '>=', \Carbon\Carbon::now()->subDays(10))->sum('cijena')}}€</th>
<th>KARTICA: {{ Auth::user()->posts->where('placanje', 'Kartica')->where('created_at', '>=', \Carbon\Carbon::now()->subDays(10))->sum('cijena')}}€</th>
<th>GOTOVINA: {{ Auth::user()->posts->where('placanje', 'Gotovina')->where('created_at', '>=', \Carbon\Carbon::now()->subDays(10))->sum('cijena')}}€</th>
<th>VIRMAN: {{ Auth::user()->posts->where('placanje', 'Virman')->where('created_at', '>=', \Carbon\Carbon::now()->subDays(10))->sum('cijena')}}€</th>
</tr>
</tfoot>
Thank you again and I would really appreciate it if you help me with this. It's my first project and I'm very happy about it.

What your current code is doing is taking all the posts, sort it by created_at and then show 3 at a time. It doesn't care about what day it is or how many $post are there for that particular day.
What I understand that, you want to do is to show it by date. In that case, your query should filter based on date.
What you need to do is pass the date to the controller and fetch only posts from that day. It is a bit tricky. You need to pass today's date to controller.
In HTTP GET method your URL should contain the date. For example, it can be something like http://example.com/index?date=20190716. Notice that "date=20190716" part. You can get this in controller. Then you can get the posts of that day by writing,
$date = new Carbon(request('date'));
$posts = Post::where('user_id', Auth::id())
->whereDate('created_at','=',$date)
->orderBy('created_at', 'DESC')
->paginate(3);
Now, what it will do is get only the posts from 16th July, 2019.
This is the main idea. How you pass the date is entirely on you. You can do that in several ways. You can use JS, HTTP GET method and HTTP POST method.

Try
public function index()
{
$posts = Post::where('user_id', Auth::id())->get();
return view('home')->with('posts', $posts);
}

Try this also, I hope helps you
public function index()
{
$dateFromUrl = \Carbon\Carbon::createFromFormat('d/m/Y', request()->date);
$posts = Post::where('user_id', Auth::id())->where('created_at',$dateFromUrl)->orderBy('created_at', 'DESC')
->get();
$sum = 0;
foreach($posts as $post){
$sum+=$post->price;
}
return view('home', compact("posts","sum"));
}

Related

Undefined index: id Laravel 5.8

My Tables:
kategoris table
id | kode_kategori | kategori_name |
items table
id | kategori_id | item_name
In items table the kategori_id column has foreignkey.
My Controller:
public function edit($id)
{
// $item = Item::findOrFail($id);
$item = DB::table('items')
->join('kategoris', 'items.kategori_id', '=', 'kategoris.id')
->where('items.id', '=', $id)
->select('items.*', 'kategoris.*', 'items.id', 'items.kategori_id')
->get();
// dd($item);
return view('master-dev/item/edit', compact('item'));
}
My View:
<div class="card card-default">
{{ Form::model($item,['route'=>['item.update',$item['id']], 'files'=>true,'method'=>'PUT']) }}
<div class="card-header">
<h3 class="card-title"><b>Edit Data Item</b></h3>
<div class="card-tools">
<button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i></button>
</div>
</div>
<!-- /.card-header -->
<div class="card-body">
#if(!empty($errors->all()))
<div class="alert alert-danger">
{{ Html::ul($errors->all())}}
</div>
#endif
<div class="row">
<div class="col-md-6">
<div class="form-group">
{{ Form::label('kode_kategori', 'Kode Kategori') }}
<select name="kode_kategori" id="kode_kategori" class="form-control">
#foreach ($item as $i)
<option valu="{{ $i['kode_kategori'] }}">{{ $i['kode_kategori'] }}</option>
#endforeach
</select>
</div>
</div>
..........
..........
{{ Form::close() }}
I've tried any solutions in stackoverflow such as adding (ifempty...) and other solution but still the result Undefined index: id in my edit blade. When I was trying using dd and vardump the results was shown. I need to loop the foreach in my dropdown menu to show the list of data from my categories table. And I need to join my items table and my categories table to get the name of the categories.
you are calling same id from items and kategoris try this
public function edit($id)
{
// $item = Item::findOrFail($id);
$item = DB::table('items')
->join('kategoris', 'items.kategori_id', '=', 'kategoris.id')
->where('items.id', '=', $id)
->select('items.*', 'kategoris.id as kategory_id', 'kategoris.kode_kategori', 'kategoris.kategori_name')
->get();
// dd($item);
return view('master-dev/item/edit', compact('item'));
}
if this answer doesnot work show your database relation i will give you solution
$item = ....->get() will return a Collection to only have one item you need to use $item = ....->first() instead
But since you have #foreach ($item as $i) I believe, you still want to have a collection, but in that case, your issue is here
{{ Form::model($item,['route'=>['item.update',$item['id']], 'files'=>true,'method'=>'PUT']) }}
Since you have a collection, we don't know what $item['id'] it's referring to. Perhaps $item->first()['id'] ?
I solved the problem, there's a conflict fetching data from items and kategoris tables. There are differences calling a value with array and object, mostly if its data looped. So in the controller I must declared one by one, the selected value id from kategoris table, and I have to join both tables to get the name of the kategoris, and then I have to declare once more to get the list of the kategoris data. So there are three (3) variables to declare each one of them. For this long time I was looking for the short code in my Controller but I cannot find it.
Thank you for all of you guys helping me this problem. Cheers.

I can't retrieve data from the related table(model) in Laravel6

I can't retrieve data from the related table.
There are 3 models(tables).
User
Chirp (has 'user_id' as foreign key)
Click (has 'chirp_id' as foreign key)
then I want to retrieve User & Click's data from Chirp model.
So I wrote:
Chirp.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Chirp extends Model
{
public $timestamps = false;
protected $guarded = [];
public function user()
{
return $this->belongsTo('App\User');
}
public function clicks()
{
return $this->hasMany('App\Click');
}
}
HomeController.php
class HomeController extends Controller
{
public function index()
{
$chirps = Chirp::with(['user','clicks'])
->orderBy('posted_at', 'desc')
->get();
return view('home', ['chirps' => $chirps]);
}
}
home.blade.php
#foreach($chirps as $chirp)
<div>
<div>by
<b>{{ $chirp->user->name }}</b>
on
<small>{{ $chirp->posted_at }}</small>
</div>
<div>
<p>{{ $chirp->text }}</p>
<p>{{ $chirp->click->ip_address }}</p>
</div>
</div>
#endforeach
at home.blade.php, {{ $chirp->click->ip_address }} can't be retrieved and get error "Facade\Ignition\Exceptions\ViewException Trying to get property 'ip_address' of non-object"
However, if I delete it, I can retrieve {{ $chirp->user->name }} properly.
Why can't I retrieve Click model from Chirp model, While I can retrieve User model from Chirp model?
Thank you.
You need to loop over your clicks as well:
#foreach($chirps as $chirp)
<div>
<div>by
<b>{{ $chirp->user->name }}</b>
on
<small>{{ $chirp->posted_at }}</small>
</div>
#foreach($chirp->clicks as $click)
<div>
<p>{{ $chirp->text }}</p>
<p>{{ $click->ip_address }}</p>
</div>
#endforeach
</div>
#endforeach
Chirp has many clicks (not click). You have to foreach $chirp->clicks in your blade.
#foreach ($chirp->clicks as $click)
<p>This is click id {{ $click->id }}</p>
#endforeach
You've hasMany relation with Chirp and clicks
And here you're getting many clicks instead of click
#foreach($chirp->clicks as $click)
<p>{{ $click->ip_address }}</p>
#endforeach
To debug this problem you can take the following steps:
Check if the chirps variable has any data within the controller.
dd($chirps);
If you know you have the data you can take the steps to make your blade better.
Becasue its a many to many relation you should loop trough the data.
#foreach($chirps as $chirp)
#foreach($chirp->clicks as $click)
<div>
<p>{{ $chirp->text }}</p>
<p>{{ $click->ip_address }}</p>
</div>
#endforeach
#endforeach

Trying to get property of non-object in json from API

I'm using the Discord API to get the members on a Discord guild to display 10 randoms users and display it in the view with blade using the foreach method.
I'm getting the JSON from the API, getting the members array of it and sclicing it to return only 10 members to send it from the controller to the view.
The problem is that, when I want to parse it and use an element of the array (avatar_url), it's not working and I'm getting this error message: Trying to get property 'avatar_url' of non-object
Here is my controller
class IndexController extends Controller {
...
/**
* Function to get 10 random players on fivem
* #return array
*/
private function getServerPlayers() {
$request = file_get_contents('https://discordapp.com/api/guilds/683766194884575355/widget.json');
$decoded = json_decode($request, true)['members'];
return array_slice($decoded, 0, 10);
}
/**
* Return index view
* #return Factory|View
*/
public function index() {
return view('index')->with('players', $this->getServerPlayers())->with('clients', $this->getServerClients())->with('members', $this->getDiscordMembers());
}
}
Here is my view
<div class="row">
<div class="col-lg-12">
<div class="tab-content" id="pills-tabContent">
<div class="tab-pane fade show active" id="pills-all-bets" role="tabpanel"
aria-labelledby="pills-all-bets-tab">
<div class="responsive-table">
<table class="table">
<thead>
<tr>
<th scope="col">Nom du joueur</th>
<th scope="col">Statut</th>
</tr>
</thead>
<tbody>
#foreach($players as $player)
<tr>
<td><img src="{{ $player->avatar_url }}">{{ $player->username }}</td>
<td>En ligne</td>
</tr>
#endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
I think that the problem is kind of dumb but I'm blocked on it, I need some help !
Thanks.
You should use avatar_url like this:
<td><img src="{{ $player['avatar_url'] }}">{{ $player['username'] }}</td>
because what you pass to view is an array, not an object.
The problem is that json_decode returns an array and not an object.
You can pass the arguments to the view using:
return view('index',[
'players' => $this->getServerPlayers(),
'clients' => $this->getServerClients(),
'members' => $this->getDiscordMembers(),
]);
And then display them in the view using:
<img src="{{ $player['avatar_url'] }}">{{ $player['username'] }}

Eloquent query to blade on view styled better?

I'm doing an assignment (never ending assignments).
I have a query in my controller that sums up certain table items by month and then I show them in a view.
However, I feel I could have done this in a better way as the output looks not great and I'm not sure how to style it.
Controller method
public function monthly()
{
$activity = DB::table('activities')
->select(
DB::raw("Month(date) as Month"),
DB::raw("SUM(minutes) as total_minutes"),
DB::raw("SUM(distance) as total_distance"))
->orderBy("month")
->groupBy(DB::raw("month"))
->get();
return view ('summary/monthly',compact('activity')); }
* View *
#extends('layouts.app')
#section('content')
{{$activity}}
#endsection
Output in view
Any tips on what I could do better?
Edit
Oh man I was definitely over thinking my approach and thought it was an error with my controller. Thank you for the help!
You need something like this:
#foreach($activity as $singleActivity)
{{$singleActivity->Month}}
{{$singleActivity->total_minutes}}
{{$singleActivity->total_distance}}
#endforeach
You need to iterate the loop on your blade file.
#extends('layouts.app')
#section('content')
#foreach($activity as $acti )
<div class="activity">
<div class="month">{{ $acti->Month }}
</div>
<div class="minutes">{{ $acti->total_minutes }}
</div>
<div class="distance">{{ $acti->total_distance }}
</div>
</div>
#endforeach
#endsection
You can iterate your data using #forelse and displa it with table
#forelse ($activity as $act)
<li>
Month: {{ $act->Month }} Total Minutes: {{ $act->total_minutes}} Total Distance: {{ $act->total_distance}}
</li>
#empty
<p>No Activities</p>
#endforelse
I don't know what you like, but how is it?
<table>
<thead>
<tr>
<th>Month</th>
<th>TotalMinutes</th>
<th>TotalDistance</th>
</thead>
<tbody>
#foreach($activity as $act)
{{$act->Month}}
{{$act->total_minutes}}
{{$act->total_distance}}
#endforeach
</tbody>
</table>

Recursive display of data with blade, laravel

My Controller:
class Comments extends Controller {
public function GenerateComments($id){
$theme = DB::table('New_Themes')
->where('id', $id)
->get();
$Comments = NewTheme_Comment::where('id_theme', $id)->get();
return view('comments', ['Themes'=>$theme, 'Comments'=>$Comments]);
}
My Table(NewTheme_Comment):
id
parent_id
id_theme
user
text
upVotes
downVotes
My view(contains the recursive display of the tree of comments like the same in reddit), ......(data) contains the bootstrap media object, and the </div>'s things are used to round up (visually) the tree of comments as it should be:
<?php
tree($Comments, 0, 0);
$var = -1;
function tree($Comments, $parent_id = 0, $level=0, $c=0) {
global $var;
foreach($Comments as $Comment) {
if($Comment['parent_id'] == $parent_id) {
If ($level > $var) $var++; else {
for ($i = $var-$level+1; $i>0; $i--) { if ($c < 0) echo '</div> </div>'; else $c--; };
$var=$level;
};
echo '........(data)';
tree($Comments, $Comment['id'], $level+1,$c);
};
};
};
?>
The problem is that .........(data) should contain this stuff:
<div class="media">
<div class="media-left">
<img class="media-object" style="height:40px; width:40px;" src="{{ URL::asset("images/upVote.svg") }}" >
<div>{{$Comment->upVotes-$Comment->downVotes}}</div>
<img class="media-object" style="height:40px; width:40px;" src="{{ URL::asset("images/downVote.svg") }}" >
</div>
<div class="media-body">
<p class="media-heading">{{ $Comment->text }}</p>
<p class="media-heading">{{ $Comment->user }} / {{ $Comment->created_at }} </p>
And I am using the blade above this line | , which I can't integrate into that echo in view, replacing the ..........(data).
I have the intuition that the function I should integrate into the controller but I am broken(I spent to much time on recursive method of displaying comments) and I don't know how to take the data and print out it as whole unit recursively.
Any help is GREATLY appreciated to find a way out of this mess, thank you very much
Edit 1:
This is an example if i am filling with bootstrap media object in ........(data):
<div class="media">
<a class="media-left" href="#">
<img class="media-object" src="..." alt="...">
</a>
<div class="media-body">
<h4 class="media-heading">Media heading</h4>
Without 2 x </div>
You are approaching the views in a wrong way, as blade templates are not meant to use functions, it's better to follow the below recommendations.
The best way for that is to place the function code inside a blade file, for example recursive.blade.php:
recursive.blade.php
#foreach($comments as $comment)
//place your code here
#endforeach
Then in your main blade you can call it several times:
main.blade.php
<div>
#include('recursive', ['comments' => $comments])
</div>
The below example works for me and is the most widely used approach. remember the default value for parent_id is -1.
Model
public function children(){
return $this->hasMany(self::class,'parent_id','id')->with('children');
}
Controller
$comments = Comments::where('parent_id','=',-1)->get();
return view('comments',['comments'=> $comments]);
Blade (comments.blade.php)
<div class="tree">
#include('comment-list-widget',['comments' => $comment])
</div>
Blade (comment-list-widget.blade.php)
<ul>
#foreach($comments as $comment)
<li>
<a>{{$comment->text}}</a>
#if(!empty($comment->children) && $comment->children->count())
#include('comment-list-widget',['comments' => $comment->children])
#endif
</li>
#endforeach
</ul>

Resources