From 56ef42f93179316e341a7417be76e46dc4adcc18 Mon Sep 17 00:00:00 2001 From: Toby Zerner Date: Mon, 4 May 2015 12:19:25 +0930 Subject: [PATCH] Add concept of "mergeable" activity posts For example: when you rename a discussion, DiscussionRenamedPost is created. If you rename it again immediately afterwards, then a new DiscussionRenamedPost can be merged into the old one. This will either result in the old one being updated with the new title, or it being deleted all together if it was renamed back to the old title. --- .../Events/DiscussionRenamedNotifier.php | 8 +--- src/Core/Models/ActivityPost.php | 27 ++++++++++++ src/Core/Models/Discussion.php | 18 ++++++++ src/Core/Models/DiscussionRenamedPost.php | 41 +++++++++++-------- src/Core/Models/MergeableInterface.php | 6 +++ src/Core/Models/MergeableTrait.php | 23 +++++++++++ 6 files changed, 100 insertions(+), 23 deletions(-) create mode 100755 src/Core/Models/ActivityPost.php create mode 100644 src/Core/Models/MergeableInterface.php create mode 100644 src/Core/Models/MergeableTrait.php diff --git a/src/Core/Handlers/Events/DiscussionRenamedNotifier.php b/src/Core/Handlers/Events/DiscussionRenamedNotifier.php index f989cc07c..5b985198c 100755 --- a/src/Core/Handlers/Events/DiscussionRenamedNotifier.php +++ b/src/Core/Handlers/Events/DiscussionRenamedNotifier.php @@ -27,7 +27,7 @@ class DiscussionRenamedNotifier { $post = $this->createPost($event); - $event->discussion->postWasAdded($post); + $event->discussion->addPost($post); if ($event->discussion->start_user_id !== $event->user->id) { $this->sendNotification($event, $post); @@ -36,16 +36,12 @@ class DiscussionRenamedNotifier protected function createPost(DiscussionWasRenamed $event) { - $post = DiscussionRenamedPost::reply( + return DiscussionRenamedPost::reply( $event->discussion->id, $event->user->id, $event->oldTitle, $event->discussion->title ); - - $post->save(); - - return $post; } protected function sendNotification(DiscussionWasRenamed $event, DiscussionRenamedPost $post) diff --git a/src/Core/Models/ActivityPost.php b/src/Core/Models/ActivityPost.php new file mode 100755 index 000000000..0b0413979 --- /dev/null +++ b/src/Core/Models/ActivityPost.php @@ -0,0 +1,27 @@ +attributes['content'] = json_encode($value); + } +} diff --git a/src/Core/Models/Discussion.php b/src/Core/Models/Discussion.php index d3c26e2d9..2e0b0bc6f 100755 --- a/src/Core/Models/Discussion.php +++ b/src/Core/Models/Discussion.php @@ -185,6 +185,24 @@ class Discussion extends Model $this->removedPosts[] = $post->id; } + public function addPost(Post $post) + { + if ($post instanceof MergeableInterface) { + $lastPost = $this->posts()->orderBy('time', 'desc')->first(); + $post = $post->saveAfter($lastPost); + } else { + $post->save(); + } + + if ($post->exists) { + $this->postWasAdded($post); + } else { + $this->postWasRemoved($post); + } + + return $post->exists; + } + /** * Define the relationship with the discussion's posts. * diff --git a/src/Core/Models/DiscussionRenamedPost.php b/src/Core/Models/DiscussionRenamedPost.php index 38ce65a9b..d10231ee7 100755 --- a/src/Core/Models/DiscussionRenamedPost.php +++ b/src/Core/Models/DiscussionRenamedPost.php @@ -1,7 +1,23 @@ content[0] == $this->content[1]) { + return false; + } + + $previous->content = static::buildContent($previous->content[0], $this->content[1]); + return true; + } + /** * Create a new instance in reply to a discussion. * @@ -15,7 +31,7 @@ class DiscussionRenamedPost extends Post { $post = new static; - $post->content = [$oldTitle, $newTitle]; + $post->content = static::buildContent($oldTitle, $newTitle); $post->time = time(); $post->discussion_id = $discussionId; $post->user_id = $userId; @@ -25,23 +41,14 @@ class DiscussionRenamedPost extends Post } /** - * Unserialize the content attribute. + * Build the content attribute. * - * @param string $value - * @return string + * @param boolean $oldTitle The old title of the discussion. + * @param boolean $newTitle The new title of the discussion. + * @return array */ - public function getContentAttribute($value) + public static function buildContent($oldTitle, $newTitle) { - return json_decode($value); - } - - /** - * Serialize the content attribute. - * - * @param string $value - */ - public function setContentAttribute($value) - { - $this->attributes['content'] = json_encode($value); + return [$oldTitle, $newTitle]; } } diff --git a/src/Core/Models/MergeableInterface.php b/src/Core/Models/MergeableInterface.php new file mode 100644 index 000000000..2a6c81ccf --- /dev/null +++ b/src/Core/Models/MergeableInterface.php @@ -0,0 +1,6 @@ +mergeInto($previous)) { + $previous->save(); + } else { + $previous->delete(); + } + + return $previous; + } + + $this->save(); + + return $this; + } + + abstract protected function mergeInto(Model $previous); +}