From 4773b3005dd46791d7b74a7d9ecbfb2f16c7b5ac Mon Sep 17 00:00:00 2001 From: Toby Zerner Date: Mon, 28 Nov 2016 11:48:19 +1030 Subject: [PATCH] Add tag-user state --- .../src/Api/Controller/ListTagsController.php | 11 ++- .../AddDiscussionTagsRelationship.php | 6 +- .../src/Listener/AddForumTagsRelationship.php | 2 +- extensions/tags/src/Tag.php | 45 ++++++++++++ extensions/tags/src/TagState.php | 73 +++++++++++++++++++ 5 files changed, 127 insertions(+), 10 deletions(-) create mode 100644 extensions/tags/src/TagState.php diff --git a/extensions/tags/src/Api/Controller/ListTagsController.php b/extensions/tags/src/Api/Controller/ListTagsController.php index 2aa112783..4f64bb55a 100644 --- a/extensions/tags/src/Api/Controller/ListTagsController.php +++ b/extensions/tags/src/Api/Controller/ListTagsController.php @@ -13,6 +13,7 @@ namespace Flarum\Tags\Api\Controller; use Flarum\Api\Controller\AbstractCollectionController; use Flarum\Tags\Api\Serializer\TagSerializer; +use Flarum\Tags\Tag; use Flarum\Tags\TagRepository; use Psr\Http\Message\ServerRequestInterface; use Tobscure\JsonApi\Document; @@ -25,14 +26,14 @@ class ListTagsController extends AbstractCollectionController public $serializer = TagSerializer::class; /** - * @var \Flarum\Tags\TagRepository + * @var \Flarum\Tags\Tag */ protected $tags; /** - * @param \Flarum\Tags\TagRepository $tags + * @param \Flarum\Tags\Tag $tags */ - public function __construct(TagRepository $tags) + public function __construct(Tag $tags) { $this->tags = $tags; } @@ -42,6 +43,8 @@ class ListTagsController extends AbstractCollectionController */ protected function data(ServerRequestInterface $request, Document $document) { - return $this->tags->all($request->getAttribute('actor')); + $actor = $request->getAttribute('actor'); + + return $this->tags->whereVisibleTo($actor)->withStateFor($actor)->get(); } } diff --git a/extensions/tags/src/Listener/AddDiscussionTagsRelationship.php b/extensions/tags/src/Listener/AddDiscussionTagsRelationship.php index 808b02557..f0eba4142 100755 --- a/extensions/tags/src/Listener/AddDiscussionTagsRelationship.php +++ b/extensions/tags/src/Listener/AddDiscussionTagsRelationship.php @@ -64,11 +64,7 @@ class AddDiscussionTagsRelationship if ($event->isController(Controller\ListDiscussionsController::class) || $event->isController(Controller\ShowDiscussionController::class) || $event->isController(Controller\CreateDiscussionController::class)) { - $event->addInclude('tags'); - } - - if ($event->isController(Controller\CreateDiscussionController::class)) { - $event->addInclude('tags.lastDiscussion'); + $event->addInclude(['tags', 'tags.state']); } } diff --git a/extensions/tags/src/Listener/AddForumTagsRelationship.php b/extensions/tags/src/Listener/AddForumTagsRelationship.php index 533436295..259d7cdc0 100755 --- a/extensions/tags/src/Listener/AddForumTagsRelationship.php +++ b/extensions/tags/src/Listener/AddForumTagsRelationship.php @@ -68,7 +68,7 @@ class AddForumTagsRelationship // doesn't actually have a tags relationship, we will manually load and // assign the tags data to it using an event listener. if ($event->isController(ShowForumController::class)) { - $event->data['tags'] = Tag::whereVisibleTo($event->actor)->with('lastDiscussion')->get(); + $event->data['tags'] = Tag::whereVisibleTo($event->actor)->withStateFor($event->actor)->with('lastDiscussion')->get(); } } diff --git a/extensions/tags/src/Tag.php b/extensions/tags/src/Tag.php index d880d2029..0a93232ef 100644 --- a/extensions/tags/src/Tag.php +++ b/extensions/tags/src/Tag.php @@ -15,6 +15,7 @@ use Flarum\Core\Permission; use Flarum\Core\Support\ScopeVisibilityTrait; use Flarum\Core\User; use Flarum\Database\AbstractModel; +use Illuminate\Database\Eloquent\Builder; class Tag extends AbstractModel { @@ -119,6 +120,50 @@ class Tag extends AbstractModel return $this; } + /** + * Define the relationship with the tag's state for a particular user. + * + * @return \Illuminate\Database\Eloquent\Relations\HasOne + */ + public function state() + { + return $this->hasOne(TagState::class); + } + + /** + * Get the state model for a user, or instantiate a new one if it does not + * exist. + * + * @param User $user + * @return TagState + */ + public function stateFor(User $user) + { + $state = $this->state()->where('user_id', $user->id)->first(); + + if (! $state) { + $state = new TagState; + $state->tag_id = $this->id; + $state->user_id = $user->id; + } + + return $state; + } + + /** + * @param Builder $query + * @param User $user + * @return Builder + */ + public function scopeWithStateFor(Builder $query, User $user) + { + return $query->with([ + 'state' => function ($query) use ($user) { + $query->where('user_id', $user->id); + } + ]); + } + /** * @param User $user * @param string $permission diff --git a/extensions/tags/src/TagState.php b/extensions/tags/src/TagState.php new file mode 100644 index 000000000..6ef45ba15 --- /dev/null +++ b/extensions/tags/src/TagState.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Flarum\Tags; + +use Flarum\Core\Support\EventGeneratorTrait; +use Flarum\Core\User; +use Flarum\Database\AbstractModel; +use Illuminate\Database\Eloquent\Builder; + +/** + * @property int $user_id + * @property int $tag_id + * @property \Carbon\Carbon|null $read_time + * @property bool $is_hidden + * @property Tag $tag + * @property User $user + */ +class TagState extends AbstractModel +{ + use EventGeneratorTrait; + + /** + * {@inheritdoc} + */ + protected $table = 'users_tags'; + + /** + * {@inheritdoc} + */ + protected $dates = ['read_time']; + + /** + * Define the relationship with the tag that this state is for. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function tag() + { + return $this->belongsTo(Tag::class, 'tag_id'); + } + + /** + * Define the relationship with the user that this state is for. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function user() + { + return $this->belongsTo(User::class, 'user_id'); + } + + /** + * Set the keys for a save update query. + * + * @param Builder $query + * @return Builder + */ + protected function setKeysForSaveQuery(Builder $query) + { + $query->where('tag_id', $this->tag_id) + ->where('user_id', $this->user_id); + + return $query; + } +}