Skip to content

Instantly share code, notes, and snippets.

@cwhite92
Created July 24, 2019 19:43
Show Gist options
  • Save cwhite92/8ca76de2104dd711f895b34c4f0a15f6 to your computer and use it in GitHub Desktop.
Save cwhite92/8ca76de2104dd711f895b34c4f0a15f6 to your computer and use it in GitHub Desktop.
AdvancedSharing trait
trait AdvancedSharing
{
/**
* Modifies a model query to ensure that the authed user is allowed to see this entity.
*
* @param Builder $query
* @param VisibleTo $visibleTo
* @return Builder
*/
public function scopeVisibleTo(Builder $query, VisibleTo $visibleTo): Builder
{
if ($visibleTo->isOrgToken()) {
return $query;
}
return $query->where('access_org_uuid', $visibleTo->getOrganization())
->where(function (Builder $query) use ($visibleTo) {
$query->where(function (Builder $query) use ($visibleTo) {
// visibility is public: everybody in the org can see
$query->where(function (Builder $query) {
$query->where('visibility', VisibleTo::VISIBILITY_PUBLIC);
})
// visibility is private: only the creator can see
->orWhere(function (Builder $query) use ($visibleTo) {
$query->where('visibility', VisibleTo::VISIBILITY_PRIVATE)
->where('created_by_uuid', $visibleTo->getUser())
->doesntHave('users')
->doesntHave('groups');
})
// visibility is private: and the user is in the allowed users
->orWhere(function (Builder $query) use ($visibleTo) {
$query->where('visibility', VisibleTo::VISIBILITY_USER)
->whereHas('users', function (Builder $query) use ($visibleTo) {
$query->where('uuid', $visibleTo->getUser());
});
})
// visibility is private: and the user is in the allowed groups
->orWhere(function (Builder $query) use ($visibleTo) {
$query->where('visibility', VisibleTo::VISIBILITY_GROUP)
->whereHas('groups', function (Builder $query) use ($visibleTo) {
$query->whereIn('uuid', $visibleTo->getUserGroups());
});
});
})->orWhere('created_by_uuid', $visibleTo->getUser());
});
}
/**
* The users that this entity has been shared with.
*/
public function users()
{
return $this->morphMany(Sharing::class, 'sharings')
->where('sharings.type', 'user');
}
/**
* The groups that this entity has been shared with.
*/
public function groups()
{
return $this->morphMany(Sharing::class, 'sharings')
->where('sharings.type', 'group');
}
/**
* Updates the sharing settings for this model to include the provided users and groups.
*
* @param array $users
* @param array $groups
*/
public function syncSharingSettings(array $users, array $groups)
{
$this->users()->delete();
$this->groups()->delete();
foreach ($users ?? [] as $user) {
$this->users()->create(array_merge($user, ['type' => 'user']));
}
foreach ($groups ?? [] as $group) {
$this->groups()->create(array_merge($group, ['type' => 'group']));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment