Leaving reviews on multiple products and Laravel relations - php

I have order system and when user order some product he then can leave feedback for the product.
My issue is when there are multiple products in same order. I want to place button on each product leave feedback.
In my controller I have this
public function orderView($orderId)
{
$order = Order::where('order_id', $orderId)->where('status', 1)->where('user_id', Auth::user()->user_id)->first();
$reviews = Review::where('user_id', Auth::user()->user_id)->get();
return View::make('order_details', [
'order' => $order,
'reviews' => $reviews
]);
}
The function query the orders table and reviews table. Then on the page I'm trying to do this
#foreach($reviews as $review)
#if($item->product_id == $review->product_id)
#if($review->rating_published == 0)
<a class="btn btn-warning" href="">Wating for Approval</a>
#else
<a class="btn btn-warning" href="">Edit Review</a>
#endif
#else
<a class="btn btn-warning" href="">Leave Review</a>
#endif
#endforeach
For now the problem is that if there is no reviews from logged user I don't see "leave review" button on page.
My review model have
public function user()
{
return $this->belongsTo('App\User', 'user_id', 'user_id');
}
public function item()
{
return $this->belongsTo('App\Product', 'product_id','product_id');
}
Product model
public function reviews()
{
return $this->hasMany('App\Review', 'product_id');
}

you can make use of #forelse blade syntax
#forelse ($users as $user)
<li>{{ $user->name }}</li>
#empty
<p>No users</p>
#endforelse
so your code may be rewritten as follows
#forelse($reviews as $review)
#if($item->product_id == $review->product_id)
#if($review->rating_published == 0)
<a class="btn btn-warning" href="">Wating for Approval</a>
#else
<a class="btn btn-warning" href="">Edit Review</a>
#endif
#endif
#empty
<a class="btn btn-warning" href="">Leave Review</a>
#endforelse
so if the review array is empty it will show the leave a review message

Related

Checking for the presence of posts in a category does not work. php, Blade, Laravel

I have a view with all categories, by clicking on a category, the user can go to that category. But I want to prevent going there if there are no posts in that category. I tried to do this:
#if(($category->id === $category->posts()) !== 0)
<a class="btn btn-success" href="{{ route('category', $category->code)}}">Open</a>
#else
<span class="btn btn-warning">No posts in this category</span>
#endif
posts() is an eloquent relationship in my Category model:
public function posts() {
return $this->hasMany(Post::class);
}
But it doesn't work. All categories are written either "The post has no categories" or "Open". That is, the check does not work correctly.
in your blade file check condition like that
#if($category->posts_count > 0)
<a class="btn btn-success" href="{{ route('category', $category->code)}}">Open</a>
#else
<span class="btn btn-warning">No posts in this category</span>
#endif
in your controller used withCount method
$category = Category::withCount('posts')->get();
and in your category model add relationship if not added(one to many)
public function posts(){
return $this->hasMany(Post::class);
}
in controller you can do
$category = Category::withCount('posts')->get()
it generate post_count key which you can check in view
#if($category->posts_count > 0)
<a class="btn btn-success" href="{{ route('category', $category->code)}}">Open</a>
#else
<span class="btn btn-warning">No posts in this category</span>
#endif
https://laravel.com/docs/8.x/eloquent-relationships#counting-related-models
Update
$category = Category::withCount('posts')->findOrFail(1)
if($category->posts_count > 1){
return redirect()->back()
}

Laravel - How to sum child data and pass it to parent #foreach

