mirror of
https://github.com/flarum/framework.git
synced 2025-04-25 22:24:04 +08:00
Initial commit
This commit is contained in:
commit
3787cc413e
4
extensions/sticky/.gitignore
vendored
Normal file
4
extensions/sticky/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
/vendor
|
||||
composer.phar
|
||||
.DS_Store
|
||||
Thumbs.db
|
21
extensions/sticky/LICENSE.txt
Normal file
21
extensions/sticky/LICENSE.txt
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2015 Toby Zerner
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
9
extensions/sticky/bootstrap.php
Normal file
9
extensions/sticky/bootstrap.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
// Require the extension's composer autoload file. This will enable all of our
|
||||
// classes in the src directory to be autoloaded.
|
||||
require __DIR__.'/vendor/autoload.php';
|
||||
|
||||
// Register our service provider with the Flarum application. In here we can
|
||||
// register bindings and execute code when the application boots.
|
||||
return $app->register('Flarum\Sticky\StickyServiceProvider');
|
19
extensions/sticky/composer.json
Normal file
19
extensions/sticky/composer.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "flarum/sticky",
|
||||
"description": "",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Toby Zerner",
|
||||
"email": "toby@flarum.org"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Flarum\\Sticky\\": "src/"
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev"
|
||||
}
|
15
extensions/sticky/extension.json
Normal file
15
extensions/sticky/extension.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "sticky",
|
||||
"description": "Pin discussions to the top of the list.",
|
||||
"version": "0.1.0",
|
||||
"author": {
|
||||
"name": "Toby Zerner",
|
||||
"email": "toby@flarum.org",
|
||||
"website": "http://tobyzerner.com"
|
||||
},
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": ">=5.4.0",
|
||||
"flarum": ">1.0.0"
|
||||
}
|
||||
}
|
4
extensions/sticky/js/.gitignore
vendored
Normal file
4
extensions/sticky/js/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
bower_components
|
||||
node_modules
|
||||
mithril.js
|
||||
dist
|
45
extensions/sticky/js/Gulpfile.js
Normal file
45
extensions/sticky/js/Gulpfile.js
Normal file
@ -0,0 +1,45 @@
|
||||
var gulp = require('gulp');
|
||||
var livereload = require('gulp-livereload');
|
||||
var concat = require('gulp-concat');
|
||||
var argv = require('yargs').argv;
|
||||
var uglify = require('gulp-uglify');
|
||||
var gulpif = require('gulp-if');
|
||||
var babel = require('gulp-babel');
|
||||
var cached = require('gulp-cached');
|
||||
var remember = require('gulp-remember');
|
||||
var merge = require('merge-stream');
|
||||
var streamqueue = require('streamqueue');
|
||||
|
||||
var staticFiles = [
|
||||
'bootstrap.js'
|
||||
];
|
||||
var moduleFiles = [
|
||||
'src/**/*.js'
|
||||
];
|
||||
var modulePrefix = 'sticky';
|
||||
|
||||
gulp.task('default', function() {
|
||||
return streamqueue({objectMode: true},
|
||||
gulp.src(moduleFiles)
|
||||
.pipe(cached('scripts'))
|
||||
.pipe(babel({ modules: 'amd', moduleIds: true, moduleRoot: modulePrefix }))
|
||||
.pipe(remember('scripts')),
|
||||
gulp.src(staticFiles)
|
||||
.pipe(babel())
|
||||
)
|
||||
.pipe(concat('extension.js'))
|
||||
.pipe(gulpif(argv.production, uglify()))
|
||||
.pipe(gulp.dest('dist'))
|
||||
.pipe(livereload());
|
||||
});
|
||||
|
||||
gulp.task('watch', ['default'], function () {
|
||||
livereload.listen();
|
||||
var watcher = gulp.watch(moduleFiles.concat(staticFiles), ['default']);
|
||||
watcher.on('change', function (event) {
|
||||
if (event.type === 'deleted') {
|
||||
delete cached.caches.scripts[event.path];
|
||||
remember.forget('scripts', event.path);
|
||||
}
|
||||
});
|
||||
});
|
60
extensions/sticky/js/bootstrap.js
vendored
Normal file
60
extensions/sticky/js/bootstrap.js
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
import { extend } from 'flarum/extension-utils';
|
||||
import Model from 'flarum/model';
|
||||
import Discussion from 'flarum/models/discussion';
|
||||
import DiscussionPage from 'flarum/components/discussion-page';
|
||||
import Badge from 'flarum/components/badge';
|
||||
import ActionButton from 'flarum/components/action-button';
|
||||
import SettingsPage from 'flarum/components/settings-page';
|
||||
import icon from 'flarum/helpers/icon';
|
||||
import app from 'flarum/app';
|
||||
|
||||
import PostDiscussionStickied from 'sticky/components/post-discussion-stickied';
|
||||
import NotificationDiscussionStickied from 'sticky/components/notification-discussion-stickied';
|
||||
|
||||
app.initializers.add('sticky', function() {
|
||||
|
||||
// Register components.
|
||||
app.postComponentRegistry['discussionStickied'] = PostDiscussionStickied;
|
||||
app.notificationComponentRegistry['discussionStickied'] = NotificationDiscussionStickied;
|
||||
|
||||
Discussion.prototype.isSticky = Model.prop('isSticky');
|
||||
|
||||
// Add a sticky badge to discussions.
|
||||
extend(Discussion.prototype, 'badges', function(badges) {
|
||||
if (this.isSticky()) {
|
||||
badges.add('sticky', Badge.component({
|
||||
label: 'Sticky',
|
||||
icon: 'thumb-tack',
|
||||
className: 'badge-sticky',
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
function toggleSticky() {
|
||||
this.save({isSticky: !this.isSticky()}).then(discussion => {
|
||||
if (app.current instanceof DiscussionPage) {
|
||||
app.current.stream().sync();
|
||||
}
|
||||
m.redraw();
|
||||
});
|
||||
}
|
||||
|
||||
// Add a sticky control to discussions.
|
||||
extend(Discussion.prototype, 'controls', function(items) {
|
||||
if (this.canEdit()) {
|
||||
items.add('sticky', ActionButton.component({
|
||||
label: this.isSticky() ? 'Unsticky' : 'Sticky',
|
||||
icon: 'thumb-tack',
|
||||
onclick: toggleSticky.bind(this)
|
||||
}), {after: 'rename'});
|
||||
}
|
||||
});
|
||||
|
||||
// Add a notification preference.
|
||||
extend(SettingsPage.prototype, 'notificationTypes', function(items) {
|
||||
items.add('discussionStickied', {
|
||||
name: 'discussionStickied',
|
||||
label: [icon('thumb-tack'), ' Someone stickies a discussion I started']
|
||||
});
|
||||
});
|
||||
});
|
18
extensions/sticky/js/package.json
Normal file
18
extensions/sticky/js/package.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "flarum-sticky",
|
||||
"devDependencies": {
|
||||
"gulp": "^3.8.11",
|
||||
"gulp-babel": "^5.1.0",
|
||||
"gulp-cached": "^1.0.4",
|
||||
"gulp-concat": "^2.5.2",
|
||||
"gulp-if": "^1.2.5",
|
||||
"gulp-livereload": "^3.8.0",
|
||||
"gulp-remember": "^0.3.0",
|
||||
"gulp-uglify": "^1.2.0",
|
||||
"merge-stream": "^0.1.7",
|
||||
"yargs": "^3.7.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"streamqueue": "^0.1.3"
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
import Notification from 'flarum/components/notification';
|
||||
import username from 'flarum/helpers/username';
|
||||
|
||||
export default class NotificationDiscussionStickied extends Notification {
|
||||
view() {
|
||||
var notification = this.props.notification;
|
||||
var discussion = notification.subject();
|
||||
|
||||
return super.view({
|
||||
href: app.route('discussion.near', {
|
||||
id: discussion.id(),
|
||||
slug: discussion.slug(),
|
||||
near: notification.content().postNumber
|
||||
}),
|
||||
config: m.route,
|
||||
title: discussion.title(),
|
||||
icon: 'thumb-tack',
|
||||
content: ['Stickied by ', username(notification.sender())]
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
import PostActivity from 'flarum/components/post-activity';
|
||||
|
||||
export default class PostDiscussionStickied extends PostActivity {
|
||||
view() {
|
||||
var post = this.props.post;
|
||||
|
||||
return super.view('thumb-tack', [post.content().sticky ? 'stickied' : 'unstickied', ' the discussion.']);
|
||||
}
|
||||
}
|
8
extensions/sticky/less/sticky.less
Normal file
8
extensions/sticky/less/sticky.less
Normal file
@ -0,0 +1,8 @@
|
||||
.badge-sticky {
|
||||
background: #d13e32;
|
||||
}
|
||||
.post-discussion-stickied {
|
||||
& .post-icon, & .post-activity-info, & .post-activity-info a {
|
||||
color: #d13e32;
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddStickyToDiscussions extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('discussions', function (Blueprint $table) {
|
||||
$table->boolean('is_sticky')->default(0);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('discussions', function (Blueprint $table) {
|
||||
$table->dropColumn('is_sticky');
|
||||
});
|
||||
}
|
||||
}
|
39
extensions/sticky/src/DiscussionStickiedNotification.php
Normal file
39
extensions/sticky/src/DiscussionStickiedNotification.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php namespace Flarum\Sticky;
|
||||
|
||||
use Flarum\Core\Models\User;
|
||||
use Flarum\Core\Notifications\Types\Notification;
|
||||
use Flarum\Core\Notifications\Types\AlertableNotification;
|
||||
|
||||
class DiscussionStickiedNotification extends Notification implements AlertableNotification
|
||||
{
|
||||
public $post;
|
||||
|
||||
public function __construct(User $recipient, User $sender, DiscussionStickiedPost $post)
|
||||
{
|
||||
$this->post = $post;
|
||||
|
||||
parent::__construct($recipient, $sender);
|
||||
}
|
||||
|
||||
public function getSubject()
|
||||
{
|
||||
return $this->post->discussion;
|
||||
}
|
||||
|
||||
public function getAlertData()
|
||||
{
|
||||
return [
|
||||
'postNumber' => $this->post->number
|
||||
];
|
||||
}
|
||||
|
||||
public static function getType()
|
||||
{
|
||||
return 'discussionStickied';
|
||||
}
|
||||
|
||||
public static function getSubjectModel()
|
||||
{
|
||||
return 'Flarum\Core\Models\Discussion';
|
||||
}
|
||||
}
|
66
extensions/sticky/src/DiscussionStickiedPost.php
Executable file
66
extensions/sticky/src/DiscussionStickiedPost.php
Executable file
@ -0,0 +1,66 @@
|
||||
<?php namespace Flarum\Sticky;
|
||||
|
||||
use Flarum\Core\Models\Model;
|
||||
use Flarum\Core\Models\ActivityPost;
|
||||
|
||||
class DiscussionStickiedPost extends ActivityPost
|
||||
{
|
||||
/**
|
||||
* The type of post this is, to be stored in the posts table.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $type = 'discussionStickied';
|
||||
|
||||
/**
|
||||
* Merge the post into another post of the same type.
|
||||
*
|
||||
* @param \Flarum\Core\Models\DiscussionRenamedPost $previous
|
||||
* @return \Flarum\Core\Models\Model|null The final model, or null if the
|
||||
* previous post was deleted.
|
||||
*/
|
||||
protected function mergeInto(Model $previous)
|
||||
{
|
||||
if ($this->user_id === $previous->user_id) {
|
||||
if ($previous->content['sticky'] != $this->content['sticky']) {
|
||||
return;
|
||||
}
|
||||
|
||||
$previous->content = $this->content;
|
||||
return $previous;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance in reply to a discussion.
|
||||
*
|
||||
* @param integer $discussionId
|
||||
* @param integer $userId
|
||||
* @param boolean $isSticky
|
||||
* @return static
|
||||
*/
|
||||
public static function reply($discussionId, $userId, $isSticky)
|
||||
{
|
||||
$post = new static;
|
||||
|
||||
$post->content = static::buildContent($isSticky);
|
||||
$post->time = time();
|
||||
$post->discussion_id = $discussionId;
|
||||
$post->user_id = $userId;
|
||||
|
||||
return $post;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the content attribute.
|
||||
*
|
||||
* @param boolean $isSticky Whether or not the discussion is stickied.
|
||||
* @return array
|
||||
*/
|
||||
public static function buildContent($isSticky)
|
||||
{
|
||||
return ['sticky' => (bool) $isSticky];
|
||||
}
|
||||
}
|
27
extensions/sticky/src/Events/DiscussionWasStickied.php
Normal file
27
extensions/sticky/src/Events/DiscussionWasStickied.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php namespace Flarum\Sticky\Events;
|
||||
|
||||
use Flarum\Core\Models\Discussion;
|
||||
use Flarum\Core\Models\User;
|
||||
|
||||
class DiscussionWasStickied
|
||||
{
|
||||
/**
|
||||
* @var \Flarum\Core\Models\Discussion
|
||||
*/
|
||||
public $discussion;
|
||||
|
||||
/**
|
||||
* @var \Flarum\Core\Models\User
|
||||
*/
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* @param \Flarum\Core\Models\Discussion $discussion
|
||||
* @param \Flarum\Core\Models\User $user
|
||||
*/
|
||||
public function __construct(Discussion $discussion, User $user)
|
||||
{
|
||||
$this->discussion = $discussion;
|
||||
$this->user = $user;
|
||||
}
|
||||
}
|
27
extensions/sticky/src/Events/DiscussionWasUnstickied.php
Normal file
27
extensions/sticky/src/Events/DiscussionWasUnstickied.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php namespace Flarum\Sticky\Events;
|
||||
|
||||
use Flarum\Core\Models\Discussion;
|
||||
use Flarum\Core\Models\User;
|
||||
|
||||
class DiscussionWasUnstickied
|
||||
{
|
||||
/**
|
||||
* @var \Flarum\Core\Models\Discussion
|
||||
*/
|
||||
public $discussion;
|
||||
|
||||
/**
|
||||
* @var \Flarum\Core\Models\User
|
||||
*/
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* @param \Flarum\Core\Models\Discussion $discussion
|
||||
* @param \Flarum\Core\Models\User $user
|
||||
*/
|
||||
public function __construct(Discussion $discussion, User $user)
|
||||
{
|
||||
$this->discussion = $discussion;
|
||||
$this->user = $user;
|
||||
}
|
||||
}
|
67
extensions/sticky/src/Handlers/DiscussionStickiedNotifier.php
Executable file
67
extensions/sticky/src/Handlers/DiscussionStickiedNotifier.php
Executable file
@ -0,0 +1,67 @@
|
||||
<?php namespace Flarum\Sticky\Handlers;
|
||||
|
||||
use Flarum\Sticky\DiscussionStickiedPost;
|
||||
use Flarum\Sticky\DiscussionStickiedNotification;
|
||||
use Flarum\Sticky\Events\DiscussionWasStickied;
|
||||
use Flarum\Sticky\Events\DiscussionWasUnstickied;
|
||||
use Flarum\Core\Notifications\Notifier;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
|
||||
class DiscussionStickiedNotifier
|
||||
{
|
||||
protected $notifier;
|
||||
|
||||
public function __construct(Notifier $notifier)
|
||||
{
|
||||
$this->notifier = $notifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the listeners for the subscriber.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Events\Dispatcher $events
|
||||
*/
|
||||
public function subscribe(Dispatcher $events)
|
||||
{
|
||||
$events->listen('Flarum\Sticky\Events\DiscussionWasStickied', __CLASS__.'@whenDiscussionWasStickied');
|
||||
$events->listen('Flarum\Sticky\Events\DiscussionWasUnstickied', __CLASS__.'@whenDiscussionWasUnstickied');
|
||||
}
|
||||
|
||||
public function whenDiscussionWasStickied(DiscussionWasStickied $event)
|
||||
{
|
||||
$post = $this->createPost($event->discussion->id, $event->user->id, true);
|
||||
|
||||
$post = $event->discussion->addPost($post);
|
||||
|
||||
if ($event->discussion->start_user_id !== $event->user->id) {
|
||||
$this->sendNotification($post);
|
||||
}
|
||||
}
|
||||
|
||||
public function whenDiscussionWasUnstickied(DiscussionWasUnstickied $event)
|
||||
{
|
||||
$post = $this->createPost($event->discussion->id, $event->user->id, false);
|
||||
|
||||
$event->discussion->addPost($post);
|
||||
}
|
||||
|
||||
protected function createPost($discussionId, $userId, $isSticky)
|
||||
{
|
||||
return DiscussionStickiedPost::reply(
|
||||
$discussionId,
|
||||
$userId,
|
||||
$isSticky
|
||||
);
|
||||
}
|
||||
|
||||
protected function sendNotification(DiscussionStickiedPost $post)
|
||||
{
|
||||
$notification = new DiscussionStickiedNotification(
|
||||
$post->discussion->startUser,
|
||||
$post->user,
|
||||
$post
|
||||
);
|
||||
|
||||
$this->notifier->send($notification);
|
||||
}
|
||||
}
|
34
extensions/sticky/src/Handlers/StickySaver.php
Executable file
34
extensions/sticky/src/Handlers/StickySaver.php
Executable file
@ -0,0 +1,34 @@
|
||||
<?php namespace Flarum\Sticky\Handlers;
|
||||
|
||||
use Flarum\Sticky\Events\DiscussionWasStickied;
|
||||
use Flarum\Sticky\Events\DiscussionWasUnstickied;
|
||||
use Flarum\Core\Events\DiscussionWillBeSaved;
|
||||
|
||||
class StickySaver
|
||||
{
|
||||
public function subscribe($events)
|
||||
{
|
||||
$events->listen('Flarum\Core\Events\DiscussionWillBeSaved', __CLASS__.'@whenDiscussionWillBeSaved');
|
||||
}
|
||||
|
||||
public function whenDiscussionWillBeSaved(DiscussionWillBeSaved $event)
|
||||
{
|
||||
if (isset($event->command->data['isSticky'])) {
|
||||
$isSticky = (bool) $event->command->data['isSticky'];
|
||||
$discussion = $event->discussion;
|
||||
$user = $event->command->user;
|
||||
|
||||
if ((bool) $discussion->is_sticky === $isSticky) {
|
||||
return;
|
||||
}
|
||||
|
||||
$discussion->is_sticky = $isSticky;
|
||||
|
||||
$discussion->raise(
|
||||
$discussion->is_sticky
|
||||
? new DiscussionWasStickied($discussion, $user)
|
||||
: new DiscussionWasUnstickied($discussion, $user)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
37
extensions/sticky/src/Handlers/StickySearchModifier.php
Executable file
37
extensions/sticky/src/Handlers/StickySearchModifier.php
Executable file
@ -0,0 +1,37 @@
|
||||
<?php namespace Flarum\Sticky\Handlers;
|
||||
|
||||
use Flarum\Core\Events\DiscussionSearchWillBePerformed;
|
||||
use Flarum\Categories\CategoryGambit;
|
||||
|
||||
class StickySearchModifier
|
||||
{
|
||||
public function subscribe($events)
|
||||
{
|
||||
$events->listen('Flarum\Core\Events\DiscussionSearchWillBePerformed', __CLASS__.'@reorderSearch');
|
||||
}
|
||||
|
||||
public function reorderSearch(DiscussionSearchWillBePerformed $event)
|
||||
{
|
||||
if ($event->criteria->sort === null) {
|
||||
$query = $event->searcher->query();
|
||||
|
||||
foreach ($event->searcher->getActiveGambits() as $gambit) {
|
||||
if ($gambit instanceof CategoryGambit) {
|
||||
array_unshift($query->orders, ['column' => 'is_sticky', 'direction' => 'desc']);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$query->leftJoin('users_discussions', function ($join) use ($event) {
|
||||
$join->on('users_discussions.discussion_id', '=', 'discussions.id')
|
||||
->where('discussions.is_sticky', '=', true)
|
||||
->where('users_discussions.user_id', '=', $event->criteria->user->id);
|
||||
});
|
||||
// might be quicker to do a subquery in the order clause than a join?
|
||||
array_unshift(
|
||||
$query->orders,
|
||||
['type' => 'raw', 'sql' => '(is_sticky AND (users_discussions.read_number IS NULL OR discussions.last_post_number > users_discussions.read_number)) desc']
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
29
extensions/sticky/src/StickyGambit.php
Normal file
29
extensions/sticky/src/StickyGambit.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php namespace Flarum\Sticky;
|
||||
|
||||
use Flarum\Core\Search\SearcherInterface;
|
||||
use Flarum\Core\Search\GambitAbstract;
|
||||
|
||||
class StickyGambit extends GambitAbstract
|
||||
{
|
||||
/**
|
||||
* The gambit's regex pattern.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $pattern = 'sticky:(true|false)';
|
||||
|
||||
/**
|
||||
* Apply conditions to the searcher, given matches from the gambit's
|
||||
* regex.
|
||||
*
|
||||
* @param array $matches The matches from the gambit's regex.
|
||||
* @param \Flarum\Core\Search\SearcherInterface $searcher
|
||||
* @return void
|
||||
*/
|
||||
public function conditions($matches, SearcherInterface $searcher)
|
||||
{
|
||||
$sticky = $matches[1] === 'true';
|
||||
|
||||
$searcher->query()->where('is_sticky', $sticky);
|
||||
}
|
||||
}
|
34
extensions/sticky/src/StickyServiceProvider.php
Normal file
34
extensions/sticky/src/StickyServiceProvider.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php namespace Flarum\Sticky;
|
||||
|
||||
use Flarum\Support\ServiceProvider;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
|
||||
class StickyServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap the application events.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot(Dispatcher $events)
|
||||
{
|
||||
$events->subscribe('Flarum\Sticky\Handlers\StickySaver');
|
||||
$events->subscribe('Flarum\Sticky\Handlers\StickySearchModifier');
|
||||
$events->subscribe('Flarum\Sticky\Handlers\DiscussionStickiedNotifier');
|
||||
|
||||
$this->forumAssets([
|
||||
__DIR__.'/../js/dist/extension.js',
|
||||
__DIR__.'/../less/sticky.less'
|
||||
]);
|
||||
|
||||
$this->postType('Flarum\Sticky\DiscussionStickiedPost');
|
||||
|
||||
$this->serializeAttributes('Flarum\Api\Serializers\DiscussionSerializer', function (&$attributes, $model) {
|
||||
$attributes['isSticky'] = (bool) $model->is_sticky;
|
||||
});
|
||||
|
||||
$this->discussionGambit('Flarum\Sticky\StickyGambit');
|
||||
|
||||
$this->notificationType('Flarum\Sticky\DiscussionStickiedNotification', ['alert' => true]);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user