From 36787bcf456843041da33c80c0c5456298e144a8 Mon Sep 17 00:00:00 2001 From: Toby Zerner Date: Thu, 12 Feb 2015 14:35:24 +1030 Subject: [PATCH] Implement hard deletion and rename soft delete to hide --- .../app/components/discussion/post-comment.js | 20 ++++++++++++------- .../components/discussion/stream-content.js | 4 ++++ ember/app/controllers/discussion.js | 4 ++++ ember/app/models/post-stream.js | 6 ++++++ ember/app/models/post.js | 4 ++-- ember/app/serializers/post.js | 16 +++++++++++++++ ember/app/styles/flarum/discussion.less | 7 +++++-- .../components/discussion/stream-content.hbs | 2 +- ember/app/templates/discussion.hbs | 3 ++- src/Flarum/Api/Actions/Discussions/Show.php | 4 ++-- src/Flarum/Api/Actions/Posts/Index.php | 4 ++-- src/Flarum/Api/Actions/Posts/Show.php | 2 +- src/Flarum/Api/Serializers/PostSerializer.php | 20 +++++++++---------- src/Flarum/Core/Discussions/Discussion.php | 2 +- src/Flarum/Core/Posts/CommentPost.php | 12 +++++------ src/Flarum/Core/Posts/Post.php | 18 ++++++++--------- .../Support/Seeders/DiscussionTableSeeder.php | 8 ++++---- .../2014_01_14_231350_create_posts_table.php | 4 ++-- 18 files changed, 90 insertions(+), 50 deletions(-) create mode 100644 ember/app/serializers/post.js diff --git a/ember/app/components/discussion/post-comment.js b/ember/app/components/discussion/post-comment.js index deea9dac8..956b99523 100644 --- a/ember/app/components/discussion/post-comment.js +++ b/ember/app/components/discussion/post-comment.js @@ -21,8 +21,8 @@ export default Ember.Component.extend(FadeIn, HasItemLists, UseComposer, { tagName: 'article', classNames: ['post', 'post-comment'], classNameBindings: [ - 'post.isHidden:deleted', - 'post.isEdited:edited', + 'post.isHidden:is-hidden', + 'post.isEdited:is-edited', 'revealContent:reveal-content' ], itemLists: ['controls', 'header', 'footer'], @@ -35,7 +35,7 @@ export default Ember.Component.extend(FadeIn, HasItemLists, UseComposer, { populateControls: function(items) { if (this.get('post.isHidden')) { this.addActionItem(items, 'restore', 'Restore', 'reply', 'post.canEdit'); - this.addActionItem(items, 'delete', 'Delete', 'times', 'post.canDelete'); + this.addActionItem(items, 'delete', 'Delete Forever', 'times', 'post.canDelete'); } else { this.addActionItem(items, 'edit', 'Edit', 'pencil', 'post.canEdit'); this.addActionItem(items, 'hide', 'Delete', 'times', 'post.canEdit'); @@ -88,8 +88,8 @@ export default Ember.Component.extend(FadeIn, HasItemLists, UseComposer, { var post = this.get('post'); post.setProperties({ isHidden: true, - deleteTime: new Date, - deleteUser: this.get('session.user') + hideTime: new Date, + hideUser: this.get('session.user') }); post.save(); }, @@ -98,10 +98,16 @@ export default Ember.Component.extend(FadeIn, HasItemLists, UseComposer, { var post = this.get('post'); post.setProperties({ isHidden: false, - deleteTime: null, - deleteUser: null + hideTime: null, + hideUser: null }); post.save(); + }, + + delete: function() { + var post = this.get('post'); + post.destroyRecord(); + this.sendAction('postRemoved', post); } } }); diff --git a/ember/app/components/discussion/stream-content.js b/ember/app/components/discussion/stream-content.js index 6218fe458..8f12fd5d4 100644 --- a/ember/app/components/discussion/stream-content.js +++ b/ember/app/components/discussion/stream-content.js @@ -288,6 +288,10 @@ export default Ember.Component.extend({ loadRange: function(start, end, backwards) { this.get('stream').loadRange(start, end, backwards); + }, + + postRemoved: function(post) { + this.sendAction('postRemoved', post); } } }); diff --git a/ember/app/controllers/discussion.js b/ember/app/controllers/discussion.js index c9a53753a..616f855f7 100644 --- a/ember/app/controllers/discussion.js +++ b/ember/app/controllers/discussion.js @@ -98,6 +98,10 @@ export default Ember.Controller.extend(Ember.Evented, UseComposerMixin, { discussion.set('readNumber', endNumber); discussion.save(); } + }, + + postRemoved: function(post) { + this.get('stream').removePost(post); } } }); diff --git a/ember/app/models/post-stream.js b/ember/app/models/post-stream.js index 154e58c71..fd088e0d8 100644 --- a/ember/app/models/post-stream.js +++ b/ember/app/models/post-stream.js @@ -168,6 +168,12 @@ export default Ember.ArrayProxy.extend(Ember.Evented, { this.get('content').pushObject(this.makeItem(index, index, post)); }, + removePost: function(post) { + this.get('ids').removeObject(post.get('id')); + var content = this.get('content'); + content.removeObject(content.findBy('content', post)); + }, + makeItem: function(indexStart, indexEnd, post) { var item = Ember.Object.create({ indexStart: indexStart, diff --git a/ember/app/models/post.js b/ember/app/models/post.js index bc0624ca2..09e85d536 100644 --- a/ember/app/models/post.js +++ b/ember/app/models/post.js @@ -15,9 +15,9 @@ export default DS.Model.extend({ editUser: DS.belongsTo('user'), isEdited: Ember.computed.notEmpty('editTime'), + hideTime: DS.attr('date'), + hideUser: DS.belongsTo('user'), isHidden: DS.attr('boolean'), - deleteTime: DS.attr('date'), - deleteUser: DS.belongsTo('user'), canEdit: DS.attr('boolean'), canDelete: DS.attr('boolean') diff --git a/ember/app/serializers/post.js b/ember/app/serializers/post.js new file mode 100644 index 000000000..020038ff9 --- /dev/null +++ b/ember/app/serializers/post.js @@ -0,0 +1,16 @@ +import ApplicationSerializer from 'flarum/serializers/application'; + +export default ApplicationSerializer.extend({ + attrs: { + number: {serialize: false}, + time: {serialize: false}, + type: {serialize: false}, + contentHtml: {serialize: false}, + editTime: {serialize: false}, + editUser: {serialize: false}, + hideTime: {serialize: false}, + hideUser: {serialize: false}, + canEdit: {serialize: false}, + canDelete: {serialize: false} + } +}); diff --git a/ember/app/styles/flarum/discussion.less b/ember/app/styles/flarum/discussion.less index 474a64950..82a13f621 100644 --- a/ember/app/styles/flarum/discussion.less +++ b/ember/app/styles/flarum/discussion.less @@ -103,7 +103,6 @@ float: right; margin: -2px 0 0 10px; visibility: hidden; - z-index: 1; } &:hover .contextual-controls, & .contextual-controls.open { visibility: visible; @@ -159,7 +158,7 @@ text-align: center; font-size: 22px; } -.post.deleted { +.post.is-hidden { & .post-user, & .post-header > ul, & .post-header > ul a:not(.btn) { color: @fl-body-muted-more-color; } @@ -173,6 +172,10 @@ opacity: 0.5; } } + & .btn-more { + background: #eee; + color: @fl-body-muted-more-color; + } } .post-meta { width: 400px; diff --git a/ember/app/templates/components/discussion/stream-content.hbs b/ember/app/templates/components/discussion/stream-content.hbs index e553c07ec..2a7431cfa 100644 --- a/ember/app/templates/components/discussion/stream-content.hbs +++ b/ember/app/templates/components/discussion/stream-content.hbs @@ -1,7 +1,7 @@ {{#each item in stream}} {{#discussion/stream-item item=item stream=stream loadRange="loadRange"}} {{#if item.content}} - {{component item.component content=item.content}} + {{component item.component content=item.content postRemoved="postRemoved"}} {{/if}} {{/discussion/stream-item}} {{/each}} diff --git a/ember/app/templates/discussion.hbs b/ember/app/templates/discussion.hbs index a3f5c7eb1..e8707e44e 100644 --- a/ember/app/templates/discussion.hbs +++ b/ember/app/templates/discussion.hbs @@ -13,5 +13,6 @@ viewName="streamContent" stream=stream class="discussion-posts posts" - positionChanged="positionChanged"}} + positionChanged="positionChanged" + postRemoved="postRemoved"}} diff --git a/src/Flarum/Api/Actions/Discussions/Show.php b/src/Flarum/Api/Actions/Discussions/Show.php index a5ad5e6d0..1c0d98e0b 100644 --- a/src/Flarum/Api/Actions/Discussions/Show.php +++ b/src/Flarum/Api/Actions/Discussions/Show.php @@ -12,7 +12,7 @@ class Show extends Base /** * The post repository. - * + * * @var PostRepository */ protected $posts; @@ -39,7 +39,7 @@ class Show extends Base $discussion = Discussion::whereCanView()->findOrFail($this->param('id')); if (in_array('posts', $include)) { - $relations = ['user', 'user.groups', 'editUser', 'deleteUser']; + $relations = ['user', 'user.groups', 'editUser', 'hideUser']; $discussion->posts = $this->getPostsForDiscussion($this->posts, $discussion->id, $relations); $include = array_merge($include, array_map(function ($relation) { diff --git a/src/Flarum/Api/Actions/Posts/Index.php b/src/Flarum/Api/Actions/Posts/Index.php index 8385fe458..7bd1af190 100644 --- a/src/Flarum/Api/Actions/Posts/Index.php +++ b/src/Flarum/Api/Actions/Posts/Index.php @@ -12,7 +12,7 @@ class Index extends Base /** * The post repository. - * + * * @var PostRepository */ protected $posts; @@ -35,7 +35,7 @@ class Index extends Base protected function run() { $postIds = (array) $this->input('ids'); - $include = ['user', 'user.groups', 'editUser', 'deleteUser']; + $include = ['user', 'user.groups', 'editUser', 'hideUser']; if (count($postIds)) { $posts = $this->posts->findMany($postIds, $include); diff --git a/src/Flarum/Api/Actions/Posts/Show.php b/src/Flarum/Api/Actions/Posts/Show.php index 3bd2df188..b5eb05348 100644 --- a/src/Flarum/Api/Actions/Posts/Show.php +++ b/src/Flarum/Api/Actions/Posts/Show.php @@ -23,7 +23,7 @@ class Show extends Base } $include = $this->included(['discussion', 'replyTo']); - $relations = array_merge(['user', 'editUser', 'deleteUser'], $include); + $relations = array_merge(['user', 'editUser', 'hideUser'], $include); $posts->load($relations); // Finally, we can set up the post serializer and use it to create diff --git a/src/Flarum/Api/Serializers/PostSerializer.php b/src/Flarum/Api/Serializers/PostSerializer.php index 16cadfe8c..ece2385ea 100644 --- a/src/Flarum/Api/Serializers/PostSerializer.php +++ b/src/Flarum/Api/Serializers/PostSerializer.php @@ -21,7 +21,7 @@ class PostSerializer extends PostBasicSerializer * Default relations to include. * @var array */ - protected $include = ['user', 'editUser', 'deleteUser']; + protected $include = ['user', 'editUser', 'hideUser']; /** * Serialize attributes of a Post model for JSON output. @@ -51,9 +51,9 @@ class PostSerializer extends PostBasicSerializer $attributes['editTime'] = $post->edit_time->toRFC3339String(); } - if ($post->delete_time) { + if ($post->hide_time) { $attributes['isHidden'] = true; - $attributes['deleteTime'] = $post->delete_time->toRFC3339String(); + $attributes['hideTime'] = $post->hide_time->toRFC3339String(); } $attributes += [ @@ -66,7 +66,7 @@ class PostSerializer extends PostBasicSerializer /** * Get a resource containing a post's user. - * + * * @param Post $post * @param array $relations * @return Tobscure\JsonApi\Resource @@ -78,7 +78,7 @@ class PostSerializer extends PostBasicSerializer /** * Get a resource containing a post's discussion. - * + * * @param Post $post * @param array $relations * @return Tobscure\JsonApi\Resource @@ -90,7 +90,7 @@ class PostSerializer extends PostBasicSerializer /** * Get a resource containing a post's edit user. - * + * * @param Post $post * @param array $relations * @return Tobscure\JsonApi\Resource @@ -101,14 +101,14 @@ class PostSerializer extends PostBasicSerializer } /** - * Get a resource containing a post's delete user. - * + * Get a resource containing a post's hide user. + * * @param Post $post * @param array $relations * @return Tobscure\JsonApi\Resource */ - public function includeDeleteUser(Post $post, $relations = []) + public function includeHideUser(Post $post, $relations = []) { - return (new UserBasicSerializer($relations))->resource($post->deleteUser); + return (new UserBasicSerializer($relations))->resource($post->hideUser); } } diff --git a/src/Flarum/Core/Discussions/Discussion.php b/src/Flarum/Core/Discussions/Discussion.php index 149763074..35d00ed83 100755 --- a/src/Flarum/Core/Discussions/Discussion.php +++ b/src/Flarum/Core/Discussions/Discussion.php @@ -111,7 +111,7 @@ class Discussion extends Entity public function comments() { - return $this->posts()->where('type', 'comment')->whereNull('delete_time'); + return $this->posts()->where('type', 'comment')->whereNull('hide_time'); } public function startPost() diff --git a/src/Flarum/Core/Posts/CommentPost.php b/src/Flarum/Core/Posts/CommentPost.php index b209d5ad9..463bc0747 100755 --- a/src/Flarum/Core/Posts/CommentPost.php +++ b/src/Flarum/Core/Posts/CommentPost.php @@ -54,24 +54,24 @@ class CommentPost extends Post public function hide($user) { - if ($this->delete_time) { + if ($this->hide_time) { return; } - $this->delete_time = time(); - $this->delete_user_id = $user->id; + $this->hide_time = time(); + $this->hide_user_id = $user->id; $this->raise(new Events\PostWasHidden($this)); } public function restore($user) { - if ($this->delete_time === null) { + if ($this->hide_time === null) { return; } - $this->delete_time = null; - $this->delete_user_id = null; + $this->hide_time = null; + $this->hide_user_id = null; $this->raise(new Events\PostWasRestored($this)); } diff --git a/src/Flarum/Core/Posts/Post.php b/src/Flarum/Core/Posts/Post.php index 03256897b..cf7504b19 100755 --- a/src/Flarum/Core/Posts/Post.php +++ b/src/Flarum/Core/Posts/Post.php @@ -23,8 +23,8 @@ class Post extends Entity 'user_id' => 'integer', 'edit_time' => 'date', 'edit_user_id' => 'integer', - 'delete_time' => 'date', - 'delete_user_id' => 'integer', + 'hide_time' => 'date', + 'hide_user_id' => 'integer', ]; public static function boot() @@ -43,7 +43,7 @@ class Post extends Entity }); static::check('view', function ($check, $user) { - $check->whereNull('delete_user_id') + $check->whereNull('hide_user_id') ->orWhereCan('edit'); }); @@ -55,8 +55,8 @@ class Post extends Entity }); static::check('editOwn', function ($check, $user) { - $check->whereNull('delete_user_id') - ->orWhere('delete_user_id', $user->id); + $check->whereNull('hide_user_id') + ->orWhere('hide_user_id', $user->id); }); static::deleted(function ($post) { @@ -79,14 +79,14 @@ class Post extends Entity return $this->belongsTo('Flarum\Core\Users\User', 'edit_user_id'); } - public function deleteUser() + public function hideUser() { - return $this->belongsTo('Flarum\Core\Users\User', 'delete_user_id'); + return $this->belongsTo('Flarum\Core\Users\User', 'hide_user_id'); } public function getDates() { - return ['time', 'edit_time', 'delete_time']; + return ['time', 'edit_time', 'hide_time']; } // Terminates the query and returns an array of matching IDs. @@ -122,7 +122,7 @@ class Post extends Entity return $instance; } } - + return parent::newFromBuilder($attributes); } } diff --git a/src/Flarum/Core/Support/Seeders/DiscussionTableSeeder.php b/src/Flarum/Core/Support/Seeders/DiscussionTableSeeder.php index d057d51ba..629273dca 100644 --- a/src/Flarum/Core/Support/Seeders/DiscussionTableSeeder.php +++ b/src/Flarum/Core/Support/Seeders/DiscussionTableSeeder.php @@ -67,9 +67,9 @@ class DiscussionTableSeeder extends Seeder ]); } else { $edited = rand(1, 20) == 1; - $deleted = rand(1, 100) == 1; + $hidden = rand(1, 100) == 1; - if ($deleted) { + if ($hidden) { $discussion->comments_count--; } @@ -82,8 +82,8 @@ class DiscussionTableSeeder extends Seeder 'content' => $faker->realText(rand(50, 500)), 'edit_time' => $edited ? $startTime = date_add($startTime, date_interval_create_from_date_string('1 second')) : null, 'edit_user_id' => $edited ? rand(1, $users) : null, - 'delete_time' => $deleted ? $startTime = date_add($startTime, date_interval_create_from_date_string('1 second')) : null, - 'delete_user_id' => $deleted ? rand(1, $users) : null, + 'hide_time' => $hidden ? $startTime = date_add($startTime, date_interval_create_from_date_string('1 second')) : null, + 'hide_user_id' => $hidden ? rand(1, $users) : null, ]); $posts[] = $post; diff --git a/src/migrations/2014_01_14_231350_create_posts_table.php b/src/migrations/2014_01_14_231350_create_posts_table.php index f122ae40c..5457836a9 100644 --- a/src/migrations/2014_01_14_231350_create_posts_table.php +++ b/src/migrations/2014_01_14_231350_create_posts_table.php @@ -26,8 +26,8 @@ class CreatePostsTable extends Migration { $table->dateTime('edit_time')->nullable(); $table->integer('edit_user_id')->unsigned()->nullable(); - $table->dateTime('delete_time')->nullable(); - $table->integer('delete_user_id')->unsigned()->nullable(); + $table->dateTime('hide_time')->nullable(); + $table->integer('hide_user_id')->unsigned()->nullable(); }); // add fulltext index to content (and title?)