Skip to content

Instantly share code, notes, and snippets.

@jmschneider
Created September 27, 2017 13:29
Show Gist options
  • Select an option

  • Save jmschneider/91747c82c4103d4cb461940f4bfb4036 to your computer and use it in GitHub Desktop.

Select an option

Save jmschneider/91747c82c4103d4cb461940f4bfb4036 to your computer and use it in GitHub Desktop.
Laravel WithPolicy Trait
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
'App\Thread' => 'App\Policies\ThreadPolicy',
'App\Reply' => 'App\Policies\ReplyPolicy',
'App\User' => 'App\Policies\UserPolicy',
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
// Gate::before(function($user) {
// if ($user->name === 'Your User Name') return true;
// });
}
}
<?php
namespace App;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
class Reply extends Model
{
use CanBeFavorited;
use RecordsActivity;
use WithPolicy;
protected $guarded = [];
protected $with = ['owner', 'favorites'];
protected $appends = ['favoritesCount', 'isFavorited', 'can'];
protected static function boot()
{
parent::boot();
static::created(function($reply) {
$reply->thread->increment('replies_count');
});
static::deleted(function($reply) {
$reply->thread->decrement('replies_count');
});
}
public function owner()
{
return $this->belongsTo(User::class, 'user_id');
}
public function thread()
{
return $this->belongsTo(Thread::class);
}
public function wasJustPublished()
{
return $this->created_at->gt(Carbon::now()->subMinute());
}
public function mentionedUsers()
{
preg_match_all('/\@([\w\-]+)/', $this->body, $matches);
return $matches[1];
}
public function path()
{
return $this->thread->path()."#reply-{$this->id}";
}
public function setBodyAttribute($body)
{
$this->attributes['body'] = preg_replace('/\@([\w\-]+)/','<a href="/profiles/$1">$0</a>', $body);
}
}
<?php
namespace App\Policies;
use App\User;
use App\Reply;
use Illuminate\Auth\Access\HandlesAuthorization;
class ReplyPolicy
{
use HandlesAuthorization;
/**
* Determine whether the user can view the reply.
*
* @param \App\User $user
* @param \App\Reply $reply
* @return mixed
*/
public function view(User $user, Reply $reply)
{
return true;
}
/**
* Determine whether the user can create replies.
*
* @param \App\User $user
* @return mixed
*/
public function create(User $user)
{
$lastReply = $user->fresh()->lastReply;
if (! $lastReply) return true;
return ! $lastReply->wasJustPublished();
}
/**
* Determine whether the user can update the reply.
*
* @param \App\User $user
* @param \App\Reply $reply
* @return mixed
*/
public function update(User $user, Reply $reply)
{
return $reply->user_id == $user->id;
}
/**
* Determine whether the user can delete the reply.
*
* @param \App\User $user
* @param \App\Reply $reply
* @return mixed
*/
public function delete(User $user, Reply $reply)
{
//
}
/**
* Determine whether the user can favorite a reply.
*
* @param \App\User $user
* @return mixed
*/
public function favorite(User $user, Reply $reply)
{
return true;
}
}
<?php
namespace App;
use Gate;
trait WithPolicy
{
public function getCanAttribute() {
$methods = collect(get_class_methods(Gate::getPolicyFor($this)));
return $methods->mapWithKeys(function($method) {
return [$method => Gate::allows($method, $this)];
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment