1
0
mirror of https://github.com/flarum/core.git synced 2025-08-06 08:27:42 +02:00

Implement "renamed" posts

Record when the discussion was renamed, from what, and by whom.
Information is stored in the `content` field as a serialised JSON
object because proper polymorphism will be too difficult with Ember
Data and especially when extensions try to add new post types.
This commit is contained in:
Toby Zerner
2015-02-13 10:23:38 +10:30
parent fa3523ac74
commit 011ae3603e
19 changed files with 225 additions and 90 deletions

View File

@@ -20,12 +20,13 @@ class Update extends Base
{
$discussionId = $this->param('id');
$readNumber = $this->input('discussions.readNumber');
$user = User::current();
// First, we will run the EditDiscussionCommand. This will update the
// discussion's direct properties; by default, this is just the title.
// As usual, however, we will fire an event to allow plugins to update
// additional properties.
$command = new EditDiscussionCommand($discussionId, User::current());
$command = new EditDiscussionCommand($discussionId, $user);
$this->fillCommandWithInput($command, 'discussions');
Event::fire('Flarum.Api.Actions.Discussions.Update.WillExecuteCommand', [$command]);
@@ -36,14 +37,14 @@ class Update extends Base
// ReadDiscussionCommand. We won't bother firing an event for this one,
// because it's pretty specific. (This may need to change in the future.)
if ($readNumber) {
$command = new ReadDiscussionCommand($discussionId, User::current(), $readNumber);
$discussion = $this->commandBus->execute($command);
$command = new ReadDiscussionCommand($discussionId, $user, $readNumber);
$this->commandBus->execute($command);
}
// Presumably, the discussion was updated successfully. (One of the command
// handlers would have thrown an exception if not.) We set this
// discussion as our document's primary element.
$serializer = new DiscussionSerializer;
$serializer = new DiscussionSerializer(['addedPosts', 'addedPosts.user']);
$this->document->setPrimaryElement($serializer->resource($discussion));
return $this->respondWithDocument();

View File

@@ -130,4 +130,17 @@ class DiscussionSerializer extends DiscussionBasicSerializer
{
return (new PostBasicSerializer($relations))->resource($discussion->lastPost);
}
/**
* Get a resource containing a discussion's list of posts that have been
* added during this request.
*
* @param Discussion $discussion
* @param array $relations
* @return Tobscure\JsonApi\Collection
*/
public function includeAddedPosts(Discussion $discussion, $relations)
{
return (new PostBasicSerializer($relations))->collection($discussion->getAddedPosts());
}
}

View File

@@ -30,7 +30,7 @@ class PostBasicSerializer extends BaseSerializer
/**
* Serialize attributes of a Post model for JSON output.
*
*
* @param Post $post The Post model to serialize.
* @return array
*/
@@ -40,17 +40,22 @@ class PostBasicSerializer extends BaseSerializer
'id' => (int) $post->id,
'number' => (int) $post->number,
'time' => $post->time->toRFC3339String(),
'type' => $post->type,
'content' => str_limit($post->content, 200)
'type' => $post->type
];
if ($post->type === 'comment') {
$attributes['content'] = str_limit($post->content, 200);
} else {
$attributes['content'] = json_encode($post->content);
}
return $this->attributesEvent($post, $attributes);
}
/**
* Get the URL templates where this resource and its related resources can
* be accessed.
*
*
* @return array
*/
public function href()
@@ -62,7 +67,7 @@ class PostBasicSerializer extends BaseSerializer
/**
* Get a resource containing a post's user.
*
*
* @param Post $post
* @param array $relations
* @return Tobscure\JsonApi\Resource
@@ -74,7 +79,7 @@ class PostBasicSerializer extends BaseSerializer
/**
* Get a resource containing a post's discussion ID.
*
*
* @param Post $post
* @return Tobscure\JsonApi\Resource
*/

View File

