Allow author to delete discussion if there are no replies

Also disallow the first post in a discussion to be deleted or hidden
(thus preventing discussions with zero posts)

closes flarum/core#90 closes flarum/core#92
This commit is contained in:
Toby Zerner
2015-06-23 10:34:33 +09:30
parent 3a7efe202e
commit 64e5d50533
8 changed files with 80 additions and 30 deletions

View File

@ -37,11 +37,14 @@ export default function(app) {
items.add('restore', ActionButton.component({ icon: 'reply', label: 'Restore', onclick: restoreAction.bind(this) })); items.add('restore', ActionButton.component({ icon: 'reply', label: 'Restore', onclick: restoreAction.bind(this) }));
} else { } else {
items.add('edit', ActionButton.component({ icon: 'pencil', label: 'Edit', onclick: editAction.bind(this) })); items.add('edit', ActionButton.component({ icon: 'pencil', label: 'Edit', onclick: editAction.bind(this) }));
if (this.number() != 1) {
items.add('hide', ActionButton.component({ icon: 'times', label: 'Delete', onclick: hideAction.bind(this) })); items.add('hide', ActionButton.component({ icon: 'times', label: 'Delete', onclick: hideAction.bind(this) }));
} }
} }
}
if ((this.contentType() !== 'comment' || this.isHidden()) && this.canDelete()) { if ((this.contentType() !== 'comment' || this.isHidden()) && this.canDelete() && this.number() != 1) {
items.add('delete', ActionButton.component({ icon: 'times', label: 'Delete', onclick: deleteAction.bind(this) })); items.add('delete', ActionButton.component({ icon: 'times', label: 'Delete', onclick: deleteAction.bind(this) }));
} }

View File

@ -19,6 +19,7 @@ class CreateDiscussionsTable extends Migration
$table->increments('id'); $table->increments('id');
$table->string('title', 200); $table->string('title', 200);
$table->integer('comments_count')->unsigned()->default(0); $table->integer('comments_count')->unsigned()->default(0);
$table->integer('participants_count')->unsigned()->default(0);
$table->integer('number_index')->unsigned()->default(0); $table->integer('number_index')->unsigned()->default(0);
$table->dateTime('start_time'); $table->dateTime('start_time');

View File

@ -17,6 +17,7 @@ class DiscussionSerializer extends DiscussionBasicSerializer
$attributes += [ $attributes += [
'commentsCount' => (int) $discussion->comments_count, 'commentsCount' => (int) $discussion->comments_count,
'participantsCount' => (int) $discussion->participants_count,
'startTime' => $discussion->start_time->toRFC3339String(), 'startTime' => $discussion->start_time->toRFC3339String(),
'lastTime' => $discussion->last_time ? $discussion->last_time->toRFC3339String() : null, 'lastTime' => $discussion->last_time ? $discussion->last_time->toRFC3339String() : null,
'lastPostNumber' => $discussion->last_post_number, 'lastPostNumber' => $discussion->last_post_number,

View File

@ -3,6 +3,7 @@
use Flarum\Core\Repositories\PostRepositoryInterface as PostRepository; use Flarum\Core\Repositories\PostRepositoryInterface as PostRepository;
use Flarum\Core\Events\PostWillBeSaved; use Flarum\Core\Events\PostWillBeSaved;
use Flarum\Core\Support\DispatchesEvents; use Flarum\Core\Support\DispatchesEvents;
use Flarum\Core\Models\CommentPost;
class EditPostCommandHandler class EditPostCommandHandler
{ {
@ -22,6 +23,7 @@ class EditPostCommandHandler
$post->assertCan($user, 'edit'); $post->assertCan($user, 'edit');
if ($post instanceof CommentPost) {
if (isset($command->data['content'])) { if (isset($command->data['content'])) {
$post->revise($command->data['content'], $user); $post->revise($command->data['content'], $user);
} }
@ -33,6 +35,7 @@ class EditPostCommandHandler
$post->restore($user); $post->restore($user);
} }
} }
}
event(new PostWillBeSaved($post, $command)); event(new PostWillBeSaved($post, $command));

View File

