Add separate tag permission for being able to add that tag to discussions

By default this is just the same as the "startDiscussion" permission, but flarum-ext-approval comes in and denies "addToDiscussion" specifically for tags where the user can't start discussions without approval.

ref flarum/core#904
This commit is contained in:
Toby Zerner 2016-05-28 10:02:45 +09:30
parent 01e776e2be
commit 1629e7fbb4
7 changed files with 44 additions and 6 deletions

View File

@ -1301,6 +1301,7 @@ System.register('flarum/tags/models/Tag', ['flarum/Model', 'flarum/utils/mixin',
isRestricted: Model.attribute('isRestricted'),
canStartDiscussion: Model.attribute('canStartDiscussion'),
canAddToDiscussion: Model.attribute('canAddToDiscussion'),
isPrimary: computed('position', 'parent', function (position, parent) {
return position !== null && parent === false;

View File

@ -446,9 +446,19 @@ System.register('flarum/tags/components/TagDiscussionModal', ['flarum/components
babelHelpers.get(Object.getPrototypeOf(TagDiscussionModal.prototype), 'init', this).call(this);
this.tags = sortTags(app.store.all('tags').filter(function (tag) {
return tag.canStartDiscussion();
}));
this.tags = app.store.all('tags');
if (this.props.discussion) {
this.tags = this.tags.filter(function (tag) {
return tag.canAddToDiscussion() || _this2.props.discussion.tags().indexOf(tag) !== -1;
});
} else {
this.tags = this.tags.filter(function (tag) {
return tag.canStartDiscussion();
});
}
this.tags = sortTags(this.tags);
this.selected = [];
this.filter = m.prop('');
@ -1258,6 +1268,7 @@ System.register('flarum/tags/models/Tag', ['flarum/Model', 'flarum/utils/mixin',
isRestricted: Model.attribute('isRestricted'),
canStartDiscussion: Model.attribute('canStartDiscussion'),
canAddToDiscussion: Model.attribute('canAddToDiscussion'),
isPrimary: computed('position', 'parent', function (position, parent) {
return position !== null && parent === false;

View File

@ -14,7 +14,15 @@ export default class TagDiscussionModal extends Modal {
init() {
super.init();
this.tags = sortTags(app.store.all('tags').filter(tag => tag.canStartDiscussion()));
this.tags = app.store.all('tags');
if (this.props.discussion) {
this.tags = this.tags.filter(tag => tag.canAddToDiscussion() || this.props.discussion.tags().indexOf(tag) !== -1);
} else {
this.tags = this.tags.filter(tag => tag.canStartDiscussion());
}
this.tags = sortTags(this.tags);
this.selected = [];
this.filter = m.prop('');

View File

@ -23,6 +23,7 @@ export default class Tag extends mixin(Model, {
isRestricted: Model.attribute('isRestricted'),
canStartDiscussion: Model.attribute('canStartDiscussion'),
canAddToDiscussion: Model.attribute('canAddToDiscussion'),
isPrimary: computed('position', 'parent', (position, parent) => position !== null && parent === false)
}) {}

View File

@ -43,4 +43,14 @@ class TagPolicy extends AbstractPolicy
return true;
}
}
/**
* @param User $actor
* @param Tag $tag
* @return bool|null
*/
public function addToDiscussion(User $actor, Tag $tag)
{
return $this->startDiscussion($actor, $tag);
}
}

View File

@ -40,7 +40,8 @@ class TagSerializer extends AbstractSerializer
'isChild' => (bool) $tag->parent_id,
'isHidden' => (bool) $tag->is_hidden,
'lastTime' => $this->formatDate($tag->last_time),
'canStartDiscussion' => $this->actor->can('startDiscussion', $tag)
'canStartDiscussion' => $this->actor->can('startDiscussion', $tag),
'canAddToDiscussion' => $this->actor->can('addToDiscussion', $tag)
];
if ($this->actor->isAdmin()) {

View File

@ -81,12 +81,18 @@ class SaveTagsToDatabase
if ($discussion->exists) {
$oldTags = $discussion->tags()->get();
$oldTagIds = $oldTags->lists('id');
$oldTagIds = $oldTags->lists('id')->all();
if ($oldTagIds == $newTagIds) {
return;
}
foreach ($newTags as $tag) {
if (! in_array($tag->id, $oldTagIds) && $actor->cannot('addToDiscussion', $tag)) {
throw new PermissionDeniedException;
}
}
$discussion->raise(
new DiscussionWasTagged($discussion, $actor, $oldTags->all())
);