@@ -38,13 +38,13 @@ class PostSerializer extends PostBasicSerializer
$canEdit = $post->can($user, 'edit');
if ($post->type != 'comment') {
$attributes['content'] = $post->content;
} else {
if ($post->type === 'comment') {
$attributes['contentHtml'] = $post->content_html;
if ($canEdit) {
$attributes['content'] = $post->content;
}
} else {
$attributes['content'] = json_encode($post->content);
}
if ($post->edit_time) {

View File

@@ -9,17 +9,17 @@ use Flarum\Core\Formatter\FormatterManager;
class CoreServiceProvider extends ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = false;
/**
* Bootstrap the application events.
*
* @return void
*/
* Bootstrap the application events.
*
* @return void
*/
public function boot()
{
$this->package('flarum/core', 'flarum');
@@ -30,14 +30,14 @@ class CoreServiceProvider extends ServiceProvider
Event::listen('Flarum.Core.*', 'Flarum\Core\Listeners\DiscussionMetadataUpdater');
Event::listen('Flarum.Core.*', 'Flarum\Core\Listeners\UserMetadataUpdater');
Event::listen('Flarum.Core.*', 'Flarum\Core\Listeners\TitleChangePostCreator');
Event::listen('Flarum.Core.*', 'Flarum\Core\Listeners\RenamedPostCreator');
}
/**
* Register the service provider.
*
* @return void
*/
* Register the service provider.
*
* @return void
*/
public function register()
{
// Start up the Laracasts Commander package. This is used as the basis
@@ -69,36 +69,36 @@ class CoreServiceProvider extends ServiceProvider
$formatter->add('basic', 'Flarum\Core\Formatter\BasicFormatter');
return $formatter;
});
// $this->app->singleton(
// 'Flarum\Core\Repositories\Contracts\DiscussionRepository',
// function($app)
// {
// $discussion = new \Flarum\Core\Repositories\EloquentDiscussionRepository;
// return new DiscussionCacheDecorator($discussion);
// }
// 'Flarum\Core\Repositories\Contracts\DiscussionRepository',
// function($app)
// {
// $discussion = new \Flarum\Core\Repositories\EloquentDiscussionRepository;
// return new DiscussionCacheDecorator($discussion);
// }
// );
// $this->app->singleton(
// 'Flarum\Core\Repositories\Contracts\UserRepository',
// 'Flarum\Core\Repositories\EloquentUserRepository'
// 'Flarum\Core\Repositories\Contracts\UserRepository',
// 'Flarum\Core\Repositories\EloquentUserRepository'
// );
// $this->app->singleton(
// 'Flarum\Core\Repositories\Contracts\PostRepository',
// 'Flarum\Core\Repositories\EloquentPostRepository'
// 'Flarum\Core\Repositories\Contracts\PostRepository',
// 'Flarum\Core\Repositories\EloquentPostRepository'
// );
// $this->app->singleton(
// 'Flarum\Core\Repositories\Contracts\GroupRepository',
// 'Flarum\Core\Repositories\EloquentGroupRepository'
// 'Flarum\Core\Repositories\Contracts\GroupRepository',
// 'Flarum\Core\Repositories\EloquentGroupRepository'
// );
}
/**
* Get the services provided by the provider.
*
* @return array
*/
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return array();

View File

@@ -8,6 +8,7 @@ use Flarum\Core\Forum;
use Flarum\Core\Permission;
use Flarum\Core\Support\Exceptions\PermissionDeniedException;
use Flarum\Core\Users\User;
use Flarum\Core\Posts\Post;
class Discussion extends Entity
{
@@ -28,6 +29,8 @@ class Discussion extends Entity
'last_post_number' => 'integer'
];
protected $addedPosts = [];
public static function boot()
{
parent::boot();
@@ -69,7 +72,7 @@ class Discussion extends Entity
return $discussion;
}
public function setLastPost($post)
public function setLastPost(Post $post)
{
$this->last_time = $post->time;
$this->last_user_id = $post->user_id;
@@ -79,8 +82,19 @@ class Discussion extends Entity
public function refreshLastPost()
{
$lastPost = $this->comments()->orderBy('time', 'desc')->first();
$this->setLastPost($lastPost);
if ($lastPost = $this->comments()->orderBy('time', 'desc')->first()) {
$this->setLastPost($lastPost);
}
}
public function getAddedPosts()
{
return $this->addedPosts;
}
public function postWasAdded(Post $post)
{
$this->addedPosts[] = $post;
}
public function refreshCommentsCount()
@@ -94,9 +108,10 @@ class Discussion extends Entity
return;
}
$oldTitle = $this->title;
$this->title = $title;
$this->raise(new Events\DiscussionWasRenamed($this, $user));
$this->raise(new Events\DiscussionWasRenamed($this, $user, $oldTitle));
}
public function getDates()

View File

@@ -9,9 +9,12 @@ class DiscussionWasRenamed
public $user;
public function __construct(Discussion $discussion, User $user)
public $oldTitle;
public function __construct(Discussion $discussion, User $user, $oldTitle)
{
$this->discussion = $discussion;
$this->user = $user;
$this->oldTitle = $oldTitle;
}
}

View File

@@ -3,10 +3,10 @@
use Laracasts\Commander\Events\EventListener;
use Flarum\Core\Posts\PostRepository;
use Flarum\Core\Posts\TitleChangePost;
use Flarum\Core\Posts\RenamedPost;
use Flarum\Core\Discussions\Events\DiscussionWasRenamed;
class TitleChangePostCreator extends EventListener
class RenamedPostCreator extends EventListener
{
protected $postRepo;
@@ -17,12 +17,15 @@ class TitleChangePostCreator extends EventListener
public function whenDiscussionWasRenamed(DiscussionWasRenamed $event)
{
$post = TitleChangePost::reply(
$post = RenamedPost::reply(
$event->discussion->id,
$event->discussion->title,
$event->user->id
$event->user->id,
$event->oldTitle,
$event->discussion->title
);
$this->postRepo->save($post);
$event->discussion->postWasAdded($post);
}
}

View File

@@ -8,18 +8,28 @@ use Flarum\Core\Permission;
use Flarum\Core\Support\Exceptions\PermissionDeniedException;
use Flarum\Core\Users\User;
class TitleChangePost extends Post
class RenamedPost extends Post
{
public static function reply($discussionId, $content, $userId)
public static function reply($discussionId, $userId, $oldTitle, $newTitle)
{
$post = new static;
$post->content = $content;
$post->content = [$oldTitle, $newTitle];
$post->time = time();
$post->discussion_id = $discussionId;
$post->user_id = $userId;
$post->type = 'titleChange';
$post->type = 'renamed';
return $post;
}
public function getContentAttribute($value)
{
return json_decode($value);
}
public function setContentAttribute($value)
{
$this->attributes['content'] = json_encode($value);
}
}