mirror of
https://github.com/flarum/framework.git
synced 2025-02-07 21:05:00 +08:00
Allow discussions to be hidden and restored
This commit is contained in:
parent
c7ed189cf3
commit
264725d872
|
@ -4,6 +4,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
## [Unreleased][unreleased]
|
## [Unreleased][unreleased]
|
||||||
### Added
|
### Added
|
||||||
|
- Allow discussions to be hidden and restored.
|
||||||
- External authentication (social login) API.
|
- External authentication (social login) API.
|
||||||
- API to set asset compiler filename.
|
- API to set asset compiler filename.
|
||||||
- Migration generator, available via generate:migration console command.
|
- Migration generator, available via generate:migration console command.
|
||||||
|
|
|
@ -13,6 +13,7 @@ import SubtreeRetainer from 'flarum/utils/SubtreeRetainer';
|
||||||
import DiscussionControls from 'flarum/utils/DiscussionControls';
|
import DiscussionControls from 'flarum/utils/DiscussionControls';
|
||||||
import slidable from 'flarum/utils/slidable';
|
import slidable from 'flarum/utils/slidable';
|
||||||
import extractText from 'flarum/utils/extractText';
|
import extractText from 'flarum/utils/extractText';
|
||||||
|
import classList from 'flarum/utils/classList';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The `DiscussionListItem` component shows a single discussion in the
|
* The `DiscussionListItem` component shows a single discussion in the
|
||||||
|
@ -43,6 +44,16 @@ export default class DiscussionListItem extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attrs() {
|
||||||
|
return {
|
||||||
|
className: classList([
|
||||||
|
'DiscussionListItem',
|
||||||
|
this.active() ? 'active' : '',
|
||||||
|
this.props.discussion.isHidden() ? 'DiscussionListItem--hidden' : ''
|
||||||
|
])
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
view() {
|
view() {
|
||||||
const retain = this.subtree.retain();
|
const retain = this.subtree.retain();
|
||||||
|
|
||||||
|
@ -56,9 +67,10 @@ export default class DiscussionListItem extends Component {
|
||||||
const jumpTo = Math.min(discussion.lastPostNumber(), (discussion.readNumber() || 0) + 1);
|
const jumpTo = Math.min(discussion.lastPostNumber(), (discussion.readNumber() || 0) + 1);
|
||||||
const relevantPosts = this.props.params.q ? discussion.relevantPosts() : [];
|
const relevantPosts = this.props.params.q ? discussion.relevantPosts() : [];
|
||||||
const controls = DiscussionControls.controls(discussion, this).toArray();
|
const controls = DiscussionControls.controls(discussion, this).toArray();
|
||||||
|
const attrs = this.attrs();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={'DiscussionListItem ' + (this.active() ? 'active' : '')}>
|
<div {...attrs}>
|
||||||
|
|
||||||
{controls.length ? Dropdown.component({
|
{controls.length ? Dropdown.component({
|
||||||
icon: 'ellipsis-v',
|
icon: 'ellipsis-v',
|
||||||
|
|
|
@ -105,10 +105,25 @@ export default {
|
||||||
destructiveControls(discussion) {
|
destructiveControls(discussion) {
|
||||||
const items = new ItemList();
|
const items = new ItemList();
|
||||||
|
|
||||||
if (discussion.canDelete()) {
|
if (!discussion.isHidden()) {
|
||||||
|
if (discussion.canHide()) {
|
||||||
|
items.add('hide', Button.component({
|
||||||
|
icon: 'trash-o',
|
||||||
|
children: app.trans('core.delete'),
|
||||||
|
onclick: this.hideAction.bind(discussion)
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
} else if (discussion.canDelete()) {
|
||||||
|
items.add('restore', Button.component({
|
||||||
|
icon: 'reply',
|
||||||
|
children: app.trans('core.restore'),
|
||||||
|
onclick: this.restoreAction.bind(discussion),
|
||||||
|
disabled: discussion.commentsCount() === 0
|
||||||
|
}));
|
||||||
|
|
||||||
items.add('delete', Button.component({
|
items.add('delete', Button.component({
|
||||||
icon: 'times',
|
icon: 'times',
|
||||||
children: app.trans('core.delete'),
|
children: app.trans('core.delete_forever'),
|
||||||
onclick: this.deleteAction.bind(discussion)
|
onclick: this.deleteAction.bind(discussion)
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -173,13 +188,35 @@ export default {
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide a discussion.
|
||||||
|
*
|
||||||
|
* @return {Promise}
|
||||||
|
*/
|
||||||
|
hideAction() {
|
||||||
|
this.pushAttributes({ hideTime: new Date(), hideUser: app.session.user });
|
||||||
|
|
||||||
|
return this.save({ isHidden: true });
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore a discussion.
|
||||||
|
*
|
||||||
|
* @return {Promise}
|
||||||
|
*/
|
||||||
|
restoreAction() {
|
||||||
|
this.pushAttributes({ hideTime: null, hideUser: null });
|
||||||
|
|
||||||
|
return this.save({ isHidden: false });
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete the discussion after confirming with the user.
|
* Delete the discussion after confirming with the user.
|
||||||
|
*
|
||||||
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
deleteAction() {
|
deleteAction() {
|
||||||
if (confirm(extractText(app.trans('core.confirm_delete_discussion')))) {
|
if (confirm(extractText(app.trans('core.confirm_delete_discussion')))) {
|
||||||
this.delete();
|
|
||||||
|
|
||||||
// If there is a discussion list in the cache, remove this discussion.
|
// If there is a discussion list in the cache, remove this discussion.
|
||||||
if (app.cache.discussionList) {
|
if (app.cache.discussionList) {
|
||||||
app.cache.discussionList.removeDiscussion(this);
|
app.cache.discussionList.removeDiscussion(this);
|
||||||
|
@ -190,11 +227,15 @@ export default {
|
||||||
if (app.viewingDiscussion(this)) {
|
if (app.viewingDiscussion(this)) {
|
||||||
app.history.back();
|
app.history.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return this.delete();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rename the discussion.
|
* Rename the discussion.
|
||||||
|
*
|
||||||
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
renameAction() {
|
renameAction() {
|
||||||
const currentTitle = this.title();
|
const currentTitle = this.title();
|
||||||
|
@ -204,7 +245,7 @@ export default {
|
||||||
// save has completed, update the post stream as there will be a new post
|
// save has completed, update the post stream as there will be a new post
|
||||||
// indicating that the discussion was renamed.
|
// indicating that the discussion was renamed.
|
||||||
if (title && title !== currentTitle) {
|
if (title && title !== currentTitle) {
|
||||||
this.save({title}).then(() => {
|
return this.save({title}).then(() => {
|
||||||
if (app.viewingDiscussion(this)) {
|
if (app.viewingDiscussion(this)) {
|
||||||
app.current.stream.update();
|
app.current.stream.update();
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,25 +114,34 @@ export default {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hide a post.
|
* Hide a post.
|
||||||
|
*
|
||||||
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
hideAction() {
|
hideAction() {
|
||||||
this.save({ isHidden: true });
|
|
||||||
this.pushAttributes({ hideTime: new Date(), hideUser: app.session.user });
|
this.pushAttributes({ hideTime: new Date(), hideUser: app.session.user });
|
||||||
|
|
||||||
|
return this.save({ isHidden: true }).then(() => m.redraw());
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restore a post.
|
* Restore a post.
|
||||||
|
*
|
||||||
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
restoreAction() {
|
restoreAction() {
|
||||||
this.save({ isHidden: false });
|
|
||||||
this.pushAttributes({ hideTime: null, hideUser: null });
|
this.pushAttributes({ hideTime: null, hideUser: null });
|
||||||
|
|
||||||
|
return this.save({ isHidden: false }).then(() => m.redraw());
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a post.
|
* Delete a post.
|
||||||
|
*
|
||||||
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
deleteAction() {
|
deleteAction() {
|
||||||
this.delete();
|
|
||||||
this.discussion().removePost(this.id());
|
this.discussion().removePost(this.id());
|
||||||
|
|
||||||
|
return this.delete();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,6 +11,7 @@ import extract from 'flarum/utils/extract';
|
||||||
* - `type` The type of badge this is. This will be used to give the badge a
|
* - `type` The type of badge this is. This will be used to give the badge a
|
||||||
* class name of `Badge--{type}`.
|
* class name of `Badge--{type}`.
|
||||||
* - `icon` The name of an icon to show inside the badge.
|
* - `icon` The name of an icon to show inside the badge.
|
||||||
|
* - `label`
|
||||||
*
|
*
|
||||||
* All other props will be assigned as attributes on the badge element.
|
* All other props will be assigned as attributes on the badge element.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -3,6 +3,7 @@ import mixin from 'flarum/utils/mixin';
|
||||||
import computed from 'flarum/utils/computed';
|
import computed from 'flarum/utils/computed';
|
||||||
import ItemList from 'flarum/utils/ItemList';
|
import ItemList from 'flarum/utils/ItemList';
|
||||||
import { slug } from 'flarum/utils/string';
|
import { slug } from 'flarum/utils/string';
|
||||||
|
import Badge from 'flarum/components/Badge';
|
||||||
|
|
||||||
export default class Discussion extends mixin(Model, {
|
export default class Discussion extends mixin(Model, {
|
||||||
title: Model.attribute('title'),
|
title: Model.attribute('title'),
|
||||||
|
@ -27,8 +28,13 @@ export default class Discussion extends mixin(Model, {
|
||||||
isUnread: computed('unreadCount', unreadCount => !!unreadCount),
|
isUnread: computed('unreadCount', unreadCount => !!unreadCount),
|
||||||
isRead: computed('unreadCount', unreadCount => app.session.user && !unreadCount),
|
isRead: computed('unreadCount', unreadCount => app.session.user && !unreadCount),
|
||||||
|
|
||||||
|
hideTime: Model.attribute('hideTime', Model.transformDate),
|
||||||
|
hideUser: Model.hasOne('hideUser'),
|
||||||
|
isHidden: computed('hideTime', 'commentsCount', (hideTime, commentsCount) => !!hideTime || commentsCount === 0),
|
||||||
|
|
||||||
canReply: Model.attribute('canReply'),
|
canReply: Model.attribute('canReply'),
|
||||||
canRename: Model.attribute('canRename'),
|
canRename: Model.attribute('canRename'),
|
||||||
|
canHide: Model.attribute('canHide'),
|
||||||
canDelete: Model.attribute('canDelete')
|
canDelete: Model.attribute('canDelete')
|
||||||
}) {
|
}) {
|
||||||
/**
|
/**
|
||||||
|
@ -75,7 +81,13 @@ export default class Discussion extends mixin(Model, {
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
badges() {
|
badges() {
|
||||||
return new ItemList();
|
const items = new ItemList();
|
||||||
|
|
||||||
|
if (this.isHidden()) {
|
||||||
|
items.add('hidden', <Badge type="hidden" icon="trash" label="Hidden"/>);
|
||||||
|
}
|
||||||
|
|
||||||
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3,6 +3,12 @@
|
||||||
max-width: none;
|
max-width: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.DiscussionListItem--hidden {
|
||||||
|
.DiscussionListItem-content {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.DiscussionListItem a {
|
.DiscussionListItem a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,3 +33,7 @@
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.Badge--hidden {
|
||||||
|
background: #888;
|
||||||
|
}
|
||||||
|
|
|
@ -50,8 +50,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&.disabled {
|
&.disabled {
|
||||||
opacity: 0.5;
|
opacity: 0.4;
|
||||||
background: none;
|
background: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
> a, > button {
|
> a, > button {
|
||||||
|
|
34
migrations/2015_09_20_224327_add_hide_to_discussions.php
Normal file
34
migrations/2015_09_20_224327_add_hide_to_discussions.php
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Flarum\Migrations\Core;
|
||||||
|
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Flarum\Migrations\Migration;
|
||||||
|
|
||||||
|
class AddHideToDiscussions extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
$this->schema->table('discussions', function (Blueprint $table) {
|
||||||
|
$table->dateTime('hide_time')->nullable();
|
||||||
|
$table->integer('hide_user_id')->unsigned()->nullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
$this->schema->table('discussions', function (Blueprint $table) {
|
||||||
|
$table->dropColumn(['hide_time', 'hide_user_id']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,6 +33,7 @@ class UpdateAction extends SerializeResourceAction
|
||||||
*/
|
*/
|
||||||
public $include = [
|
public $include = [
|
||||||
'editUser' => true,
|
'editUser' => true,
|
||||||
|
'discussion' => true
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -27,9 +27,15 @@ class DiscussionSerializer extends DiscussionBasicSerializer
|
||||||
'lastPostNumber' => $discussion->last_post_number,
|
'lastPostNumber' => $discussion->last_post_number,
|
||||||
'canReply' => $discussion->can($this->actor, 'reply'),
|
'canReply' => $discussion->can($this->actor, 'reply'),
|
||||||
'canRename' => $discussion->can($this->actor, 'rename'),
|
'canRename' => $discussion->can($this->actor, 'rename'),
|
||||||
'canDelete' => $discussion->can($this->actor, 'delete')
|
'canDelete' => $discussion->can($this->actor, 'delete'),
|
||||||
|
'canHide' => $discussion->can($this->actor, 'hide')
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if ($discussion->hide_time) {
|
||||||
|
$attributes['isHidden'] = true;
|
||||||
|
$attributes['hideTime'] = $discussion->hide_time->toRFC3339String();
|
||||||
|
}
|
||||||
|
|
||||||
Discussion::setStateUser($this->actor);
|
Discussion::setStateUser($this->actor);
|
||||||
|
|
||||||
if ($state = $discussion->state) {
|
if ($state = $discussion->state) {
|
||||||
|
@ -41,4 +47,12 @@ class DiscussionSerializer extends DiscussionBasicSerializer
|
||||||
|
|
||||||
return $attributes;
|
return $attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return callable
|
||||||
|
*/
|
||||||
|
public function hideUser()
|
||||||
|
{
|
||||||
|
return $this->hasOne('Flarum\Api\Serializers\UserSerializer');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,16 @@ class EditDiscussionHandler
|
||||||
$discussion->rename($attributes['title'], $actor);
|
$discussion->rename($attributes['title'], $actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($attributes['isHidden'])) {
|
||||||
|
$discussion->assertCan($actor, 'hide');
|
||||||
|
|
||||||
|
if ($attributes['isHidden']) {
|
||||||
|
$discussion->hide($actor);
|
||||||
|
} else {
|
||||||
|
$discussion->restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
event(new DiscussionWillBeSaved($discussion, $actor, $data));
|
event(new DiscussionWillBeSaved($discussion, $actor, $data));
|
||||||
|
|
||||||
$discussion->save();
|
$discussion->save();
|
||||||
|
|
|
@ -14,6 +14,8 @@ use Flarum\Core\Model;
|
||||||
use Flarum\Events\DiscussionWasDeleted;
|
use Flarum\Events\DiscussionWasDeleted;
|
||||||
use Flarum\Events\DiscussionWasStarted;
|
use Flarum\Events\DiscussionWasStarted;
|
||||||
use Flarum\Events\DiscussionWasRenamed;
|
use Flarum\Events\DiscussionWasRenamed;
|
||||||
|
use Flarum\Events\DiscussionWasHidden;
|
||||||
|
use Flarum\Events\DiscussionWasRestored;
|
||||||
use Flarum\Events\PostWasDeleted;
|
use Flarum\Events\PostWasDeleted;
|
||||||
use Flarum\Events\ScopePostVisibility;
|
use Flarum\Events\ScopePostVisibility;
|
||||||
use Flarum\Core\Posts\Post;
|
use Flarum\Core\Posts\Post;
|
||||||
|
@ -68,7 +70,7 @@ class Discussion extends Model
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
protected $dates = ['start_time', 'last_time'];
|
protected $dates = ['start_time', 'last_time', 'hide_time'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The user for which the state relationship should be loaded.
|
* The user for which the state relationship should be loaded.
|
||||||
|
@ -147,6 +149,41 @@ class Discussion extends Model
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide the discussion.
|
||||||
|
*
|
||||||
|
* @param User $actor
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function hide(User $actor = null)
|
||||||
|
{
|
||||||
|
if (! $this->hide_time) {
|
||||||
|
$this->hide_time = time();
|
||||||
|
$this->hide_user_id = $actor ? $actor->id : null;
|
||||||
|
|
||||||
|
$this->raise(new DiscussionWasHidden($this));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore the discussion.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function restore()
|
||||||
|
{
|
||||||
|
if ($this->hide_time !== null) {
|
||||||
|
$this->hide_time = null;
|
||||||
|
$this->hide_user_id = null;
|
||||||
|
|
||||||
|
$this->raise(new DiscussionWasRestored($this));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the discussion's start post details.
|
* Set the discussion's start post details.
|
||||||
*
|
*
|
||||||
|
|
|
@ -15,7 +15,7 @@ use Flarum\Core\Users\User;
|
||||||
use Flarum\Events\ModelAllow;
|
use Flarum\Events\ModelAllow;
|
||||||
use Flarum\Events\ScopeModelVisibility;
|
use Flarum\Events\ScopeModelVisibility;
|
||||||
use Flarum\Events\RegisterDiscussionGambits;
|
use Flarum\Events\RegisterDiscussionGambits;
|
||||||
use Flarum\Events\ScopeEmptyDiscussionVisibility;
|
use Flarum\Events\ScopeHiddenDiscussionVisibility;
|
||||||
use Flarum\Support\ServiceProvider;
|
use Flarum\Support\ServiceProvider;
|
||||||
use Flarum\Extend;
|
use Flarum\Extend;
|
||||||
use Illuminate\Contracts\Container\Container;
|
use Illuminate\Contracts\Container\Container;
|
||||||
|
@ -58,12 +58,15 @@ class DiscussionsServiceProvider extends ServiceProvider
|
||||||
|
|
||||||
$events->listen(ScopeModelVisibility::class, function (ScopeModelVisibility $event) {
|
$events->listen(ScopeModelVisibility::class, function (ScopeModelVisibility $event) {
|
||||||
if ($event->model instanceof Discussion) {
|
if ($event->model instanceof Discussion) {
|
||||||
if (! $event->actor->hasPermission('discussion.editPosts')) {
|
$user = $event->actor;
|
||||||
$event->query->where(function ($query) use ($event) {
|
|
||||||
$query->where('comments_count', '>', '0')
|
|
||||||
->orWhere('start_user_id', $event->actor->id);
|
|
||||||
|
|
||||||
event(new ScopeEmptyDiscussionVisibility($query, $event->actor));
|
if (! $user->hasPermission('discussion.hide')) {
|
||||||
|
$event->query->where(function ($query) use ($user) {
|
||||||
|
$query->whereNull('discussions.hide_time')
|
||||||
|
->where('comments_count', '>', 0)
|
||||||
|
->orWhere('start_user_id', $user->id);
|
||||||
|
|
||||||
|
event(new ScopeHiddenDiscussionVisibility($query, $user, 'discussion.hide'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,8 +89,10 @@ class DiscussionsServiceProvider extends ServiceProvider
|
||||||
->needs('Flarum\Core\Search\GambitManager')
|
->needs('Flarum\Core\Search\GambitManager')
|
||||||
->give(function (Container $app) {
|
->give(function (Container $app) {
|
||||||
$gambits = new GambitManager($app);
|
$gambits = new GambitManager($app);
|
||||||
|
|
||||||
$gambits->setFulltextGambit('Flarum\Core\Discussions\Search\Gambits\FulltextGambit');
|
$gambits->setFulltextGambit('Flarum\Core\Discussions\Search\Gambits\FulltextGambit');
|
||||||
$gambits->add('Flarum\Core\Discussions\Search\Gambits\AuthorGambit');
|
$gambits->add('Flarum\Core\Discussions\Search\Gambits\AuthorGambit');
|
||||||
|
$gambits->add('Flarum\Core\Discussions\Search\Gambits\HiddenGambit');
|
||||||
$gambits->add('Flarum\Core\Discussions\Search\Gambits\UnreadGambit');
|
$gambits->add('Flarum\Core\Discussions\Search\Gambits\UnreadGambit');
|
||||||
|
|
||||||
event(new RegisterDiscussionGambits($gambits));
|
event(new RegisterDiscussionGambits($gambits));
|
||||||
|
|
42
src/Core/Discussions/Search/Gambits/HiddenGambit.php
Normal file
42
src/Core/Discussions/Search/Gambits/HiddenGambit.php
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Flarum.
|
||||||
|
*
|
||||||
|
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Flarum\Core\Discussions\Search\Gambits;
|
||||||
|
|
||||||
|
use Flarum\Core\Discussions\Search\DiscussionSearch;
|
||||||
|
use Flarum\Core\Search\RegexGambit;
|
||||||
|
use Flarum\Core\Search\Search;
|
||||||
|
use LogicException;
|
||||||
|
|
||||||
|
class HiddenGambit extends RegexGambit
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected $pattern = 'is:hidden';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function conditions(Search $search, array $matches, $negate)
|
||||||
|
{
|
||||||
|
if (! $search instanceof DiscussionSearch) {
|
||||||
|
throw new LogicException('This gambit can only be applied on a DiscussionSearch');
|
||||||
|
}
|
||||||
|
|
||||||
|
$search->getQuery()->where(function ($query) use ($negate) {
|
||||||
|
if ($negate) {
|
||||||
|
$query->whereNull('hide_time')->where('comments_count', '>', 0);
|
||||||
|
} else {
|
||||||
|
$query->whereNotNull('hide_time')->orWhere('comments_count', 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
31
src/Events/DiscussionWasHidden.php
Normal file
31
src/Events/DiscussionWasHidden.php
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Flarum.
|
||||||
|
*
|
||||||
|
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Flarum\Events;
|
||||||
|
|
||||||
|
use Flarum\Core\Discussions\Discussion;
|
||||||
|
|
||||||
|
class DiscussionWasHidden
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The discussion that was hidden.
|
||||||
|
*
|
||||||
|
* @var Discussion
|
||||||
|
*/
|
||||||
|
public $discussion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Discussion $discussion
|
||||||
|
*/
|
||||||
|
public function __construct(Discussion $discussion)
|
||||||
|
{
|
||||||
|
$this->discussion = $discussion;
|
||||||
|
}
|
||||||
|
}
|
31
src/Events/DiscussionWasRestored.php
Normal file
31
src/Events/DiscussionWasRestored.php
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Flarum.
|
||||||
|
*
|
||||||
|
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Flarum\Events;
|
||||||
|
|
||||||
|
use Flarum\Core\Discussions\Discussion;
|
||||||
|
|
||||||
|
class DiscussionWasRestored
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The discussion that was restored.
|
||||||
|
*
|
||||||
|
* @var Discussion
|
||||||
|
*/
|
||||||
|
public $discussion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Discussion $discussion
|
||||||
|
*/
|
||||||
|
public function __construct(Discussion $discussion)
|
||||||
|
{
|
||||||
|
$this->discussion = $discussion;
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,9 +14,9 @@ use Flarum\Core\Users\User;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The `ScopeEmptyDiscussionVisibility` event
|
* The `ScopeHiddenDiscussionVisibility` event
|
||||||
*/
|
*/
|
||||||
class ScopeEmptyDiscussionVisibility
|
class ScopeHiddenDiscussionVisibility
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var Builder
|
* @var Builder
|
||||||
|
@ -28,13 +28,20 @@ class ScopeEmptyDiscussionVisibility
|
||||||
*/
|
*/
|
||||||
public $actor;
|
public $actor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $permission;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Builder $query
|
* @param Builder $query
|
||||||
* @param User $actor
|
* @param User $actor
|
||||||
|
* @param string $permission
|
||||||
*/
|
*/
|
||||||
public function __construct(Builder $query, User $actor)
|
public function __construct(Builder $query, User $actor, $permission)
|
||||||
{
|
{
|
||||||
$this->query = $query;
|
$this->query = $query;
|
||||||
$this->actor = $actor;
|
$this->actor = $actor;
|
||||||
|
$this->permission = $permission;
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user