i'm new to laravel. So in this case i'm trying to sum child data and pass it to parent nominal column inside parent index #foreach,
the thing is idk how to declare the parent id inside controller
here's my parent index which i want to show the sum child each parent id in #foreach
here's my child index that i've already sum it, i want to show it into parent #foreach nominal column as well
here's my SPJCreateController which is parent controller
class SPJCreateController extends Controller
{
public function index(Request $request, $id)
{
$kegiatan = DPAKegiatan::with('dpatahun')->findorfail($id);
$data = SPJCreate::with('spjcreatedetail')
->where('id_dpakegiatan', $kegiatan->id)
->orderBy('created_at', 'asc')
->paginate(10);
$total = SPJCreateDetail::where('id_spj', $request->id)->sum('nominal');
return view('spj.kegiatan.create.data', compact('kegiatan','data','total'));
}
}
in this controller i declare variable $total which is gonna sum column 'nominal' in SPJCreateDetail Model but idk how to declare where inside of it since $id is the id of grandparent
It returns 0 inside nominal column if i put $request->id inside where
however it shown when i call it manually like this
$total = SPJCreateDetail::where('id_spj', 6)->sum('nominal');
my parent index after i put where id manually
But i don't want that because i want my id to be dynamically called and sum eachrow of it
My SPJCreate Model which is parent model
class SPJCreate extends Model
{
protected $primaryKey = 'id';
protected $table = 'spj';
protected $fillable = ['id_dpakegiatan','tipebelanja','tipebelanjadetail'];
public function dpakegiatan()
{
return $this->belongsTo(DPAKegiatan::class, 'id_dpakegiatan');
}
public function spjcreatedetail()
{
return $this->hasMany(DPAKegiatan::class, 'id');
}
}
My SPJCreateDetail model which is child model
class SPJCreateDetail extends Model
{
protected $primaryKey = 'id';
protected $table = 'spj_detail';
protected $fillable = ['id_spj','id_listbelanja','ket','penerima','nominal','ppn','pph21','pph22','pph23'];
public function spjcreate()
{
return $this->belongsTo(SPJCreate::class, 'id_spj');
}
}
Sorry for my bad english i hope u guys can help me because im stuck for a month trying to figure it out :( , Thank you.
i dd inside my controller
$total = dd(SPJCreateDetail::where('id_spj', $request->id)->sum('nominal'));
it returns like this
image
however
$total = dd(SPJCreateDetail::where('id_spj', 6)->sum('nominal'));
it return the value correctly
image
here's my web routes
// --Here's my grandparent routes-- //
Route::get('/spj/kegiatan&id={spjkeg}', 'SPJKegController#index')->name('spjkeg')->middleware('auth');
// ------------- //
// --Here's my Parent Route Which is Gonna show my child sum-- //
Route::get('/spj/kegiatan/create&id={spjcreate}', 'SPJCreateController#index')->name('spj')->middleware('auth');
Route::post('/spj/kegiatan/create/store&id={spjcreate}', 'SPJCreateController#store')->name('spj.store')->middleware('auth');
Route::post('/spj/kegiatan/create/updt&id={spjcreate}', 'SPJCreateController#update')->name('spj.update')->middleware('auth');
Route::delete('/spj/kegiatan/create/del&id={spjcreate}', 'SPJCreateController#destroy')->name('spj.destroy')->middleware('auth');
// ------------ //
// --Here's the child route-- //
Route::get('/spj/kegiatan/create/detail&id={spjdet}', 'SPJCreateDetailController#index')->name('spj.detail')->middleware('auth');
Route::post('/spj/kegiatan/create/detail/store&id={spjdet}', 'SPJCreateDetailController#store')->name('spj.detail.store')->middleware('auth');
Route::post('/spj/kegiatan/create/detail/updt&id={spjdet}', 'SPJCreateDetailController#update')->name('spj.detail.update')->middleware('auth');
Route::delete('/spj/kegiatan/create/detail/del&id={spjdet}', 'SPJCreateDetailController#destroy')->name('spj.detail.destroy')->middleware('auth');
// ------------ //
Here's my View.blade.php
#php $no = 0; #endphp
#forelse($data as $spj => $result)
#php $no++; #endphp
<tr>
<td class="text-center">{{ $spj + $data->firstitem() }}.</td>
<td class="text-center"><b>{{ $result->tipebelanjadetail }}</b></td>
<td class="text-center">{{ $total }}</td>
<td class="text-center">
<div class="dropdown">
<button data-id="{{ $result->id }}" data-idtipebelanja="{{ $result->tipebelanja }}" data-idtipebelanjadetail="{{ $result->tipebelanjadetail }}" data-toggle="modal" data-target="#editspj" class="btn btn-success btn-s" style="background-color:#138496;border-color:#138496"><i class="fad fa-pencil"></i></button>
<button data-id="{{ $result->id }}" data-toggle="modal" data-target="#deletespj" class="btn btn-success btn-s" style="background-color:#eb1c0f;border-color:#eb1c0f"><i class="fad fa-trash"></i></button>
<button type="button" data-toggle="dropdown" class="btn btn-warning dropdown dropdown-toggle" aria-haspopup="true" aria-expanded="false"><i class="fad fa-info"></i></button>
<div class="dropdown-menu">
<a class="dropdown-item" href="{{ Route('spj.detail', $result->id)}}"><i style="padding-right:5px" class="fad fa-eye"></i>Detail</a>
</div>
</div>
</td>
</tr>
#empty
<tr>
<td colspan="7" class="text-center">Tidak ada data <i class="far fa-frown fa-5"></i></td>
</tr>
#endforelse
Try this.
public function index($spjcreate)
{
$kegiatan = DPAKegiatan::with('dpatahun')->findorfail($spjcreate);
$data = SPJCreate::with('spjcreatedetail')
->where('id_dpakegiatan', $kegiatan->id)
->withCount(['spjcreatedetail AS total' => function ($query) {
$query->select(DB::raw('SUM(nominal) as total'));
}])
->orderBy('created_at', 'asc')
->paginate(10);
return view('spj.kegiatan.create.data', compact('kegiatan','data'));
}
#php $no = 0; #endphp
#forelse($data as $spj => $result)
#php $no++; #endphp
<tr>
<td class="text-center">{{ $spj + $data->firstitem() }}.</td>
<td class="text-center"><b>{{ $result->tipebelanjadetail }}</b></td>
<td class="text-center">{{ $result->total }}</td>
<td class="text-center">
<div class="dropdown">
<button data-id="{{ $result->id }}" data-idtipebelanja="{{ $result->tipebelanja }}" data-idtipebelanjadetail="{{ $result->tipebelanjadetail }}" data-toggle="modal" data-target="#editspj" class="btn btn-success btn-s" style="background-color:#138496;border-color:#138496"><i class="fad fa-pencil"></i></button>
<button data-id="{{ $result->id }}" data-toggle="modal" data-target="#deletespj" class="btn btn-success btn-s" style="background-color:#eb1c0f;border-color:#eb1c0f"><i class="fad fa-trash"></i></button>
<button type="button" data-toggle="dropdown" class="btn btn-warning dropdown dropdown-toggle" aria-haspopup="true" aria-expanded="false"><i class="fad fa-info"></i></button>
<div class="dropdown-menu">
<a class="dropdown-item" href="{{ Route('spj.detail', $result->id)}}"><i style="padding-right:5px" class="fad fa-eye"></i>Detail</a>
</div>
</div>
</td>
</tr>
#empty
<tr>
<td colspan="7" class="text-center">Tidak ada data <i class="far fa-frown fa-5"></i></td>
</tr>
#endforelse

invalid argument supplied for foreach() laravel relationship

I'm trying to show a book's comments by ISBN (book table's PK) and I get the following error:
Invalid argument supplied for foreach
I'm using Laravel relationship and a foreach to get the records from the following query, in a Helper class:
function getCommentsByISBN($data)
{
foreach (Book::where("ISBN", $data)->get() as $comments) {
return $comments->comments;
}
}
And here's my Book model, comment relationship:
public function comments()
{
return $this->hasMany(Comment::class, "ISBN", "ISBN");
}
And here's the view where I show the comments:
#foreach(getCommentsByISBN(session("isbn")) as $comment)
<div class="form-group">
<h3>
{{ getUserWhoPostedComment($comment->email) }}
</h3>
<p>
{{ $comment->commentary }}
</p>
#if(Session::has("username") && isAdmin(session("username")))
<button type="button" onclick="openModal('{{$comment->commentary}}')"
name="warningButton" class="btn btn-warning" data-toggle="modal"
data-target="#modalWarning">
<i class="fas fa-exclamation-circle"></i>
</button>
#endif
<hr>
<span>
Hace: {{ getTimeWherePostedComment($comment->publicated_at) }}
</span>
</div>
#endforeach
Thanks in advance!
I think you helper returns void because no book was found with that ISBN.
I think it should look like this btw
function getCommentsByISBN($isbn)
{
if ($book = Book::where("ISBN", $isbn)->first()) {
return $book->comments;
}
}
and in your blade your top should look like
#php
$comments = getCommentsByISBN(session("isbn")) ?: [];
#endphp
#foreach($comments as $comment)
<div class="form-group">
/// Rest of the code

How to limit delete acces from direct link?

I have 2 questions and I need your help.First of all, I have made a delete route for comments, but other users logged can also delete comments from direct link...link.com/deleteComment/id. How to make this available only for owner of the comment?The owner id is saved in database and can be accessed with {{ $comment->user_id }}.
Second problem...In my view, when I click on a photo which have no comments, I'm receiving undefined variable comment, but I dont know why because on photos with comments, I have no problem with that.Can I make something like if comments != empty, dont show it or something like that?
CommentsController:
public function store(Request $request, $post_id)
{
$this->validate($request, array(
'comment' => 'required|min:5|max:2000',
));
$post = Post::find($post_id);
$comment = new Comment();
$comment->username = Auth::user()->username;
$comment->email = Auth::user()->email;
$comment->user_id = Auth::user()->id;
$comment->comment = $request->comment;
$comment->approved = true;
$comment->post()->associate($post);
$comment->save();
Session::flash('message', "Message posted successfully!");
return Redirect::back();
}
PostsController:
public function delete($id){
DB::table('posts')->where('id',$id)->delete();
return redirect('/profile/' . auth()->user()->id);
}
My view
#foreach($post->comments as $comment)
<div class="comment d-flex ">
<p><strong><a class="text-dark" href="/profile/{{ $comment->user_id }}">{{ $comment->username}}</a>: </strong> {{ $comment->comment}}</p>
#can('update', $post->user->profile)
<div class="dropdown col-md-6">
<button type="button" class="btn btn-primary dropdown-toggle btn-sm" style="background-color: #ffffff00;border: 1px solid #555;color: black;padding: 0 5px" data-toggle="dropdown">
Select
</button>
<div class="dropdown-menu">
<a class="dropdown-item" href="#">Edit comment</a>
<a class="dropdown-item" title="Options" style="text-decoration: none;" href="/deleteComment/{{$comment->id}}">Delete comment</a>
</div>
</div>
</div>
#endcan
#endforeach
My route
Route::post('comments/{post_id}', ['uses' => 'CommentsController#store', 'as' => 'comments.store']);
Route::get('/deleteComment/{id}', 'CommentsController#delete');
Try this to restrict the deletion only for the authenticated user who owns the comment:
/**
* Comments Controller Method Delete
*/
public function delete($id){
if(!DB::table('comments')->where('id',$id)->where('user_id',auth()->user()->id)->delete()){
Session::flash('remove', "You do not have permission to delete the comment!");
}else{
Session::flash('remove', "Message removed successfully!");
}
return Redirect::back();
}
For your second question, I think that what happens is that by not having comments you are using the variable without results.
You can try to enclose the statement where you use the variable $comments using this.
For Controller or others files php
if (!$comment->isEmpty()) {
//your code
}
if ($comment->count()) {
//your code
}
if (count($comment)) {
//your code
}
For Blade
#if(!$comment->isEmpty())
//your code
#endif
#if($comment->count())
//your code
#endif
#if(count($comment))
//your code
#endif
I hope I could help you, if not, please attach more code where they appear exactly what he says, since comments and delete the picture, since I have not seen in the code you have attached. Thanks and good luck.
References
$comment->isEmpty
$comment->count() and count($comment)
Updated
<div class="row">
<div class="col-md-12">
#if(!$post->comments->isEmpty()) //****Added
#if($post->comments->count() > 0)
#foreach($post->comments as $comment)
<div class="comment d-flex ">
<p><strong><a class="text-dark"
href="/profile/{{ $comment->user_id }}">{{ $comment->username}}</a>:
</strong> {{ isset($comment->comment) ? $comment->comment : "--" }}</p>
#can('update', $post->user->profile)
<div class="dropdown col-md-6">
<button type="button" class="btn btn-primary dropdown-toggle btn-sm"
style="background-color: #ffffff00;border: 1px solid #555;color: black;padding: 0 5px"
data-toggle="dropdown">
Select
</button>
<div class="dropdown-menu">
<a class="dropdown-item" href="#">Edit comment</a>
<a class="dropdown-item" title="Options" style="text-decoration: none;"
href="/deleteComment/{{$comment->id}}">Delete comment</a>
</div>
</div>
</div>
#endcan
#endforeach
#endif
#endif //****Added
</div>
</div>
Updated for delete if admin or no
/**
* Comments Controller Method Delete
*/
public function delete($id)
{
$comment = DB::table('comments')->where('id', $id):
if(!auth()->user()->admin){
$comment->where('user_id', auth()->user()->id);
}
if (!$comment->delete()) {
Session::flash('remove', "You do not have permission to delete the comment!");
} else {
Session::flash('remove', "Message removed successfully!");
}
return Redirect::back();
}
The first question can be done easily. In your destroy() function, just check comment owner:
// Check comment owner
if($comment->user_id != \Auth::id()){
return abort(401);
}
// Do logic code to delete comment.
The second question, you can check exist comment like this :
if(! $comments->isEmpty()) {
// Do logic code to show comment
}

Creating delete query in Laravel

I'm kind of new using laravel.
I created delete function but it doesnt work as I wanted to. Here are the codes in view, controller as well as routes. Could you guys tell me what was wrong in the code? Thanks
View:
<div class="btn-group">
<a class="btn btn-info" href="{{ URL::to('/delete_data_tanah/{id}') }}">
<i class="fa fa-close"
onclick="return confirm('Are you sure you want to delete this data?');">----</i>
</a>
</div>
Controller:
public function delete($id){
\App\Tbl_object::where('id_objects', '=', $id)->delete();
return redirect('/list_tanah')->with('Success', 'Data telah dihapus');
}
Routes:
Route::post('/delete_data_tanah/{id}', 'formulir_tanah#delete');
Controller:
class formulir_tanah extends Controller
{
public function index()
{
$query_tanah = \App\Tbl_object::where('id_objects_referencies', '=', '1')->get();
$query_view = \App\Tbl_view::where('id_objects_referencies', '=', '1')->get();
$data = ['page_title' => 'Kertas Kerja Penilaian Tanah', 'query_tanah' => $query_tanah, 'query_view' => $query_view];
return view('admin/list_tanah')->with($data);
}
}
Try this:
in your blade.php, change {id} to {$data->id}
<div class="btn-group">
<a class="btn btn-info" href="{{ URL::to('/delete_data_tanah/{$data->id}') }}">
<i class="fa fa-close"
onclick="return confirm('Are you sure you want to delete this data?');">----</i>
</a>
then in your controller, add the id variable:
class formulir_tanah extends Controller { public function index(){
//ambil semua data dari table categories
$query_tanah = \App\Tbl_object::where('id_objects_referencies', '=', '1')->first();
$query_view = \App\Tbl_view::where('id_objects_referencies', '=', '1') ->first();
$data = ['id' => $query_view->id, 'page_title' => 'Kertas Kerja Penilaian Tanah', 'query_tanah' => $query_tanah, 'query_view' => $query_view ];
return view('admin/list_tanah')->with($data);
}
your code doesn't work since laravel doesn't know what row to delete since there is no specific id in your return.
Apply these changes to your code:
Route::delete('/delete_data_tanah/{id}', 'formulir_tanah#delete');
and in your view you need to wrap the button in a form
<form action="{{ URL::to('/delete_data_tanah/{id}') }}" method="post">
#method('DELETE')
#csrf
<button class="btn btn-danger" type="submit">Delete</button>
</form>

Categories