From fca470604e5664f6556beb823cf73ba40326f8fe Mon Sep 17 00:00:00 2001 From: Toby Zerner Date: Sun, 11 Oct 2015 16:15:07 +1030 Subject: [PATCH] Update for composer branch --- extensions/lock/.gitignore | 2 + extensions/lock/bootstrap.php | 14 +- extensions/lock/composer.json | 28 ++- extensions/lock/flarum.json | 25 --- extensions/lock/js/.gitignore | 4 - extensions/lock/js/admin/Gulpfile.js | 2 +- extensions/lock/js/admin/dist/extension.js | 26 +++ extensions/lock/js/forum/Gulpfile.js | 2 +- extensions/lock/js/forum/dist/extension.js | 192 ++++++++++++++++++ extensions/lock/js/forum/src/addLockBadge.js | 2 +- .../lock/js/forum/src/addLockControl.js | 2 +- .../DiscussionLockedNotification.js | 2 +- .../src/components/DiscussionLockedPost.js | 4 +- extensions/lock/js/forum/src/main.js | 34 ++-- extensions/lock/locale/en.yml | 8 - ...02_24_000000_add_locked_to_discussions.php | 16 +- extensions/lock/scripts/compile.sh | 27 +++ .../lock/src/Access/DiscussionPolicy.php | 36 ++++ .../{Events => Event}/DiscussionWasLocked.php | 6 +- .../DiscussionWasUnlocked.php | 6 +- extensions/lock/src/Extension.php | 26 --- .../LockedGambit.php} | 16 +- .../lock/src/Listener/AddClientAssets.php | 48 +++++ .../AddDiscussionLockedAttributes.php | 37 ++++ .../lock/src/Listener/AddLockedGambit.php | 34 ++++ .../CreatePostWhenDiscussionIsLocked.php | 104 ++++++++++ .../SaveLockedToDatabase.php} | 24 ++- .../lock/src/Listeners/AddApiAttributes.php | 31 --- .../lock/src/Listeners/AddClientAssets.php | 55 ----- .../src/Listeners/ConfigurePermissions.php | 33 --- .../src/Listeners/NotifyDiscussionLocked.php | 81 -------- .../DiscussionLockedBlueprint.php | 32 ++- .../{Posts => Post}/DiscussionLockedPost.php | 16 +- 33 files changed, 644 insertions(+), 331 deletions(-) delete mode 100644 extensions/lock/flarum.json delete mode 100644 extensions/lock/js/.gitignore create mode 100644 extensions/lock/js/admin/dist/extension.js create mode 100644 extensions/lock/js/forum/dist/extension.js delete mode 100644 extensions/lock/locale/en.yml create mode 100755 extensions/lock/scripts/compile.sh create mode 100755 extensions/lock/src/Access/DiscussionPolicy.php rename extensions/lock/src/{Events => Event}/DiscussionWasLocked.php (85%) rename extensions/lock/src/{Events => Event}/DiscussionWasUnlocked.php (85%) delete mode 100644 extensions/lock/src/Extension.php rename extensions/lock/src/{Gambits/LockGambit.php => Gambit/LockedGambit.php} (51%) create mode 100755 extensions/lock/src/Listener/AddClientAssets.php create mode 100755 extensions/lock/src/Listener/AddDiscussionLockedAttributes.php create mode 100755 extensions/lock/src/Listener/AddLockedGambit.php create mode 100755 extensions/lock/src/Listener/CreatePostWhenDiscussionIsLocked.php rename extensions/lock/src/{Listeners/PersistData.php => Listener/SaveLockedToDatabase.php} (66%) delete mode 100755 extensions/lock/src/Listeners/AddApiAttributes.php delete mode 100755 extensions/lock/src/Listeners/AddClientAssets.php delete mode 100755 extensions/lock/src/Listeners/ConfigurePermissions.php delete mode 100755 extensions/lock/src/Listeners/NotifyDiscussionLocked.php rename extensions/lock/src/{Notifications => Notification}/DiscussionLockedBlueprint.php (58%) rename extensions/lock/src/{Posts => Post}/DiscussionLockedPost.php (86%) diff --git a/extensions/lock/.gitignore b/extensions/lock/.gitignore index a4f3b125e..43eeee7fe 100644 --- a/extensions/lock/.gitignore +++ b/extensions/lock/.gitignore @@ -2,3 +2,5 @@ composer.phar .DS_Store Thumbs.db +bower_components +node_modules \ No newline at end of file diff --git a/extensions/lock/bootstrap.php b/extensions/lock/bootstrap.php index 8b5b02d82..46f9a2e84 100644 --- a/extensions/lock/bootstrap.php +++ b/extensions/lock/bootstrap.php @@ -9,6 +9,16 @@ * file that was distributed with this source code. */ -require __DIR__.'/vendor/autoload.php'; +use Flarum\Lock\Access; +use Flarum\Lock\Listener; +use Illuminate\Contracts\Events\Dispatcher; -return 'Flarum\Lock\Extension'; +return function (Dispatcher $events) { + $events->subscribe(Listener\AddClientAssets::class); + $events->subscribe(Listener\AddDiscussionLockedAttributes::class); + $events->subscribe(Listener\AddLockedGambit::class); + $events->subscribe(Listener\CreatePostWhenDiscussionIsLocked::class); + $events->subscribe(Listener\SaveLockedToDatabase::class); + + $events->subscribe(Access\DiscussionPolicy::class); +}; diff --git a/extensions/lock/composer.json b/extensions/lock/composer.json index 606d71bb9..b96e38f68 100644 --- a/extensions/lock/composer.json +++ b/extensions/lock/composer.json @@ -1,10 +1,34 @@ { + "name": "flarum/lock", + "description": "End a discussion and don't let anyone add further replies.", + "type": "flarum-extension", + "license": "MIT", + "authors": [ + { + "name": "Toby Zerner", + "email": "toby.zerner@gmail.com" + } + ], + "support": { + "issues": "https://github.com/flarum/core/issues", + "source": "https://github.com/flarum/lock" + }, + "require": { + "flarum/core": "^0.1.0-beta.3" + }, "autoload": { "psr-4": { "Flarum\\Lock\\": "src/" } }, - "scripts": { - "style": "phpcs --standard=PSR2 -np src" + "extra": { + "flarum-extension": { + "title": "Lock", + "icon": { + "name": "lock", + "backgroundColor": "#ddd", + "color": "#666" + } + } } } diff --git a/extensions/lock/flarum.json b/extensions/lock/flarum.json deleted file mode 100644 index 539298efa..000000000 --- a/extensions/lock/flarum.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "lock", - "title": "Lock", - "description": "End a discussion and don't let anyone add further replies.", - "keywords": ["moderation"], - "version": "0.1.0-beta.2", - "author": { - "name": "Toby Zerner", - "email": "toby@flarum.org", - "homepage": "http://tobyzerner.com" - }, - "license": "MIT", - "require": { - "flarum": ">=0.1.0-beta.2" - }, - "support": { - "source": "https://github.com/flarum/lock", - "issues": "https://github.com/flarum/core/issues" - }, - "icon": { - "name": "lock", - "backgroundColor": "#ddd", - "color": "#666" - } -} diff --git a/extensions/lock/js/.gitignore b/extensions/lock/js/.gitignore deleted file mode 100644 index bae304483..000000000 --- a/extensions/lock/js/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -bower_components -node_modules -mithril.js -dist diff --git a/extensions/lock/js/admin/Gulpfile.js b/extensions/lock/js/admin/Gulpfile.js index dcc422f3d..85d1f486b 100644 --- a/extensions/lock/js/admin/Gulpfile.js +++ b/extensions/lock/js/admin/Gulpfile.js @@ -2,6 +2,6 @@ var gulp = require('flarum-gulp'); gulp({ modules: { - 'lock': 'src/**/*.js' + 'flarum/lock': 'src/**/*.js' } }); diff --git a/extensions/lock/js/admin/dist/extension.js b/extensions/lock/js/admin/dist/extension.js new file mode 100644 index 000000000..672db4724 --- /dev/null +++ b/extensions/lock/js/admin/dist/extension.js @@ -0,0 +1,26 @@ +System.register('flarum/lock/main', ['flarum/extend', 'flarum/app', 'flarum/components/PermissionGrid'], function (_export) { + 'use strict'; + + var extend, app, PermissionGrid; + return { + setters: [function (_flarumExtend) { + extend = _flarumExtend.extend; + }, function (_flarumApp) { + app = _flarumApp['default']; + }, function (_flarumComponentsPermissionGrid) { + PermissionGrid = _flarumComponentsPermissionGrid['default']; + }], + execute: function () { + + app.initializers.add('lock', function () { + extend(PermissionGrid.prototype, 'moderateItems', function (items) { + items.add('lock', { + icon: 'lock', + label: 'Lock discussions', + permission: 'discussion.lock' + }, 95); + }); + }); + } + }; +}); \ No newline at end of file diff --git a/extensions/lock/js/forum/Gulpfile.js b/extensions/lock/js/forum/Gulpfile.js index dcc422f3d..85d1f486b 100644 --- a/extensions/lock/js/forum/Gulpfile.js +++ b/extensions/lock/js/forum/Gulpfile.js @@ -2,6 +2,6 @@ var gulp = require('flarum-gulp'); gulp({ modules: { - 'lock': 'src/**/*.js' + 'flarum/lock': 'src/**/*.js' } }); diff --git a/extensions/lock/js/forum/dist/extension.js b/extensions/lock/js/forum/dist/extension.js new file mode 100644 index 000000000..881921c93 --- /dev/null +++ b/extensions/lock/js/forum/dist/extension.js @@ -0,0 +1,192 @@ +System.register('flarum/lock/addLockBadge', ['flarum/extend', 'flarum/models/Discussion', 'flarum/components/Badge'], function (_export) { + 'use strict'; + + var extend, Discussion, Badge; + + _export('default', addLockBadge); + + function addLockBadge() { + extend(Discussion.prototype, 'badges', function (badges) { + if (this.isLocked()) { + badges.add('locked', Badge.component({ + type: 'locked', + label: app.trans('flarum-lock.forum.locked'), + icon: 'lock' + })); + } + }); + } + + return { + setters: [function (_flarumExtend) { + extend = _flarumExtend.extend; + }, function (_flarumModelsDiscussion) { + Discussion = _flarumModelsDiscussion['default']; + }, function (_flarumComponentsBadge) { + Badge = _flarumComponentsBadge['default']; + }], + execute: function () {} + }; +});;System.register('flarum/lock/addLockControl', ['flarum/extend', 'flarum/utils/DiscussionControls', 'flarum/components/DiscussionPage', 'flarum/components/Button'], function (_export) { + 'use strict'; + + var extend, DiscussionControls, DiscussionPage, Button; + + _export('default', addLockControl); + + function addLockControl() { + extend(DiscussionControls, 'moderationControls', function (items, discussion) { + if (discussion.canLock()) { + items.add('lock', Button.component({ + children: app.trans(discussion.isLocked() ? 'flarum-lock.forum.unlock' : 'flarum-lock.forum.lock'), + icon: 'lock', + onclick: this.lockAction.bind(discussion) + })); + } + }); + + DiscussionControls.lockAction = function () { + this.save({ isLocked: !this.isLocked() }).then(function () { + if (app.current instanceof DiscussionPage) { + app.current.stream.update(); + } + + m.redraw(); + }); + }; + } + + return { + setters: [function (_flarumExtend) { + extend = _flarumExtend.extend; + }, function (_flarumUtilsDiscussionControls) { + DiscussionControls = _flarumUtilsDiscussionControls['default']; + }, function (_flarumComponentsDiscussionPage) { + DiscussionPage = _flarumComponentsDiscussionPage['default']; + }, function (_flarumComponentsButton) { + Button = _flarumComponentsButton['default']; + }], + execute: function () {} + }; +});;System.register('flarum/lock/main', ['flarum/extend', 'flarum/app', 'flarum/Model', 'flarum/models/Discussion', 'flarum/components/NotificationGrid', 'flarum/lock/components/DiscussionLockedPost', 'flarum/lock/components/DiscussionLockedNotification', 'flarum/lock/addLockBadge', 'flarum/lock/addLockControl'], function (_export) { + 'use strict'; + + var extend, app, Model, Discussion, NotificationGrid, DiscussionLockedPost, DiscussionLockedNotification, addLockBadge, addLockControl; + return { + setters: [function (_flarumExtend) { + extend = _flarumExtend.extend; + }, function (_flarumApp) { + app = _flarumApp['default']; + }, function (_flarumModel) { + Model = _flarumModel['default']; + }, function (_flarumModelsDiscussion) { + Discussion = _flarumModelsDiscussion['default']; + }, function (_flarumComponentsNotificationGrid) { + NotificationGrid = _flarumComponentsNotificationGrid['default']; + }, function (_flarumLockComponentsDiscussionLockedPost) { + DiscussionLockedPost = _flarumLockComponentsDiscussionLockedPost['default']; + }, function (_flarumLockComponentsDiscussionLockedNotification) { + DiscussionLockedNotification = _flarumLockComponentsDiscussionLockedNotification['default']; + }, function (_flarumLockAddLockBadge) { + addLockBadge = _flarumLockAddLockBadge['default']; + }, function (_flarumLockAddLockControl) { + addLockControl = _flarumLockAddLockControl['default']; + }], + execute: function () { + + app.initializers.add('flarum-lock', function () { + app.postComponents.discussionLocked = DiscussionLockedPost; + app.notificationComponents.discussionLocked = DiscussionLockedNotification; + + Discussion.prototype.isLocked = Model.attribute('isLocked'); + Discussion.prototype.canLock = Model.attribute('canLock'); + + addLockBadge(); + addLockControl(); + + extend(NotificationGrid.prototype, 'notificationTypes', function (items) { + items.add('discussionLocked', { + name: 'discussionLocked', + icon: 'lock', + label: app.trans('flarum-lock.forum.notify_discussion_locked') + }); + }); + }); + } + }; +});;System.register('flarum/lock/components/DiscussionLockedNotification', ['flarum/components/Notification'], function (_export) { + 'use strict'; + + var Notification, DiscussionLockedNotification; + return { + setters: [function (_flarumComponentsNotification) { + Notification = _flarumComponentsNotification['default']; + }], + execute: function () { + DiscussionLockedNotification = (function (_Notification) { + babelHelpers.inherits(DiscussionLockedNotification, _Notification); + + function DiscussionLockedNotification() { + babelHelpers.classCallCheck(this, DiscussionLockedNotification); + babelHelpers.get(Object.getPrototypeOf(DiscussionLockedNotification.prototype), 'constructor', this).apply(this, arguments); + } + + babelHelpers.createClass(DiscussionLockedNotification, [{ + key: 'icon', + value: function icon() { + return 'lock'; + } + }, { + key: 'href', + value: function href() { + var notification = this.props.notification; + + return app.route.discussion(notification.subject(), notification.content().postNumber); + } + }, { + key: 'content', + value: function content() { + return app.trans('flarum-lock.forum.discussion_locked_notification', { user: this.props.notification.sender() }); + } + }]); + return DiscussionLockedNotification; + })(Notification); + + _export('default', DiscussionLockedNotification); + } + }; +});;System.register('flarum/lock/components/DiscussionLockedPost', ['flarum/components/EventPost'], function (_export) { + 'use strict'; + + var EventPost, DiscussionLockedPost; + return { + setters: [function (_flarumComponentsEventPost) { + EventPost = _flarumComponentsEventPost['default']; + }], + execute: function () { + DiscussionLockedPost = (function (_EventPost) { + babelHelpers.inherits(DiscussionLockedPost, _EventPost); + + function DiscussionLockedPost() { + babelHelpers.classCallCheck(this, DiscussionLockedPost); + babelHelpers.get(Object.getPrototypeOf(DiscussionLockedPost.prototype), 'constructor', this).apply(this, arguments); + } + + babelHelpers.createClass(DiscussionLockedPost, [{ + key: 'icon', + value: function icon() { + return this.props.post.content().locked ? 'lock' : 'unlock'; + } + }, { + key: 'descriptionKey', + value: function descriptionKey() { + return this.props.post.content().locked ? 'flarum-lock.forum.discussion_locked_post' : 'flarum-lock.forum.discussion_unlocked_post'; + } + }]); + return DiscussionLockedPost; + })(EventPost); + + _export('default', DiscussionLockedPost); + } + }; +}); \ No newline at end of file diff --git a/extensions/lock/js/forum/src/addLockBadge.js b/extensions/lock/js/forum/src/addLockBadge.js index 75482c851..b72b0d13c 100644 --- a/extensions/lock/js/forum/src/addLockBadge.js +++ b/extensions/lock/js/forum/src/addLockBadge.js @@ -7,7 +7,7 @@ export default function addLockBadge() { if (this.isLocked()) { badges.add('locked', Badge.component({ type: 'locked', - label: app.trans('lock.locked'), + label: app.trans('flarum-lock.forum.locked'), icon: 'lock' })); } diff --git a/extensions/lock/js/forum/src/addLockControl.js b/extensions/lock/js/forum/src/addLockControl.js index f30ed0601..67678cbe6 100644 --- a/extensions/lock/js/forum/src/addLockControl.js +++ b/extensions/lock/js/forum/src/addLockControl.js @@ -7,7 +7,7 @@ export default function addLockControl() { extend(DiscussionControls, 'moderationControls', function(items, discussion) { if (discussion.canLock()) { items.add('lock', Button.component({ - children: app.trans(discussion.isLocked() ? 'lock.unlock' : 'lock.lock'), + children: app.trans(discussion.isLocked() ? 'flarum-lock.forum.unlock' : 'flarum-lock.forum.lock'), icon: 'lock', onclick: this.lockAction.bind(discussion) })); diff --git a/extensions/lock/js/forum/src/components/DiscussionLockedNotification.js b/extensions/lock/js/forum/src/components/DiscussionLockedNotification.js index 83b9bffa1..629efc2f6 100644 --- a/extensions/lock/js/forum/src/components/DiscussionLockedNotification.js +++ b/extensions/lock/js/forum/src/components/DiscussionLockedNotification.js @@ -12,6 +12,6 @@ export default class DiscussionLockedNotification extends Notification { } content() { - return app.trans('lock.discussion_locked_notification', {user: this.props.notification.sender()}); + return app.trans('flarum-lock.forum.discussion_locked_notification', {user: this.props.notification.sender()}); } } diff --git a/extensions/lock/js/forum/src/components/DiscussionLockedPost.js b/extensions/lock/js/forum/src/components/DiscussionLockedPost.js index be2c628bd..9472c2a9e 100644 --- a/extensions/lock/js/forum/src/components/DiscussionLockedPost.js +++ b/extensions/lock/js/forum/src/components/DiscussionLockedPost.js @@ -9,7 +9,7 @@ export default class DiscussionLockedPost extends EventPost { descriptionKey() { return this.props.post.content().locked - ? 'lock.discussion_locked_post' - : 'lock.discussion_unlocked_post'; + ? 'flarum-lock.forum.discussion_locked_post' + : 'flarum-lock.forum.discussion_unlocked_post'; } } diff --git a/extensions/lock/js/forum/src/main.js b/extensions/lock/js/forum/src/main.js index 5f34e5262..97ebdcbef 100644 --- a/extensions/lock/js/forum/src/main.js +++ b/extensions/lock/js/forum/src/main.js @@ -4,24 +4,26 @@ import Model from 'flarum/Model'; import Discussion from 'flarum/models/Discussion'; import NotificationGrid from 'flarum/components/NotificationGrid'; -import DiscussionLockedPost from 'lock/components/DiscussionLockedPost'; -import DiscussionLockedNotification from 'lock/components/DiscussionLockedNotification'; -import addLockBadge from 'lock/addLockBadge'; -import addLockControl from 'lock/addLockControl'; +import DiscussionLockedPost from 'flarum/lock/components/DiscussionLockedPost'; +import DiscussionLockedNotification from 'flarum/lock/components/DiscussionLockedNotification'; +import addLockBadge from 'flarum/lock/addLockBadge'; +import addLockControl from 'flarum/lock/addLockControl'; -app.postComponents.discussionLocked = DiscussionLockedPost; -app.notificationComponents.discussionLocked = DiscussionLockedNotification; +app.initializers.add('flarum-lock', () => { + app.postComponents.discussionLocked = DiscussionLockedPost; + app.notificationComponents.discussionLocked = DiscussionLockedNotification; -Discussion.prototype.isLocked = Model.attribute('isLocked'); -Discussion.prototype.canLock = Model.attribute('canLock'); + Discussion.prototype.isLocked = Model.attribute('isLocked'); + Discussion.prototype.canLock = Model.attribute('canLock'); -addLockBadge(); -addLockControl(); + addLockBadge(); + addLockControl(); -extend(NotificationGrid.prototype, 'notificationTypes', function(items) { - items.add('discussionLocked', { - name: 'discussionLocked', - icon: 'lock', - label: app.trans('lock.notify_discussion_locked') + extend(NotificationGrid.prototype, 'notificationTypes', function (items) { + items.add('discussionLocked', { + name: 'discussionLocked', + icon: 'lock', + label: app.trans('flarum-lock.forum.notify_discussion_locked') + }); }); -}); +}); \ No newline at end of file diff --git a/extensions/lock/locale/en.yml b/extensions/lock/locale/en.yml deleted file mode 100644 index bbd202e57..000000000 --- a/extensions/lock/locale/en.yml +++ /dev/null @@ -1,8 +0,0 @@ -lock: - discussion_locked_notification: "{username} locked" - discussion_locked_post: "{username} locked the discussion." - discussion_unlocked_post: "{username} unlocked the discussion." - notify_discussion_locked: Someone locks a discussion I started - locked: Locked - lock: Lock - unlock: Unlock diff --git a/extensions/lock/migrations/2015_02_24_000000_add_locked_to_discussions.php b/extensions/lock/migrations/2015_02_24_000000_add_locked_to_discussions.php index e9922e132..8fa4f0773 100644 --- a/extensions/lock/migrations/2015_02_24_000000_add_locked_to_discussions.php +++ b/extensions/lock/migrations/2015_02_24_000000_add_locked_to_discussions.php @@ -8,18 +8,13 @@ * file that was distributed with this source code. */ -namespace Flarum\Migrations\Lock; +namespace Flarum\Lock\Migration; +use Flarum\Database\AbstractMigration; use Illuminate\Database\Schema\Blueprint; -use Flarum\Migrations\Migration; -class AddLockedToDiscussions extends Migration +class AddLockedToDiscussions extends AbstractMigration { - /** - * Run the migrations. - * - * @return void - */ public function up() { $this->schema->table('discussions', function (Blueprint $table) { @@ -27,11 +22,6 @@ class AddLockedToDiscussions extends Migration }); } - /** - * Reverse the migrations. - * - * @return void - */ public function down() { $this->schema->table('discussions', function (Blueprint $table) { diff --git a/extensions/lock/scripts/compile.sh b/extensions/lock/scripts/compile.sh new file mode 100755 index 000000000..b0d8e8bd3 --- /dev/null +++ b/extensions/lock/scripts/compile.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +# This script compiles the extension so that it can be used in a Flarum +# installation. It should be run from the root directory of the extension. + +base=$PWD + +cd "${base}/js" + +if [ -f bower.json ]; then + bower install +fi + +for app in forum admin; do + cd "${base}/js" + + if [ -d $app ]; then + cd $app + + if [ -f bower.json ]; then + bower install + fi + + npm install + gulp --production + fi +done diff --git a/extensions/lock/src/Access/DiscussionPolicy.php b/extensions/lock/src/Access/DiscussionPolicy.php new file mode 100755 index 000000000..a8432bfd2 --- /dev/null +++ b/extensions/lock/src/Access/DiscussionPolicy.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Flarum\Lock\Access; + +use Flarum\Core\Access\AbstractPolicy; +use Flarum\Core\Discussion; +use Flarum\Core\User; +use Illuminate\Contracts\Events\Dispatcher; + +class DiscussionPolicy extends AbstractPolicy +{ + /** + * {@inheritdoc} + */ + protected $model = Discussion::class; + + /** + * @param User $actor + * @param Discussion $discussion + * @return bool + */ + public function reply(User $actor, Discussion $discussion) + { + if ($discussion->is_locked && $actor->cannot('lock', $discussion)) { + return false; + } + } +} diff --git a/extensions/lock/src/Events/DiscussionWasLocked.php b/extensions/lock/src/Event/DiscussionWasLocked.php similarity index 85% rename from extensions/lock/src/Events/DiscussionWasLocked.php rename to extensions/lock/src/Event/DiscussionWasLocked.php index d3a962def..1fbe4e38f 100644 --- a/extensions/lock/src/Events/DiscussionWasLocked.php +++ b/extensions/lock/src/Event/DiscussionWasLocked.php @@ -8,10 +8,10 @@ * file that was distributed with this source code. */ -namespace Flarum\Lock\Events; +namespace Flarum\Lock\Event; -use Flarum\Core\Discussions\Discussion; -use Flarum\Core\Users\User; +use Flarum\Core\Discussion; +use Flarum\Core\User; class DiscussionWasLocked { diff --git a/extensions/lock/src/Events/DiscussionWasUnlocked.php b/extensions/lock/src/Event/DiscussionWasUnlocked.php similarity index 85% rename from extensions/lock/src/Events/DiscussionWasUnlocked.php rename to extensions/lock/src/Event/DiscussionWasUnlocked.php index b7ae0a1d2..25dc3fc70 100644 --- a/extensions/lock/src/Events/DiscussionWasUnlocked.php +++ b/extensions/lock/src/Event/DiscussionWasUnlocked.php @@ -8,10 +8,10 @@ * file that was distributed with this source code. */ -namespace Flarum\Lock\Events; +namespace Flarum\Lock\Event; -use Flarum\Core\Discussions\Discussion; -use Flarum\Core\Users\User; +use Flarum\Core\Discussion; +use Flarum\Core\User; class DiscussionWasUnlocked { diff --git a/extensions/lock/src/Extension.php b/extensions/lock/src/Extension.php deleted file mode 100644 index 1a3827753..000000000 --- a/extensions/lock/src/Extension.php +++ /dev/null @@ -1,26 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Flarum\Lock; - -use Flarum\Support\Extension as BaseExtension; -use Illuminate\Events\Dispatcher; - -class Extension extends BaseExtension -{ - public function listen(Dispatcher $events) - { - $events->subscribe('Flarum\Lock\Listeners\AddClientAssets'); - $events->subscribe('Flarum\Lock\Listeners\AddApiAttributes'); - $events->subscribe('Flarum\Lock\Listeners\PersistData'); - $events->subscribe('Flarum\Lock\Listeners\NotifyDiscussionLocked'); - $events->subscribe('Flarum\Lock\Listeners\ConfigurePermissions'); - } -} diff --git a/extensions/lock/src/Gambits/LockGambit.php b/extensions/lock/src/Gambit/LockedGambit.php similarity index 51% rename from extensions/lock/src/Gambits/LockGambit.php rename to extensions/lock/src/Gambit/LockedGambit.php index 9038ee5ff..88a60fea1 100644 --- a/extensions/lock/src/Gambits/LockGambit.php +++ b/extensions/lock/src/Gambit/LockedGambit.php @@ -8,16 +8,22 @@ * file that was distributed with this source code. */ -namespace Flarum\Lock\Gambits; +namespace Flarum\Lock\Gambit; -use Flarum\Core\Search\Search; -use Flarum\Core\Search\RegexGambit; +use Flarum\Core\Search\AbstractRegexGambit; +use Flarum\Core\Search\AbstractSearch; -class LockGambit extends RegexGambit +class LockedGambit extends AbstractRegexGambit { + /** + * {@inheritdoc} + */ protected $pattern = 'is:locked'; - protected function conditions(Search $search, array $matches, $negate) + /** + * {@inheritdoc} + */ + protected function conditions(AbstractSearch $search, array $matches, $negate) { $search->getQuery()->where('is_locked', ! $negate); } diff --git a/extensions/lock/src/Listener/AddClientAssets.php b/extensions/lock/src/Listener/AddClientAssets.php new file mode 100755 index 000000000..06eb839b3 --- /dev/null +++ b/extensions/lock/src/Listener/AddClientAssets.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Flarum\Lock\Listener; + +use Flarum\Event\ConfigureClientView; +use Illuminate\Contracts\Events\Dispatcher; + +class AddClientAssets +{ + /** + * @param Dispatcher $events + */ + public function subscribe(Dispatcher $events) + { + $events->listen(ConfigureClientView::class, [$this, 'addAssets']); + } + + /** + * @param ConfigureClientView $event + */ + public function addAssets(ConfigureClientView $event) + { + if ($event->isForum()) { + $event->addAssets([ + __DIR__.'/../../js/forum/dist/extension.js', + __DIR__.'/../../less/forum/extension.less' + ]); + $event->addBootstrapper('flarum/lock/main'); + $event->addTranslations('flarum-lock.forum'); + } + + if ($event->isAdmin()) { + $event->addAssets([ + __DIR__.'/../../js/admin/dist/extension.js' + ]); + $event->addBootstrapper('flarum/lock/main'); + $event->addTranslations('flarum-lock.admin'); + } + } +} diff --git a/extensions/lock/src/Listener/AddDiscussionLockedAttributes.php b/extensions/lock/src/Listener/AddDiscussionLockedAttributes.php new file mode 100755 index 000000000..a62dc431e --- /dev/null +++ b/extensions/lock/src/Listener/AddDiscussionLockedAttributes.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Flarum\Lock\Listener; + +use Flarum\Api\Serializer\DiscussionSerializer; +use Flarum\Event\PrepareApiAttributes; +use Illuminate\Contracts\Events\Dispatcher; + +class AddDiscussionLockedAttributes +{ + /** + * @param Dispatcher $events + */ + public function subscribe(Dispatcher $events) + { + $events->listen(PrepareApiAttributes::class, [$this, 'prepareApiAttributes']); + } + + /** + * @param PrepareApiAttributes $event + */ + public function prepareApiAttributes(PrepareApiAttributes $event) + { + if ($event->isSerializer(DiscussionSerializer::class)) { + $event->attributes['isLocked'] = (bool) $event->model->is_locked; + $event->attributes['canLock'] = (bool) $event->actor->can('lock', $event->model); + } + } +} diff --git a/extensions/lock/src/Listener/AddLockedGambit.php b/extensions/lock/src/Listener/AddLockedGambit.php new file mode 100755 index 000000000..9cfed36c1 --- /dev/null +++ b/extensions/lock/src/Listener/AddLockedGambit.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Flarum\Lock\Listener; + +use Flarum\Event\ConfigureDiscussionGambits; +use Flarum\Lock\Gambit\LockedGambit; +use Illuminate\Contracts\Events\Dispatcher; + +class AddLockedGambit +{ + /** + * @param Dispatcher $events + */ + public function subscribe(Dispatcher $events) + { + $events->listen(ConfigureDiscussionGambits::class, [$this, 'configureDiscussionGambits']); + } + + /** + * @param ConfigureDiscussionGambits $event + */ + public function configureDiscussionGambits(ConfigureDiscussionGambits $event) + { + $event->gambits->add(LockedGambit::class); + } +} diff --git a/extensions/lock/src/Listener/CreatePostWhenDiscussionIsLocked.php b/extensions/lock/src/Listener/CreatePostWhenDiscussionIsLocked.php new file mode 100755 index 000000000..eba69d528 --- /dev/null +++ b/extensions/lock/src/Listener/CreatePostWhenDiscussionIsLocked.php @@ -0,0 +1,104 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Flarum\Lock\Listener; + +use Flarum\Api\Serializer\DiscussionBasicSerializer; +use Flarum\Core\Discussion; +use Flarum\Core\Notification\NotificationSyncer; +use Flarum\Core\User; +use Flarum\Event\ConfigureNotificationTypes; +use Flarum\Event\ConfigurePostTypes; +use Flarum\Lock\Event\DiscussionWasLocked; +use Flarum\Lock\Event\DiscussionWasUnlocked; +use Flarum\Lock\Notification\DiscussionLockedBlueprint; +use Flarum\Lock\Post\DiscussionLockedPost; +use Illuminate\Contracts\Events\Dispatcher; + +class CreatePostWhenDiscussionIsLocked +{ + /** + * @var NotificationSyncer + */ + protected $notifications; + + /** + * @param NotificationSyncer $notifications + */ + public function __construct(NotificationSyncer $notifications) + { + $this->notifications = $notifications; + } + + /** + * @param Dispatcher $events + */ + public function subscribe(Dispatcher $events) + { + $events->listen(ConfigurePostTypes::class, [$this, 'addPostType']); + $events->listen(ConfigureNotificationTypes::class, [$this, 'addNotificationType']); + $events->listen(DiscussionWasLocked::class, [$this, 'whenDiscussionWasLocked']); + $events->listen(DiscussionWasUnlocked::class, [$this, 'whenDiscussionWasUnlocked']); + } + + /** + * @param ConfigurePostTypes $event + */ + public function addPostType(ConfigurePostTypes $event) + { + $event->add(DiscussionLockedPost::class); + } + + /** + * @param ConfigureNotificationTypes $event + */ + public function addNotificationType(ConfigureNotificationTypes $event) + { + $event->add(DiscussionLockedBlueprint::class, DiscussionBasicSerializer::class, ['alert']); + } + + /** + * @param DiscussionWasLocked $event + */ + public function whenDiscussionWasLocked(DiscussionWasLocked $event) + { + $this->lockedChanged($event->discussion, $event->user, true); + } + + /** + * @param DiscussionWasUnlocked $event + */ + public function whenDiscussionWasUnlocked(DiscussionWasUnlocked $event) + { + $this->lockedChanged($event->discussion, $event->user, false); + } + + /** + * @param Discussion $discussion + * @param User $user + * @param $isLocked + */ + protected function lockedChanged(Discussion $discussion, User $user, $isLocked) + { + $post = DiscussionLockedPost::reply( + $discussion->id, + $user->id, + $isLocked + ); + + $post = $discussion->mergePost($post); + + if ($discussion->start_user_id !== $user->id) { + $notification = new DiscussionLockedBlueprint($post); + + $this->notifications->sync($notification, $post->exists ? [$discussion->startUser] : []); + } + } +} diff --git a/extensions/lock/src/Listeners/PersistData.php b/extensions/lock/src/Listener/SaveLockedToDatabase.php similarity index 66% rename from extensions/lock/src/Listeners/PersistData.php rename to extensions/lock/src/Listener/SaveLockedToDatabase.php index b0b306b5c..b391ce437 100755 --- a/extensions/lock/src/Listeners/PersistData.php +++ b/extensions/lock/src/Listener/SaveLockedToDatabase.php @@ -8,19 +8,29 @@ * file that was distributed with this source code. */ -namespace Flarum\Lock\Listeners; +namespace Flarum\Lock\Listener; -use Flarum\Lock\Events\DiscussionWasLocked; -use Flarum\Lock\Events\DiscussionWasUnlocked; -use Flarum\Events\DiscussionWillBeSaved; +use Flarum\Core\Access\AssertPermissionTrait; +use Flarum\Event\DiscussionWillBeSaved; +use Flarum\Lock\Event\DiscussionWasLocked; +use Flarum\Lock\Event\DiscussionWasUnlocked; +use Illuminate\Contracts\Events\Dispatcher; -class PersistData +class SaveLockedToDatabase { - public function subscribe($events) + use AssertPermissionTrait; + + /** + * @param Dispatcher $events + */ + public function subscribe(Dispatcher $events) { $events->listen(DiscussionWillBeSaved::class, [$this, 'whenDiscussionWillBeSaved']); } + /** + * @param DiscussionWillBeSaved $event + */ public function whenDiscussionWillBeSaved(DiscussionWillBeSaved $event) { if (isset($event->data['attributes']['isLocked'])) { @@ -28,7 +38,7 @@ class PersistData $discussion = $event->discussion; $actor = $event->actor; - $discussion->assertCan($actor, 'lock'); + $this->assertCan($actor, 'lock', $discussion); if ((bool) $discussion->is_locked === $isLocked) { return; diff --git a/extensions/lock/src/Listeners/AddApiAttributes.php b/extensions/lock/src/Listeners/AddApiAttributes.php deleted file mode 100755 index 6fd7ec507..000000000 --- a/extensions/lock/src/Listeners/AddApiAttributes.php +++ /dev/null @@ -1,31 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Flarum\Lock\Listeners; - -use Flarum\Events\ApiAttributes; -use Illuminate\Contracts\Events\Dispatcher; -use Flarum\Api\Serializers\DiscussionSerializer; - -class AddApiAttributes -{ - public function subscribe(Dispatcher $events) - { - $events->listen(ApiAttributes::class, [$this, 'addAttributes']); - } - - public function addAttributes(ApiAttributes $event) - { - if ($event->serializer instanceof DiscussionSerializer) { - $event->attributes['isLocked'] = (bool) $event->model->is_locked; - $event->attributes['canLock'] = (bool) $event->model->can($event->actor, 'lock'); - } - } -} diff --git a/extensions/lock/src/Listeners/AddClientAssets.php b/extensions/lock/src/Listeners/AddClientAssets.php deleted file mode 100755 index abe3b1437..000000000 --- a/extensions/lock/src/Listeners/AddClientAssets.php +++ /dev/null @@ -1,55 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Flarum\Lock\Listeners; - -use Flarum\Events\RegisterLocales; -use Flarum\Events\BuildClientView; -use Illuminate\Contracts\Events\Dispatcher; - -class AddClientAssets -{ - public function subscribe(Dispatcher $events) - { - $events->listen(RegisterLocales::class, [$this, 'addLocale']); - $events->listen(BuildClientView::class, [$this, 'addAssets']); - } - - public function addLocale(RegisterLocales $event) - { - $event->addTranslations('en', __DIR__.'/../../locale/en.yml'); - } - - public function addAssets(BuildClientView $event) - { - $event->forumAssets([ - __DIR__.'/../../js/forum/dist/extension.js', - __DIR__.'/../../less/forum/extension.less' - ]); - - $event->forumBootstrapper('lock/main'); - - $event->forumTranslations([ - 'lock.discussion_locked_notification', - 'lock.discussion_locked_post', - 'lock.discussion_unlocked_post', - 'lock.notify_discussion_locked', - 'lock.locked', - 'lock.lock', - 'lock.unlock' - ]); - - $event->adminAssets([ - __DIR__.'/../../js/admin/dist/extension.js' - ]); - - $event->adminBootstrapper('lock/main'); - } -} diff --git a/extensions/lock/src/Listeners/ConfigurePermissions.php b/extensions/lock/src/Listeners/ConfigurePermissions.php deleted file mode 100755 index 8502bb260..000000000 --- a/extensions/lock/src/Listeners/ConfigurePermissions.php +++ /dev/null @@ -1,33 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Flarum\Lock\Listeners; - -use Flarum\Events\ModelAllow; -use Flarum\Core\Discussions\Discussion; - -class ConfigurePermissions -{ - public function subscribe($events) - { - $events->listen(ModelAllow::class, [$this, 'allowDiscussionPermissions'], 10); - } - - public function allowDiscussionPermissions(ModelAllow $event) - { - if ($event->model instanceof Discussion && - $event->model->is_locked && - $event->action === 'reply') { - if (! $event->model->can($event->actor, 'lock')) { - return false; - } - } - } -} diff --git a/extensions/lock/src/Listeners/NotifyDiscussionLocked.php b/extensions/lock/src/Listeners/NotifyDiscussionLocked.php deleted file mode 100755 index 25dec2cb9..000000000 --- a/extensions/lock/src/Listeners/NotifyDiscussionLocked.php +++ /dev/null @@ -1,81 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Flarum\Lock\Listeners; - -use Flarum\Events\RegisterPostTypes; -use Flarum\Events\RegisterNotificationTypes; -use Flarum\Lock\Posts\DiscussionLockedPost; -use Flarum\Lock\Notifications\DiscussionLockedBlueprint; -use Flarum\Lock\Events\DiscussionWasLocked; -use Flarum\Lock\Events\DiscussionWasUnlocked; -use Flarum\Core\Notifications\NotificationSyncer; -use Flarum\Core\Discussions\Discussion; -use Flarum\Core\Users\User; -use Illuminate\Contracts\Events\Dispatcher; - -class NotifyDiscussionLocked -{ - protected $notifications; - - public function __construct(NotificationSyncer $notifications) - { - $this->notifications = $notifications; - } - - public function subscribe(Dispatcher $events) - { - $events->listen(RegisterPostTypes::class, [$this, 'registerPostType']); - $events->listen(RegisterNotificationTypes::class, [$this, 'registerNotificationType']); - $events->listen(DiscussionWasLocked::class, [$this, 'whenDiscussionWasLocked']); - $events->listen(DiscussionWasUnlocked::class, [$this, 'whenDiscussionWasUnlocked']); - } - - public function registerPostType(RegisterPostTypes $event) - { - $event->register('Flarum\Lock\Posts\DiscussionLockedPost'); - } - - public function registerNotificationType(RegisterNotificationTypes $event) - { - $event->register( - 'Flarum\Lock\Notifications\DiscussionLockedBlueprint', - 'Flarum\Api\Serializers\DiscussionBasicSerializer', - ['alert'] - ); - } - - public function whenDiscussionWasLocked(DiscussionWasLocked $event) - { - $this->stickyChanged($event->discussion, $event->user, true); - } - - public function whenDiscussionWasUnlocked(DiscussionWasUnlocked $event) - { - $this->stickyChanged($event->discussion, $event->user, false); - } - - protected function stickyChanged(Discussion $discussion, User $user, $isLocked) - { - $post = DiscussionLockedPost::reply( - $discussion->id, - $user->id, - $isLocked - ); - - $post = $discussion->mergePost($post); - - if ($discussion->start_user_id !== $user->id) { - $notification = new DiscussionLockedBlueprint($post); - - $this->notifications->sync($notification, $post->exists ? [$discussion->startUser] : []); - } - } -} diff --git a/extensions/lock/src/Notifications/DiscussionLockedBlueprint.php b/extensions/lock/src/Notification/DiscussionLockedBlueprint.php similarity index 58% rename from extensions/lock/src/Notifications/DiscussionLockedBlueprint.php rename to extensions/lock/src/Notification/DiscussionLockedBlueprint.php index 9d15ab17e..3399723ec 100644 --- a/extensions/lock/src/Notifications/DiscussionLockedBlueprint.php +++ b/extensions/lock/src/Notification/DiscussionLockedBlueprint.php @@ -8,42 +8,64 @@ * file that was distributed with this source code. */ -namespace Flarum\Lock\Notifications; +namespace Flarum\Lock\Notification; -use Flarum\Lock\Posts\DiscussionLockedPost; -use Flarum\Core\Notifications\Blueprint; +use Flarum\Core\Discussion; +use Flarum\Core\Notification\BlueprintInterface; +use Flarum\Lock\Post\DiscussionLockedPost; -class DiscussionLockedBlueprint implements Blueprint +class DiscussionLockedBlueprint implements BlueprintInterface { + /** + * @var DiscussionLockedPost + */ protected $post; + /** + * @param DiscussionLockedPost $post + */ public function __construct(DiscussionLockedPost $post) { $this->post = $post; } + /** + * {@inheritdoc} + */ public function getSender() { return $this->post->user; } + /** + * {@inheritdoc} + */ public function getSubject() { return $this->post->discussion; } + /** + * {@inheritdoc} + */ public function getData() { return ['postNumber' => (int) $this->post->number]; } + /** + * {@inheritdoc} + */ public static function getType() { return 'discussionLocked'; } + /** + * {@inheritdoc} + */ public static function getSubjectModel() { - return 'Flarum\Core\Discussions\Discussion'; + return Discussion::class; } } diff --git a/extensions/lock/src/Posts/DiscussionLockedPost.php b/extensions/lock/src/Post/DiscussionLockedPost.php similarity index 86% rename from extensions/lock/src/Posts/DiscussionLockedPost.php rename to extensions/lock/src/Post/DiscussionLockedPost.php index 4ebe2d48d..a8c5a227d 100755 --- a/extensions/lock/src/Posts/DiscussionLockedPost.php +++ b/extensions/lock/src/Post/DiscussionLockedPost.php @@ -8,16 +8,22 @@ * file that was distributed with this source code. */ -namespace Flarum\Lock\Posts; +namespace Flarum\Lock\Post; -use Flarum\Core\Posts\Post; -use Flarum\Core\Posts\EventPost; -use Flarum\Core\Posts\MergeablePost; +use Flarum\Core\Post; +use Flarum\Core\Post\AbstractEventPost; +use Flarum\Core\Post\MergeableInterface; -class DiscussionLockedPost extends EventPost implements MergeablePost +class DiscussionLockedPost extends AbstractEventPost implements MergeableInterface { + /** + * {@inheritdoc} + */ public static $type = 'discussionLocked'; + /** + * {@inheritdoc} + */ public function saveAfter(Post $previous) { // If the previous post is another 'discussion locked' post, and it's