How do I implement a scope where in the user will claim a reward on a specific level and once they claim their rewards, the reward field will no longer display the reward that they have claimed. So for example:
The user is on level 20, on his reward panel, there are 3 available rewards to be claimed, level 10, 15 and 20. So if the user claimed the level 10 reward, it will no longer display on the panel except for level 15 and 20 rewards.
Here is the code for the blade:
#foreach(App\LevelRewards::getRewards()->get() as $rewards)
#if(Auth::user()->level >= $rewards->level_required || Auth::user()->level == $rewards->level_required)
#if(App\ClaimReward::claimLevel()->get())
<div class="col-lg-2 col-md-3 col-sm-6 col-xs-6" style="margin: 5px 0px;">
<div class="hovereffect">
<a href="#" class="d-block mb-4 h-100">
<input type ="hidden" name="id" value="{{$rewards->id}}"/>
<img class="img-responsive" src="{{asset('rewards_img/'.$rewards->picture)}}" alt="">
</a>
<div class="overlay">
<h2 style="font-size: 14px;">{{$rewards->details}}</h2>
#if($rewards->type == 'physical')
<button type="button" class="btn btn-success btn-sm" data-toggle="modal" data-target="#claimPhysical" data-details="{{$rewards->details}}" data-id="{{$rewards->id}}" data-level="{{$rewards->level_required}}" data-physical="{{$rewards->item_name}}">
CLAIM
</button>
#else
<button type="button" class="btn btn-success btn-sm" data-toggle="modal" data-target="#claimDigital" data-id="{{$rewards->id}}" data-level="{{$rewards->level_required}}" data-physical="{{$rewards->item_name}}">
CLAIM
</button>
#endif
</div>
<div style="background: #2d2d2d; padding: 9px;">
<span class="credits_top">Required Level: <span>{{$rewards->level_required}}</span></span>
<p>{{$rewards->item_name}}</p>
</div>
</div>
#endif
#endif
#endforeach
And this is the code for the model ClaimReward model:
public function scopeClaimLevel2($query)
{
return $query->join('level_rewards','level_rewards.id','=','claim_rewards.reward_id')->select('level_rewards.*');
}
Any links and source of information regarding this question will be highly appreciated. Thank you.
Edit: I tried;
public function scopeClaimLevel($query)
{
return $query->join('claim_rewards','claim_rewards.reward_id','=','level_rewards.id')->select('level_rewards.*');
}
public function scopeGetRewards($query)
{
return $query
->join('claim_rewards','claim_rewards.reward_id','=','level_rewards.id')
->whereDoesntHave('claimLevel', function (Builder $query) {
$query->where('claim_rewards.status', '=', '0');
})
->select('level_rewards.*');
}
But it says
Call to undefined method Illuminate\Database\Query\Builder::getRelated()'
add another table that will hold rewards thats user already claimed,
and in the foreach check if this reward id exists in this user claimed rewards,
if not so show it and if yes so skip it.
the table will hold 2 fields:
1) user_id
2) rewards_id
regarding the comments above,
and after your edit to what you tried,
looks like the order of the query is wrong... put whereDoesntHave before the select,
and change to implementation of it as wrote in Laravel documentation example.
try this:
public function scopeClaimLevel2($query)
{
return $query
->join('claim_rewards','claim_rewards.reward_id','=','level_rewards.id')
->whereDoesntHave('claim_rewards', function (Builder $query) {
$query->where('status', '=', '0');
})
->select('level_rewards.*');
}
edit:
try to change the join, as wrote here: https://laravel.com/docs/5.4/queries#joins
build the join and in it's function set how to join and where status=0
return $query
->join('claim_rewards', function ($join) {
$join->on('claim_rewards.reward_id', '=', 'level_rewards.id')->where('status', '=', '0');
})
->select('level_rewards.*');
Related
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
}
I have three tables, the activity, the category and the activity_categories table.Each activity may belong to many categories therefore the category_id and activity_id are saved in activity_categories.
I am trying to get only one category per product, because to display use one category image per activity but on search I have to show them in all belonging categories.I have created my models as follow:
class Activity extends Model
{
protected $table = "activities";
public function category()
{
return $this->belongsToMany('App\Category','activity_categories');
}
}
//Controller
public function userActivities()
{
$user_id = Auth::user()->id;
$activities = Activity::all()->where('user_id', $user_id);
return view('user_profile.activities', compact( 'activities' ));
}
//View
#foreach($activities as $activity)
<div class="col-lg-4 col-md-4 col-xs-12" id="profile-card">
<div class="widget-head-color-box navy-bg p-lg text-center"
style="background-image: url('{{asset('/images/categories/'.$activity->category->first()->image)}}')">
<img src="/storage/profile/{{Auth::user()->image}}" class="img-small-profile" alt="profile">
<button id="heart-favorite" class="btn btn-danger btn-circle btn-outline"
type="button"><i
class="fa fa-heart"></i></button>
</div>
<div class="widget-text-box">
<h3 class="media-heading m-t-md"><b>{{$activity->title}}</b></h3>
<h5 class="media-heading m-t-md" style="text-align: justify">
{{$activity->description}}<br><br>
</h5>
</div>
</div>
#endforeach
When i use dd($activity->category->first()->image) it shows the data but when i place the same in the view id shows the error "Trying to get property of non-object"
I would like to ask if it is possible to validate a href element in laravel.
For example, I'm having a bunch of people responses in my guest book and each user is able do delete his posts. I'm deleting it like this:
<div class="col-lg-2">
<ul class="list-unstyled trash">
<li>
<a href="/responses/{{$response->id}}">
<span onclick="alertDialog()" class="glyphicon glyphicon-trash"></span></a></li>
<li><button type="button" class="btn btn-danger btn-sm" data-toggle="modal" data-target="#{{$response->id}}">Edit</button></li>
</ul>
</div>
Unfortunately, every single user can change "/responses/{{$response->id}}"> id via browser developer tools and delete other user's responses. Is there any possible solutions to prevent this issue?
Just check the logged user before rendering that html section:
<div class="col-lg-2">
<!-- assuming post is your variable and user is a property which references the user who created the record -->
#if($post->user == Auth::id())
<ul class="list-unstyled trash">
<li>
<a href="/responses/{{$response->id}}">
<span onclick="alertDialog()" class="glyphicon glyphicon-trash"></span></a></li>
<li><button type="button" class="btn btn-danger btn-sm" data-toggle="modal" data-target="#{{$response->id}}">Edit</button></li>
</ul>
#endif
</div>
This way only the user who owns the post will be able to see the button in the html.
You need to use policies to check if the user that tries to delete a record is its owner:
public function delete(User $user, Model $model)
{
return $user->id === $model->user_id;
}
Or you can do it manually in a controller method:
if (auth()->id() === $model->user_id) {
// Delete the record
}
You should make /responses/{{$response->id}} a POST route and verify that the passed id matches with the authenticated users id. ( Auth::user()->id;)
I ended up checking like this in my destroy(id) method:
$count = Comment::where(['response_id' => $id])->count();
if (($responses->where('id',$id)->value('guests_email') == Cookie::get('email') && ($count==0)) || (Auth::check()))
It's me again but now I need some more help from you, I have some version of shopping cart and the whole idea is when I click on the product button the database to be update with the informations which user(id) has order that product(id). First I make orders table with informations(id, product_name, price), other table is users table (id, user_name) and the final table user_order table(id, user_id, order_id);
After that I make two models, one is the Orders model for the products and the second one is the User model. The relationship that I want to make is between this two models.
User model function:
public function orders(){
return $this->belongsToMany('App\Orders', 'user_order', 'user_id', 'order_id');
// return $this->belongsToMany('App\Orders');
}
Orders model function:
public function users(){
return $this->belongsToMany('App\User', 'user_order', 'order_id', 'user_id');
//return $this->belongsToMany('App\User');
}
This is the main html where I show all products with the submit button:
<div class="row">
#foreach($orders as $order)
<div class="col-sm-4 col-lg-4 col-md-4">
<div class="thumbnail">
<img src="http://placehold.it/320x150" alt="">
<div class="caption">
<h4 class="pull-right">{{ $order->cena }}</h4>
<h4>{{ $order->order_name }}
</h4>
<p>See more snippets like this online store item at <a target="_blank" href="http://www.bootsnipp.com">Bootsnipp - http://bootsnipp.com</a>.</p>
</div>
<div class="ratings">
<p class="pull-right">15 reviews</p>
<p>
<span class="glyphicon glyphicon-star"></span>
<span class="glyphicon glyphicon-star"></span>
<span class="glyphicon glyphicon-star"></span>
<span class="glyphicon glyphicon-star"></span>
<span class="glyphicon glyphicon-star"></span>
</p>
</div>
<div class="btn-group center">
Order this product!
</div>
<br>
</div>
</div>
#endforeach
Controller function:
public function makeOrder(Request $request, $id){
$user = User::where('email', $request['email'])->first();
$findorder = Orders::find($id);
//$user->orders()->detach();
$user->orders()->attach(Orders::where('id', $findorder))->first();
return redirect()->back();
}
And the route:
Route::get('/add-to-database/{id}',[
'uses' => 'AppController#makeOrder',
'as' => 'product.makeOrder'
]);
The whole idea is how to make function after submiting the button the table user_order to be updated with the id of the user, and id of the product.
Any help?
Your makeOrder() should be as:
public function makeOrder(Request $request, $id) {
$user = User::where('email', $request->get('email'))->first();
// this is to make sure that order is available in database
$order = Orders::findOrFail($id);
$user->orders()->attach($order->id);
return redirect()->back();
}
In my application, I've always been able to pass data to any view as one would normally do using view('myView', compact('data'));. As of today, any view I try to render this way times out. I'm getting the error Maximum execution time of 120 seconds exceeded in Whoops!. I tried increasing php.ini and httpd.conf timeout times but no cigar. It's really odd and it doesn't make sense to me because I've always been able to render my views almost instantly, even when retrieving 15k+ records from the database and passing them to the view like I've always done.
My controller:
use App\Product;
use Illuminate\Support\Facades\Session;
class HomeController extends Controller {
public function __construct()
{
$this->middleware('auth');
}
public function index()
{
//the controller is normally like this
//$products = Product::paginate(16);
//return view('home', compact('products'));
//I'm testing with these 2 lines below but no cigar.
$product = Product::wherePid(303)->first();
return view('test', compact('product'));
}
}
The test view I created:
#extends('app')
#section('content')
{{ $product->name }}
#stop
My application view:
#extends('app')
<pre>{{ var_dump(Session::all())}}</pre>
#section('content')
<div class="row">
#foreach($products as $product)
<div class="col-xs-6 col-sm-3 col-lg-3 col-md-3">
<?php
if($product->img[7] == 'm' || $product->img[7] == 'M') echo "<div class='continenteIcon'></div>";
else echo "<div class='jumboIcon'></div>";
?>
<div class="thumbnail">
<a href="products/{{$product->pid}}"><img src="{{$product->img}}" title="
<?php
if($product->dispname != '') echo $product->dispname;
else echo $product->name;
?> ">
</a>
<div class="caption">
<h4>
<a style="text-decoration:none;" class="wordwrap" title="
<?php
if($product->dispname != '')
echo $product->dispname;
else echo $product->name;
?>" href="products/{{$product->pid}}">
<?php
if($product->dispname != '')
echo $product->dispname;
else echo $product->name;?>
</a>
</h4>
<p>{{$product->brand}}</p>
<span class="pull-right price">€{{$product->price}}</span>
<br/>
<span class="pull-right ppk">€{{round($product->pricekilo, 2)}} Kg, L ou Und</span>
</div>
<div class="ratings">
<p class="pull-right"> {{-- # review--}}</p>
<p>
<form method="post" action="add/{{$product->pid}}">
<input type="hidden" name="_token" value="{{{ csrf_token() }}}" />
<button title="Adicionar ao carrinho" type="submit" class="btn btn-success">
<i class="fa fa-shopping-cart"></i>
</button>
</form>
<form method="post" action="products/related/{{$product->pid}}">
<input type="hidden" name="_token" value="{{{ csrf_token() }}}" />
<button title="Ver artigos semelhantes" style="position:relative; bottom:35px;" type="submit" class="btn btn-info pull-right">
<i class="fa fa-search"></i>
</button>
</form>
</p>
</div>
</div>
</div>
#endforeach
</div>
<div class="row">
{!! $products->render() !!}
</div>
<div class="row">
<div class="pull-right">
* Preço por unidade, Litro ou Kilograma
</div>
#stop
#section('scripts')
#stop
The problem doesn't only happen in this view, but every single time I try to fecth someting from the database and pass it to the view to render. I keep getting timeouts and I can't seem to fix it no matter what I do.
I am clueless why this is happening. It seems like it started out of the blue. I have no Idea what could be causing this issue.
Any help?
P.S.: I'm using Wamp.
EDIT: I forgot to add something that might be important:
Everything is up and running in Wamp. If I dd() out the query result and do not render the view
$products = Product::paginate(16);
dd($products);
//return view('home', compact('products'));
this is fast, as it always used to be. And by fast I mean it takes less than 1 second to retrieve everything I need. But if I render the view with
return view('home', compact('products'));
everything just stalls and I get a 500 (I checked with Fiddler2 and after the page stops loading, the request status is 500)
It seems like you may be requesting too many records which may be using too much of your RAM. I would use the chunk command to help you with managing the amount you're requesting.
For example:
User::chunk(200, function($users)
{
foreach ($users as $user)
{
//
}
});
First check logs.
Next try to dd($product)
Next if you try to render view with last 2 lines (getting first record) remove pagination from template.
Clean template to minimum e.g.
#extends('app')
#section('content')
<div class="row">
#foreach($products as $product)
#endforeach
</div>
#stop
I just sorted it out. The issue was in the following block of code in app.blade.php.
$size = Session::get('size');
...
<input type="text" value="'.Session::get($item).'">
...
I was messing around with data from an existing session and everything was working fine. I assumed I was doing it right. I wasn't. Not by a chance :)
Assumption is the mother of all screw ups.
Surrounded the whole block with if(Session::has('size') and everything is blazing fast and running smoothly as usual.
Thanks #Pyton for pointing me out into the right direction and thanks everyone for your contribution.