@ -28,6 +28,7 @@ class DiscussionMetadataUpdater
$discussion->comments_count++; $discussion->comments_count++;
$discussion->setLastPost($event->post); $discussion->setLastPost($event->post);
$discussion->refreshParticipantsCount();
$discussion->save(); $discussion->save();
} }
@ -46,6 +47,7 @@ class DiscussionMetadataUpdater
$discussion = $event->post->discussion; $discussion = $event->post->discussion;
$discussion->refreshCommentsCount(); $discussion->refreshCommentsCount();
$discussion->refreshParticipantsCount();
$discussion->refreshLastPost(); $discussion->refreshLastPost();
$discussion->save(); $discussion->save();
} }
@ -56,6 +58,7 @@ class DiscussionMetadataUpdater
if ($discussion->exists) { if ($discussion->exists) {
$discussion->refreshCommentsCount(); $discussion->refreshCommentsCount();
$discussion->refreshParticipantsCount();
if ($discussion->last_post_id == $post->id) { if ($discussion->last_post_id == $post->id) {
$discussion->refreshLastPost(); $discussion->refreshLastPost();

View File

@ -5,6 +5,7 @@ use Flarum\Core\Events\PostWasPosted;
use Flarum\Core\Events\PostWasRevised; use Flarum\Core\Events\PostWasRevised;
use Flarum\Core\Events\PostWasHidden; use Flarum\Core\Events\PostWasHidden;
use Flarum\Core\Events\PostWasRestored; use Flarum\Core\Events\PostWasRestored;
use Flarum\Core\Exceptions\ValidationFailureException;
class CommentPost extends Post class CommentPost extends Post
{ {
@ -75,6 +76,10 @@ class CommentPost extends Post
*/ */
public function hide($user) public function hide($user)
{ {
if ($this->number == 1) {
throw new ValidationFailureException;
}
if (! $this->hide_time) { if (! $this->hide_time) {
$this->hide_time = time(); $this->hide_time = time();
$this->hide_user_id = $user->id; $this->hide_user_id = $user->id;
@ -93,6 +98,10 @@ class CommentPost extends Post
*/ */
public function restore($user) public function restore($user)
{ {
if ($this->number == 1) {
throw new ValidationFailureException;
}
if ($this->hide_time !== null) { if ($this->hide_time !== null) {
$this->hide_time = null; $this->hide_time = null;
$this->hide_user_id = null; $this->hide_user_id = null;

View File

@ -23,6 +23,7 @@ class Discussion extends Model
'title' => 'required', 'title' => 'required',
'start_time' => 'required|date', 'start_time' => 'required|date',
'comments_count' => 'integer', 'comments_count' => 'integer',
'participants_count' => 'integer',
'start_user_id' => 'integer', 'start_user_id' => 'integer',
'start_post_id' => 'integer', 'start_post_id' => 'integer',
'last_time' => 'date', 'last_time' => 'date',
@ -175,6 +176,18 @@ class Discussion extends Model
return $this; return $this;
} }
/**
* Refresh the discussion's participants count.
*
* @return $this
*/
public function refreshParticipantsCount()
{
$this->participants_count = $this->participants()->count('users.id');
return $this;
}
/** /**
* Specify that a post was added to this discussion during this request * Specify that a post was added to this discussion during this request
* for later retrieval. * for later retrieval.
@ -255,6 +268,16 @@ class Discussion extends Model
return $this->posts()->where('type', 'comment')->whereNull('hide_time'); return $this->posts()->where('type', 'comment')->whereNull('hide_time');
} }
/**
* Define the relationship with the discussion's participants.
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function participants()
{
return User::join('posts', 'posts.user_id', '=', 'users.id')->where('posts.discussion_id', $this->id)->select('users.*')->distinct();
}
/** /**
* Define the relationship with the discussion's first post. * Define the relationship with the discussion's first post.
* *

View File

@ -2,6 +2,7 @@
use Flarum\Core\Events\PostWasDeleted; use Flarum\Core\Events\PostWasDeleted;
use Flarum\Core\Support\Locked; use Flarum\Core\Support\Locked;
use Flarum\Core\Exceptions\ValidationFailureException;
class Post extends Model class Post extends Model
{ {
@ -74,6 +75,12 @@ class Post extends Model
$post->discussion->save(); $post->discussion->save();
}); });
static::deleting(function ($post) {
if ($post->number == 1) {
throw new ValidationFailureException;
}
});
static::deleted(function ($post) { static::deleted(function ($post) {
$post->raise(new PostWasDeleted($post)); $post->raise(new PostWasDeleted($post));
}); });