making posts and discussions private (#1153)

* flagrow/byobu#11 making posts and discussions private

* tested migrations and tested setting is_private on discussion and post manually

* added phpdoc for Post and Discussion and added the casting for these attributes

* satisfying styleci

* fixes for review

* added new private discussion event and included it in the access policy

* added new private post event and included it in the access policy
This commit is contained in:
Daniël Klabbers 2017-05-27 06:49:15 +02:00 committed by Toby Zerner
parent 4c0339c30e
commit 04c4806f6f
8 changed files with 169 additions and 1 deletions

View File

@ -0,0 +1,16 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Flarum\Database\Migration;
return Migration::addColumns('discussions', [
'is_private' => ['boolean', 'default' => false]
]);

View File

@ -0,0 +1,16 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Flarum\Database\Migration;
return Migration::addColumns('posts', [
'is_private' => ['boolean', 'default' => false]
]);

View File

@ -15,6 +15,7 @@ use Carbon\Carbon;
use Flarum\Core\Discussion;
use Flarum\Core\User;
use Flarum\Event\ScopeHiddenDiscussionVisibility;
use Flarum\Event\ScopePrivateDiscussionVisibility;
use Flarum\Settings\SettingsRepositoryInterface;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Database\Eloquent\Builder;
@ -44,6 +45,7 @@ class DiscussionPolicy extends AbstractPolicy
/**
* @param SettingsRepositoryInterface $settings
* @param Gate $gate
* @param Dispatcher $events
*/
public function __construct(SettingsRepositoryInterface $settings, Gate $gate, Dispatcher $events)
{
@ -70,6 +72,15 @@ class DiscussionPolicy extends AbstractPolicy
*/
public function find(User $actor, Builder $query)
{
// Hide private discussions per default.
$query->where(function ($query) use ($actor) {
$query->where('discussions.is_private', false);
$this->events->fire(
new ScopePrivateDiscussionVisibility($query, $actor)
);
});
if ($actor->cannot('viewDiscussions')) {
$query->whereRaw('FALSE');
} elseif (! $actor->hasPermission('discussion.hide')) {

View File

@ -15,6 +15,7 @@ use Carbon\Carbon;
use Flarum\Core\Post;
use Flarum\Core\User;
use Flarum\Event\ScopePostVisibility;
use Flarum\Event\ScopePrivatePostVisibility;
use Flarum\Settings\SettingsRepositoryInterface;
use Illuminate\Contracts\Events\Dispatcher;
@ -29,13 +30,18 @@ class PostPolicy extends AbstractPolicy
* @var SettingsRepositoryInterface
*/
protected $settings;
/**
* @var Dispatcher
*/
protected $events;
/**
* @param SettingsRepositoryInterface $settings
*/
public function __construct(SettingsRepositoryInterface $settings)
public function __construct(SettingsRepositoryInterface $settings, Dispatcher $events)
{
$this->settings = $settings;
$this->events = $events;
}
/**
@ -66,6 +72,15 @@ class PostPolicy extends AbstractPolicy
*/
public function scopePostVisibility(ScopePostVisibility $event)
{
// Hide private posts per default.
$event->query->where(function ($query) use ($event) {
$query->where('posts.is_private', false);
$this->events->fire(
new ScopePrivatePostVisibility($event->discussion, $query, $event->actor)
);
});
// When fetching a discussion's posts: if the user doesn't have permission
// to moderate the discussion, then they can't see posts that have been
// hidden by someone other than themself.

View File

@ -49,6 +49,7 @@ use Flarum\Util\Str;
* @property Post|null $lastPost
* @property User|null $lastUser
* @property \Illuminate\Database\Eloquent\Collection $readers
* @property bool $is_private
*/
class Discussion extends AbstractModel
{
@ -72,6 +73,15 @@ class Discussion extends AbstractModel
*/
protected $dates = ['start_time', 'last_time', 'hide_time'];
/**
* Casts properties to a specific type.
*
* @var array
*/
protected $casts = [
'is_private' => 'boolean'
];
/**
* The user for which the state relationship should be loaded.
*

View File

@ -35,6 +35,7 @@ use Illuminate\Database\Eloquent\Builder;
* @property User|null $editUser
* @property User|null $hideUser
* @property string $ip_address
* @property bool $is_private
*/
class Post extends AbstractModel
{
@ -51,6 +52,15 @@ class Post extends AbstractModel
*/
protected $dates = ['time', 'edit_time', 'hide_time'];
/**
* Casts properties to a specific type.
*
* @var array
*/
protected $casts = [
'is_private' => 'boolean'
];
/**
* A map of post types, as specified in the `type` column, to their
* classes.

View File

@ -0,0 +1,41 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Event;
use Flarum\Core\User;
use Illuminate\Database\Eloquent\Builder;
/**
* The `ScopePrivateDiscussionVisibility` event.
*/
class ScopePrivateDiscussionVisibility
{
/**
* @var Builder
*/
public $query;
/**
* @var User
*/
public $actor;
/**
* @param Builder $query
* @param User $actor
*/
public function __construct(Builder $query, User $actor)
{
$this->query = $query;
$this->actor = $actor;
}
}

View File

@ -0,0 +1,49 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Event;
use Flarum\Core\Discussion;
use Flarum\Core\User;
use Illuminate\Database\Eloquent\Builder;
/**
* The `ScopePrivatePostVisibility` event.
*/
class ScopePrivatePostVisibility
{
/**
* @var Discussion
*/
public $discussion;
/**
* @var Builder
*/
public $query;
/**
* @var User
*/
public $actor;
/**
* @param Discussion $discussion
* @param Builder $query
* @param User $actor
*/
public function __construct(Discussion $discussion, Builder $query, User $actor)
{
$this->discussion = $discussion;
$this->query = $query;
$this->actor = $actor;
}
}