mirror of
https://github.com/flarum/core.git
synced 2025-07-15 13:56:23 +02:00
Merge remote-tracking branch 'extensions_lock/REWRITE'
This commit is contained in:
19
extensions/lock/.editorconfig
Normal file
19
extensions/lock/.editorconfig
Normal file
@ -0,0 +1,19 @@
|
||||
# EditorConfig helps developers define and maintain consistent
|
||||
# coding styles between different editors and IDEs
|
||||
# editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.{diff,md}]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.{php,xml,json}]
|
||||
indent_size = 4
|
18
extensions/lock/.gitattributes
vendored
Normal file
18
extensions/lock/.gitattributes
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
.gitattributes export-ignore
|
||||
.gitignore export-ignore
|
||||
.gitmodules export-ignore
|
||||
.github export-ignore
|
||||
.travis export-ignore
|
||||
.travis.yml export-ignore
|
||||
.editorconfig export-ignore
|
||||
.styleci.yml export-ignore
|
||||
|
||||
phpunit.xml export-ignore
|
||||
tests export-ignore
|
||||
|
||||
js/dist/* -diff
|
||||
js/dist/* linguist-generated
|
||||
js/dist-typings/* linguist-generated
|
||||
js/yarn.lock -diff
|
||||
|
||||
* text=auto eol=lf
|
15
extensions/lock/.github/workflows/backend.yml
vendored
Normal file
15
extensions/lock/.github/workflows/backend.yml
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
name: Lock PHP
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_backend.yml@main
|
||||
with:
|
||||
enable_backend_testing: false
|
||||
|
||||
backend_directory: .
|
21
extensions/lock/.github/workflows/frontend.yml
vendored
Normal file
21
extensions/lock/.github/workflows/frontend.yml
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
name: Lock JS
|
||||
|
||||
on: [workflow_dispatch, push, pull_request]
|
||||
|
||||
# The reusable workflow definitions will be moved to the `flarum/framework` repo soon.
|
||||
# This will break your current script.
|
||||
# When this happens, run `flarum-cli audit infra --fix` to update your infrastructure.
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: flarum/.github/.github/workflows/REUSABLE_frontend.yml@main
|
||||
with:
|
||||
enable_bundlewatch: false
|
||||
enable_prettier: true
|
||||
enable_typescript: false
|
||||
|
||||
frontend_directory: ./js
|
||||
main_git_branch: master
|
||||
|
||||
secrets:
|
||||
bundlewatch_github_token: ${{ secrets.BUNDLEWATCH_GITHUB_TOKEN }}
|
12
extensions/lock/.gitignore
vendored
Normal file
12
extensions/lock/.gitignore
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
/vendor
|
||||
composer.lock
|
||||
composer.phar
|
||||
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
tests/.phpunit.result.cache
|
||||
/tests/integration/tmp
|
||||
.vagrant
|
||||
.idea/*
|
||||
.vscode
|
||||
js/coverage-ts
|
14
extensions/lock/.styleci.yml
Normal file
14
extensions/lock/.styleci.yml
Normal file
@ -0,0 +1,14 @@
|
||||
preset: recommended
|
||||
|
||||
enabled:
|
||||
- logical_not_operators_with_successor_space
|
||||
|
||||
disabled:
|
||||
- align_double_arrow
|
||||
- blank_line_after_opening_tag
|
||||
- multiline_array_trailing_comma
|
||||
- new_with_braces
|
||||
- phpdoc_align
|
||||
- phpdoc_order
|
||||
- phpdoc_separation
|
||||
- phpdoc_types
|
46
extensions/lock/CHANGELOG.md
Normal file
46
extensions/lock/CHANGELOG.md
Normal file
@ -0,0 +1,46 @@
|
||||
# Changelog
|
||||
|
||||
## [1.2.0](https://github.com/flarum/lock/compare/v1.1.0...v1.2.0)
|
||||
|
||||
No changes.
|
||||
|
||||
## [1.1.0](https://github.com/flarum/lock/compare/v1.0.0...v1.1.0)
|
||||
|
||||
### Changed
|
||||
- Use css variables for badge (https://github.com/flarum/lock/pulls/29)
|
||||
|
||||
## [1.0.0](https://github.com/flarum/lock/compare/v0.1.0-beta.16...v1.0.0)
|
||||
|
||||
### Changed
|
||||
- Compatibility with Flarum v1.0.0.
|
||||
|
||||
## [0.1.0-beta.16](https://github.com/flarum/lock/compare/v0.1.0-beta.15...v0.1.0-beta.16)
|
||||
|
||||
### Changed
|
||||
- Updated admin category from moderation to feature (https://github.com/flarum/lock/pull/27)
|
||||
- Moved locale files from translation pack to extension (https://github.com/flarum/lock/pull/24)
|
||||
|
||||
## [0.1.0-beta.15](https://github.com/flarum/lock/compare/v0.1.0-beta.14...v0.1.0-beta.15)
|
||||
|
||||
### Changed
|
||||
- Updated composer.json and admin javascript for new admin area.
|
||||
- Updated to use newest extenders.
|
||||
|
||||
## [0.1.0-beta.14](https://github.com/flarum/lock/compare/v0.1.0-beta.13...v0.1.0-beta.14)
|
||||
|
||||
### Changed
|
||||
- Updated mithril to version 2
|
||||
- Load language strings correctly on en-/disable
|
||||
- Updated JS dependencies
|
||||
|
||||
## [0.1.0-beta.13](https://github.com/flarum/lock/compare/v0.1.0-beta.12...v0.1.0-beta.13)
|
||||
|
||||
### Changed
|
||||
- Updated JS dependencies
|
||||
|
||||
## [0.1.0-beta.9](https://github.com/flarum/lock/compare/v0.1.0-beta.8...v0.1.0-beta.9)
|
||||
|
||||
### Changed
|
||||
- Replace event subscribers (that resolve services too early) with listeners ([adad532](https://github.com/flarum/lock/commit/adad5324b8aab612d51251074315bb4bc2308b17))
|
||||
- Compatibility with Laravel 5.7 ([c27411d](https://github.com/flarum/lock/commit/c27411ded2499c74d53e690308cd092831060ac2))
|
||||
|
22
extensions/lock/LICENSE
Normal file
22
extensions/lock/LICENSE
Normal file
@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2019-2021 Stichting Flarum (Flarum Foundation)
|
||||
Copyright (c) 2014-2019 Toby Zerner (toby.zerner@gmail.com)
|
||||
|
||||
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.
|
60
extensions/lock/composer.json
Normal file
60
extensions/lock/composer.json
Normal file
@ -0,0 +1,60 @@
|
||||
{
|
||||
"name": "flarum/lock",
|
||||
"description": "End a discussion and don't let anyone add further replies.",
|
||||
"type": "flarum-extension",
|
||||
"keywords": [
|
||||
"moderation"
|
||||
],
|
||||
"license": "MIT",
|
||||
"support": {
|
||||
"issues": "https://github.com/flarum/core/issues",
|
||||
"source": "https://github.com/flarum/lock",
|
||||
"forum": "https://discuss.flarum.org"
|
||||
},
|
||||
"homepage": "https://flarum.org",
|
||||
"funding": [
|
||||
{
|
||||
"type": "website",
|
||||
"url": "https://flarum.org/donate/"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"flarum/core": "^1.2"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Flarum\\Lock\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.x-dev"
|
||||
},
|
||||
"flarum-extension": {
|
||||
"title": "Lock",
|
||||
"category": "feature",
|
||||
"icon": {
|
||||
"name": "fas fa-lock",
|
||||
"backgroundColor": "#ddd",
|
||||
"color": "#666"
|
||||
}
|
||||
},
|
||||
"flarum-cli": {
|
||||
"modules": {
|
||||
"admin": true,
|
||||
"forum": true,
|
||||
"js": true,
|
||||
"jsCommon": false,
|
||||
"css": true,
|
||||
"gitConf": true,
|
||||
"githubActions": true,
|
||||
"prettier": true,
|
||||
"typescript": false,
|
||||
"bundlewatch": false,
|
||||
"backendTesting": false,
|
||||
"editorConfig": true,
|
||||
"styleci": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
62
extensions/lock/extend.php
Normal file
62
extensions/lock/extend.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Flarum\Api\Serializer\BasicDiscussionSerializer;
|
||||
use Flarum\Api\Serializer\DiscussionSerializer;
|
||||
use Flarum\Discussion\Discussion;
|
||||
use Flarum\Discussion\Event\Saving;
|
||||
use Flarum\Discussion\Filter\DiscussionFilterer;
|
||||
use Flarum\Discussion\Search\DiscussionSearcher;
|
||||
use Flarum\Extend;
|
||||
use Flarum\Lock\Access;
|
||||
use Flarum\Lock\Event\DiscussionWasLocked;
|
||||
use Flarum\Lock\Event\DiscussionWasUnlocked;
|
||||
use Flarum\Lock\Listener;
|
||||
use Flarum\Lock\Notification\DiscussionLockedBlueprint;
|
||||
use Flarum\Lock\Post\DiscussionLockedPost;
|
||||
use Flarum\Lock\Query\LockedFilterGambit;
|
||||
|
||||
return [
|
||||
(new Extend\Frontend('forum'))
|
||||
->js(__DIR__.'/js/dist/forum.js')
|
||||
->css(__DIR__.'/less/forum.less'),
|
||||
|
||||
(new Extend\Frontend('admin'))
|
||||
->js(__DIR__.'/js/dist/admin.js'),
|
||||
|
||||
new Extend\Locales(__DIR__.'/locale'),
|
||||
|
||||
(new Extend\Notification())
|
||||
->type(DiscussionLockedBlueprint::class, BasicDiscussionSerializer::class, ['alert']),
|
||||
|
||||
(new Extend\ApiSerializer(DiscussionSerializer::class))
|
||||
->attribute('isLocked', function (DiscussionSerializer $serializer, Discussion $discussion) {
|
||||
return (bool) $discussion->is_locked;
|
||||
})
|
||||
->attribute('canLock', function (DiscussionSerializer $serializer, Discussion $discussion) {
|
||||
return (bool) $serializer->getActor()->can('lock', $discussion);
|
||||
}),
|
||||
|
||||
(new Extend\Post())
|
||||
->type(DiscussionLockedPost::class),
|
||||
|
||||
(new Extend\Event())
|
||||
->listen(Saving::class, Listener\SaveLockedToDatabase::class)
|
||||
->listen(DiscussionWasLocked::class, Listener\CreatePostWhenDiscussionIsLocked::class)
|
||||
->listen(DiscussionWasUnlocked::class, Listener\CreatePostWhenDiscussionIsUnlocked::class),
|
||||
|
||||
(new Extend\Policy())
|
||||
->modelPolicy(Discussion::class, Access\DiscussionPolicy::class),
|
||||
|
||||
(new Extend\Filter(DiscussionFilterer::class))
|
||||
->addFilter(LockedFilterGambit::class),
|
||||
|
||||
(new Extend\SimpleFlarumSearch(DiscussionSearcher::class))
|
||||
->addGambit(LockedFilterGambit::class),
|
||||
];
|
9
extensions/lock/js/.gitignore
vendored
Normal file
9
extensions/lock/js/.gitignore
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
.pnp.*
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/plugins
|
||||
!.yarn/releases
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
|
||||
node_modules
|
1
extensions/lock/js/admin.js
Normal file
1
extensions/lock/js/admin.js
Normal file
@ -0,0 +1 @@
|
||||
export * from './src/admin';
|
2
extensions/lock/js/dist/admin.js
generated
vendored
Normal file
2
extensions/lock/js/dist/admin.js
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
(()=>{var e={n:o=>{var r=o&&o.__esModule?()=>o.default:()=>o;return e.d(r,{a:r}),r},d:(o,r)=>{for(var a in r)e.o(r,a)&&!e.o(o,a)&&Object.defineProperty(o,a,{enumerable:!0,get:r[a]})},o:(e,o)=>Object.prototype.hasOwnProperty.call(e,o),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},o={};(()=>{"use strict";e.r(o);const r=flarum.core.compat["admin/app"];var a=e.n(r);a().initializers.add("lock",(function(){a().extensionData.for("flarum-lock").registerPermission({icon:"fas fa-lock",label:a().translator.trans("flarum-lock.admin.permissions.lock_discussions_label"),permission:"discussion.lock"},"moderate",95)}))})(),module.exports=o})();
|
||||
//# sourceMappingURL=admin.js.map
|
1
extensions/lock/js/dist/admin.js.map
generated
vendored
Normal file
1
extensions/lock/js/dist/admin.js.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"admin.js","mappings":"MACA,IAAIA,EAAsB,CCA1BA,EAAyBC,IACxB,IAAIC,EAASD,GAAUA,EAAOE,WAC7B,IAAOF,EAAiB,QACxB,IAAM,EAEP,OADAD,EAAoBI,EAAEF,EAAQ,CAAEG,EAAGH,IAC5BA,GCLRF,EAAwB,CAACM,EAASC,KACjC,IAAI,IAAIC,KAAOD,EACXP,EAAoBS,EAAEF,EAAYC,KAASR,EAAoBS,EAAEH,EAASE,IAC5EE,OAAOC,eAAeL,EAASE,EAAK,CAAEI,YAAY,EAAMC,IAAKN,EAAWC,MCJ3ER,EAAwB,CAACc,EAAKC,IAAUL,OAAOM,UAAUC,eAAeC,KAAKJ,EAAKC,GCClFf,EAAyBM,IACH,oBAAXa,QAA0BA,OAAOC,aAC1CV,OAAOC,eAAeL,EAASa,OAAOC,YAAa,CAAEC,MAAO,WAE7DX,OAAOC,eAAeL,EAAS,aAAc,CAAEe,OAAO,M,+BCLvD,MAAM,EAA+BC,OAAOC,KAAKC,OAAO,a,aCExDC,IAAAA,aAAAA,IAAqB,QAAQ,WAC3BA,IAAAA,cAAAA,IAAsB,eAAeC,mBACnC,CACEC,KAAM,cACNC,MAAOH,IAAAA,WAAAA,MAAqB,wDAC5BI,WAAY,mBAEd,WACA,Q","sources":["webpack://@flarum/lock/webpack/bootstrap","webpack://@flarum/lock/webpack/runtime/compat get default export","webpack://@flarum/lock/webpack/runtime/define property getters","webpack://@flarum/lock/webpack/runtime/hasOwnProperty shorthand","webpack://@flarum/lock/webpack/runtime/make namespace object","webpack://@flarum/lock/external root \"flarum.core.compat['admin/app']\"","webpack://@flarum/lock/./src/admin/index.js"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['admin/app'];","import app from 'flarum/admin/app';\n\napp.initializers.add('lock', () => {\n app.extensionData.for('flarum-lock').registerPermission(\n {\n icon: 'fas fa-lock',\n label: app.translator.trans('flarum-lock.admin.permissions.lock_discussions_label'),\n permission: 'discussion.lock',\n },\n 'moderate',\n 95\n );\n});\n"],"names":["__webpack_require__","module","getter","__esModule","d","a","exports","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","flarum","core","compat","app","registerPermission","icon","label","permission"],"sourceRoot":""}
|
2
extensions/lock/js/dist/forum.js
generated
vendored
Normal file
2
extensions/lock/js/dist/forum.js
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
(()=>{var o={n:t=>{var n=t&&t.__esModule?()=>t.default:()=>t;return o.d(n,{a:n}),n},d:(t,n)=>{for(var c in n)o.o(n,c)&&!o.o(t,c)&&Object.defineProperty(t,c,{enumerable:!0,get:n[c]})},o:(o,t)=>Object.prototype.hasOwnProperty.call(o,t),r:o=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(o,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(o,"__esModule",{value:!0})}},t={};(()=>{"use strict";o.r(t);const n=flarum.core.compat["common/extend"],c=flarum.core.compat["forum/app"];var r=o.n(c);const e=flarum.core.compat["common/Model"];var s=o.n(e);const a=flarum.core.compat["common/models/Discussion"];var i=o.n(a);const u=flarum.core.compat["forum/components/NotificationGrid"];var l=o.n(u);function f(o,t){return f=Object.setPrototypeOf||function(o,t){return o.__proto__=t,o},f(o,t)}function p(o,t){o.prototype=Object.create(t.prototype),o.prototype.constructor=o,f(o,t)}const d=flarum.core.compat["forum/components/EventPost"];var k=function(o){function t(){return o.apply(this,arguments)||this}p(t,o);var n=t.prototype;return n.icon=function(){return this.attrs.post.content().locked?"fas fa-lock":"fas fa-unlock"},n.descriptionKey=function(){return this.attrs.post.content().locked?"flarum-lock.forum.post_stream.discussion_locked_text":"flarum-lock.forum.post_stream.discussion_unlocked_text"},t}(o.n(d)());const y=flarum.core.compat["forum/components/Notification"];var _=function(o){function t(){return o.apply(this,arguments)||this}p(t,o);var n=t.prototype;return n.icon=function(){return"fas fa-lock"},n.href=function(){var o=this.attrs.notification;return r().route.discussion(o.subject(),o.content().postNumber)},n.content=function(){return r().translator.trans("flarum-lock.forum.notifications.discussion_locked_text",{user:this.attrs.notification.fromUser()})},t}(o.n(y)());const b=flarum.core.compat["common/components/Badge"];var v=o.n(b);const h=flarum.core.compat["forum/utils/DiscussionControls"];var L=o.n(h);const g=flarum.core.compat["forum/components/DiscussionPage"];var x=o.n(g);const O=flarum.core.compat["common/components/Button"];var j=o.n(O);r().initializers.add("flarum-lock",(function(){r().postComponents.discussionLocked=k,r().notificationComponents.discussionLocked=_,i().prototype.isLocked=s().attribute("isLocked"),i().prototype.canLock=s().attribute("canLock"),(0,n.extend)(i().prototype,"badges",(function(o){this.isLocked()&&o.add("locked",v().component({type:"locked",label:r().translator.trans("flarum-lock.forum.badge.locked_tooltip"),icon:"fas fa-lock"}))})),(0,n.extend)(L(),"moderationControls",(function(o,t){t.canLock()&&o.add("lock",j().component({icon:"fas fa-lock",onclick:this.lockAction.bind(t)},r().translator.trans(t.isLocked()?"flarum-lock.forum.discussion_controls.unlock_button":"flarum-lock.forum.discussion_controls.lock_button")))})),L().lockAction=function(){this.save({isLocked:!this.isLocked()}).then((function(){r().current.matches(x())&&r().current.get("stream").update(),m.redraw()}))},(0,n.extend)(l().prototype,"notificationTypes",(function(o){o.add("discussionLocked",{name:"discussionLocked",icon:"fas fa-lock",label:r().translator.trans("flarum-lock.forum.settings.notify_discussion_locked_label")})}))}))})(),module.exports=t})();
|
||||
//# sourceMappingURL=forum.js.map
|
1
extensions/lock/js/dist/forum.js.map
generated
vendored
Normal file
1
extensions/lock/js/dist/forum.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1
extensions/lock/js/forum.js
Normal file
1
extensions/lock/js/forum.js
Normal file
@ -0,0 +1 @@
|
||||
export * from './src/forum';
|
26
extensions/lock/js/package.json
Normal file
26
extensions/lock/js/package.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "@flarum/lock",
|
||||
"prettier": "@flarum/prettier-config",
|
||||
"devDependencies": {
|
||||
"prettier": "^2.5.1",
|
||||
"flarum-webpack-config": "^2.0.0",
|
||||
"webpack": "^5.65.0",
|
||||
"webpack-cli": "^4.9.1",
|
||||
"@flarum/prettier-config": "^1.0.0",
|
||||
"flarum-tsconfig": "^1.0.2",
|
||||
"typescript": "^4.5.4",
|
||||
"typescript-coverage-report": "^0.6.1"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "webpack --mode development --watch",
|
||||
"build": "webpack --mode production",
|
||||
"format": "prettier --write src",
|
||||
"format-check": "prettier --check src",
|
||||
"analyze": "cross-env ANALYZER=true yarn build",
|
||||
"clean-typings": "npx rimraf dist-typings && mkdir dist-typings",
|
||||
"build-typings": "npm run clean-typings && cp -r src/@types dist-typings/@types && tsc",
|
||||
"check-typings": "tsc --noEmit --emitDeclarationOnly false",
|
||||
"check-typings-coverage": "typescript-coverage-report"
|
||||
}
|
||||
}
|
13
extensions/lock/js/src/admin/index.js
Normal file
13
extensions/lock/js/src/admin/index.js
Normal file
@ -0,0 +1,13 @@
|
||||
import app from 'flarum/admin/app';
|
||||
|
||||
app.initializers.add('lock', () => {
|
||||
app.extensionData.for('flarum-lock').registerPermission(
|
||||
{
|
||||
icon: 'fas fa-lock',
|
||||
label: app.translator.trans('flarum-lock.admin.permissions.lock_discussions_label'),
|
||||
permission: 'discussion.lock',
|
||||
},
|
||||
'moderate',
|
||||
95
|
||||
);
|
||||
});
|
19
extensions/lock/js/src/forum/addLockBadge.js
Normal file
19
extensions/lock/js/src/forum/addLockBadge.js
Normal file
@ -0,0 +1,19 @@
|
||||
import app from 'flarum/forum/app';
|
||||
import { extend } from 'flarum/common/extend';
|
||||
import Discussion from 'flarum/common/models/Discussion';
|
||||
import Badge from 'flarum/common/components/Badge';
|
||||
|
||||
export default function addLockBadge() {
|
||||
extend(Discussion.prototype, 'badges', function (badges) {
|
||||
if (this.isLocked()) {
|
||||
badges.add(
|
||||
'locked',
|
||||
Badge.component({
|
||||
type: 'locked',
|
||||
label: app.translator.trans('flarum-lock.forum.badge.locked_tooltip'),
|
||||
icon: 'fas fa-lock',
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
34
extensions/lock/js/src/forum/addLockControl.js
Normal file
34
extensions/lock/js/src/forum/addLockControl.js
Normal file
@ -0,0 +1,34 @@
|
||||
import app from 'flarum/forum/app';
|
||||
import { extend } from 'flarum/common/extend';
|
||||
import DiscussionControls from 'flarum/forum/utils/DiscussionControls';
|
||||
import DiscussionPage from 'flarum/forum/components/DiscussionPage';
|
||||
import Button from 'flarum/common/components/Button';
|
||||
|
||||
export default function addLockControl() {
|
||||
extend(DiscussionControls, 'moderationControls', function (items, discussion) {
|
||||
if (discussion.canLock()) {
|
||||
items.add(
|
||||
'lock',
|
||||
Button.component(
|
||||
{
|
||||
icon: 'fas fa-lock',
|
||||
onclick: this.lockAction.bind(discussion),
|
||||
},
|
||||
app.translator.trans(
|
||||
discussion.isLocked() ? 'flarum-lock.forum.discussion_controls.unlock_button' : 'flarum-lock.forum.discussion_controls.lock_button'
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
DiscussionControls.lockAction = function () {
|
||||
this.save({ isLocked: !this.isLocked() }).then(() => {
|
||||
if (app.current.matches(DiscussionPage)) {
|
||||
app.current.get('stream').update();
|
||||
}
|
||||
|
||||
m.redraw();
|
||||
});
|
||||
};
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
import app from 'flarum/forum/app';
|
||||
import Notification from 'flarum/forum/components/Notification';
|
||||
|
||||
export default class DiscussionLockedNotification extends Notification {
|
||||
icon() {
|
||||
return 'fas fa-lock';
|
||||
}
|
||||
|
||||
href() {
|
||||
const notification = this.attrs.notification;
|
||||
|
||||
return app.route.discussion(notification.subject(), notification.content().postNumber);
|
||||
}
|
||||
|
||||
content() {
|
||||
return app.translator.trans('flarum-lock.forum.notifications.discussion_locked_text', { user: this.attrs.notification.fromUser() });
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
import EventPost from 'flarum/forum/components/EventPost';
|
||||
|
||||
export default class DiscussionLockedPost extends EventPost {
|
||||
icon() {
|
||||
return this.attrs.post.content().locked ? 'fas fa-lock' : 'fas fa-unlock';
|
||||
}
|
||||
|
||||
descriptionKey() {
|
||||
return this.attrs.post.content().locked
|
||||
? 'flarum-lock.forum.post_stream.discussion_locked_text'
|
||||
: 'flarum-lock.forum.post_stream.discussion_unlocked_text';
|
||||
}
|
||||
}
|
29
extensions/lock/js/src/forum/index.js
Normal file
29
extensions/lock/js/src/forum/index.js
Normal file
@ -0,0 +1,29 @@
|
||||
import { extend } from 'flarum/common/extend';
|
||||
import app from 'flarum/forum/app';
|
||||
import Model from 'flarum/common/Model';
|
||||
import Discussion from 'flarum/common/models/Discussion';
|
||||
import NotificationGrid from 'flarum/forum/components/NotificationGrid';
|
||||
|
||||
import DiscussionLockedPost from './components/DiscussionLockedPost';
|
||||
import DiscussionLockedNotification from './components/DiscussionLockedNotification';
|
||||
import addLockBadge from './addLockBadge';
|
||||
import addLockControl from './addLockControl';
|
||||
|
||||
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');
|
||||
|
||||
addLockBadge();
|
||||
addLockControl();
|
||||
|
||||
extend(NotificationGrid.prototype, 'notificationTypes', function (items) {
|
||||
items.add('discussionLocked', {
|
||||
name: 'discussionLocked',
|
||||
icon: 'fas fa-lock',
|
||||
label: app.translator.trans('flarum-lock.forum.settings.notify_discussion_locked_label'),
|
||||
});
|
||||
});
|
||||
});
|
1
extensions/lock/js/webpack.config.js
Normal file
1
extensions/lock/js/webpack.config.js
Normal file
@ -0,0 +1 @@
|
||||
module.exports = require('flarum-webpack-config')();
|
2838
extensions/lock/js/yarn.lock
Normal file
2838
extensions/lock/js/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
0
extensions/lock/less/admin.less
Normal file
0
extensions/lock/less/admin.less
Normal file
11
extensions/lock/less/forum.less
Normal file
11
extensions/lock/less/forum.less
Normal file
@ -0,0 +1,11 @@
|
||||
:root {
|
||||
--lock-color: #888;
|
||||
}
|
||||
|
||||
.DiscussionLockedPost {
|
||||
.EventPost-icon,
|
||||
.EventPost-info,
|
||||
.EventPost-info a {
|
||||
color: var(--lock-color);
|
||||
}
|
||||
}
|
37
extensions/lock/locale/en.yml
Normal file
37
extensions/lock/locale/en.yml
Normal file
@ -0,0 +1,37 @@
|
||||
flarum-lock:
|
||||
|
||||
##
|
||||
# UNIQUE KEYS - The following keys are used in only one location each.
|
||||
##
|
||||
|
||||
# Translations in this namespace are used by the admin interface.
|
||||
admin:
|
||||
|
||||
# These translations are used in the Permissions page of the admin interface.
|
||||
permissions:
|
||||
lock_discussions_label: Lock discussions
|
||||
|
||||
# Translations in this namespace are used by the forum user interface.
|
||||
forum:
|
||||
|
||||
# These translations are displayed as tooltips for discussion badges.
|
||||
badge:
|
||||
locked_tooltip: Locked
|
||||
|
||||
# These translations are used by the discussion control buttons.
|
||||
discussion_controls:
|
||||
lock_button: Lock
|
||||
unlock_button: Unlock
|
||||
|
||||
# These translations are used by the Notifications dropdown, a.k.a. "the bell".
|
||||
notifications:
|
||||
discussion_locked_text: "{username} locked"
|
||||
|
||||
# These translations are displayed between posts in the post stream.
|
||||
post_stream:
|
||||
discussion_locked_text: "{username} locked the discussion."
|
||||
discussion_unlocked_text: "{username} unlocked the discussion."
|
||||
|
||||
# These translations are used in the Settings page.
|
||||
settings:
|
||||
notify_discussion_locked_label: Someone locks a discussion I started
|
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Flarum\Database\Migration;
|
||||
|
||||
return Migration::addColumns('discussions', [
|
||||
'is_locked' => ['boolean', 'default' => 0]
|
||||
]);
|
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Flarum\Database\Migration;
|
||||
use Flarum\Group\Group;
|
||||
|
||||
return Migration::addPermissions([
|
||||
'discussion.lock' => Group::MODERATOR_ID
|
||||
]);
|
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Schema\Builder;
|
||||
|
||||
return [
|
||||
'up' => function (Builder $schema) {
|
||||
$schema->table('discussions', function (Blueprint $table) {
|
||||
$table->index('is_locked');
|
||||
});
|
||||
},
|
||||
|
||||
'down' => function (Builder $schema) {
|
||||
$schema->table('discussions', function (Blueprint $table) {
|
||||
$table->dropIndex(['is_locked']);
|
||||
});
|
||||
}
|
||||
];
|
29
extensions/lock/src/Access/DiscussionPolicy.php
Executable file
29
extensions/lock/src/Access/DiscussionPolicy.php
Executable file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Lock\Access;
|
||||
|
||||
use Flarum\Discussion\Discussion;
|
||||
use Flarum\User\Access\AbstractPolicy;
|
||||
use Flarum\User\User;
|
||||
|
||||
class DiscussionPolicy extends AbstractPolicy
|
||||
{
|
||||
/**
|
||||
* @param User $actor
|
||||
* @param Discussion $discussion
|
||||
* @return bool
|
||||
*/
|
||||
public function reply(User $actor, Discussion $discussion)
|
||||
{
|
||||
if ($discussion->is_locked && $actor->cannot('lock', $discussion)) {
|
||||
return $this->deny();
|
||||
}
|
||||
}
|
||||
}
|
36
extensions/lock/src/Event/DiscussionWasLocked.php
Normal file
36
extensions/lock/src/Event/DiscussionWasLocked.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Lock\Event;
|
||||
|
||||
use Flarum\Discussion\Discussion;
|
||||
use Flarum\User\User;
|
||||
|
||||
class DiscussionWasLocked
|
||||
{
|
||||
/**
|
||||
* @var Discussion
|
||||
*/
|
||||
public $discussion;
|
||||
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* @param Discussion $discussion
|
||||
* @param User $user
|
||||
*/
|
||||
public function __construct(Discussion $discussion, User $user)
|
||||
{
|
||||
$this->discussion = $discussion;
|
||||
$this->user = $user;
|
||||
}
|
||||
}
|
36
extensions/lock/src/Event/DiscussionWasUnlocked.php
Normal file
36
extensions/lock/src/Event/DiscussionWasUnlocked.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Lock\Event;
|
||||
|
||||
use Flarum\Discussion\Discussion;
|
||||
use Flarum\User\User;
|
||||
|
||||
class DiscussionWasUnlocked
|
||||
{
|
||||
/**
|
||||
* @var Discussion
|
||||
*/
|
||||
public $discussion;
|
||||
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* @param Discussion $discussion
|
||||
* @param User $user
|
||||
*/
|
||||
public function __construct(Discussion $discussion, User $user)
|
||||
{
|
||||
$this->discussion = $discussion;
|
||||
$this->user = $user;
|
||||
}
|
||||
}
|
45
extensions/lock/src/Listener/CreatePostWhenDiscussionIsLocked.php
Executable file
45
extensions/lock/src/Listener/CreatePostWhenDiscussionIsLocked.php
Executable file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Lock\Listener;
|
||||
|
||||
use Flarum\Lock\Event\DiscussionWasLocked;
|
||||
use Flarum\Lock\Notification\DiscussionLockedBlueprint;
|
||||
use Flarum\Lock\Post\DiscussionLockedPost;
|
||||
use Flarum\Notification\NotificationSyncer;
|
||||
|
||||
class CreatePostWhenDiscussionIsLocked
|
||||
{
|
||||
/**
|
||||
* @var NotificationSyncer
|
||||
*/
|
||||
protected $notifications;
|
||||
|
||||
public function __construct(NotificationSyncer $notifications)
|
||||
{
|
||||
$this->notifications = $notifications;
|
||||
}
|
||||
|
||||
public function handle(DiscussionWasLocked $event)
|
||||
{
|
||||
$post = DiscussionLockedPost::reply(
|
||||
$event->discussion->id,
|
||||
$event->user->id,
|
||||
true
|
||||
);
|
||||
|
||||
$post = $event->discussion->mergePost($post);
|
||||
|
||||
if ($event->discussion->user_id !== $event->user->id) {
|
||||
$notification = new DiscussionLockedBlueprint($post);
|
||||
|
||||
$this->notifications->sync($notification, $post->exists ? [$event->discussion->user] : []);
|
||||
}
|
||||
}
|
||||
}
|
45
extensions/lock/src/Listener/CreatePostWhenDiscussionIsUnlocked.php
Executable file
45
extensions/lock/src/Listener/CreatePostWhenDiscussionIsUnlocked.php
Executable file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Lock\Listener;
|
||||
|
||||
use Flarum\Lock\Event\DiscussionWasUnlocked;
|
||||
use Flarum\Lock\Notification\DiscussionLockedBlueprint;
|
||||
use Flarum\Lock\Post\DiscussionLockedPost;
|
||||
use Flarum\Notification\NotificationSyncer;
|
||||
|
||||
class CreatePostWhenDiscussionIsUnlocked
|
||||
{
|
||||
/**
|
||||
* @var NotificationSyncer
|
||||
*/
|
||||
protected $notifications;
|
||||
|
||||
public function __construct(NotificationSyncer $notifications)
|
||||
{
|
||||
$this->notifications = $notifications;
|
||||
}
|
||||
|
||||
public function handle(DiscussionWasUnlocked $event)
|
||||
{
|
||||
$post = DiscussionLockedPost::reply(
|
||||
$event->discussion->id,
|
||||
$event->user->id,
|
||||
false
|
||||
);
|
||||
|
||||
$post = $event->discussion->mergePost($post);
|
||||
|
||||
if ($event->discussion->user_id !== $event->user->id) {
|
||||
$notification = new DiscussionLockedBlueprint($post);
|
||||
|
||||
$this->notifications->sync($notification, $post->exists ? [$event->discussion->user] : []);
|
||||
}
|
||||
}
|
||||
}
|
40
extensions/lock/src/Listener/SaveLockedToDatabase.php
Executable file
40
extensions/lock/src/Listener/SaveLockedToDatabase.php
Executable file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Lock\Listener;
|
||||
|
||||
use Flarum\Discussion\Event\Saving;
|
||||
use Flarum\Lock\Event\DiscussionWasLocked;
|
||||
use Flarum\Lock\Event\DiscussionWasUnlocked;
|
||||
|
||||
class SaveLockedToDatabase
|
||||
{
|
||||
public function handle(Saving $event)
|
||||
{
|
||||
if (isset($event->data['attributes']['isLocked'])) {
|
||||
$isLocked = (bool) $event->data['attributes']['isLocked'];
|
||||
$discussion = $event->discussion;
|
||||
$actor = $event->actor;
|
||||
|
||||
$actor->assertCan('lock', $discussion);
|
||||
|
||||
if ((bool) $discussion->is_locked === $isLocked) {
|
||||
return;
|
||||
}
|
||||
|
||||
$discussion->is_locked = $isLocked;
|
||||
|
||||
$discussion->raise(
|
||||
$discussion->is_locked
|
||||
? new DiscussionWasLocked($discussion, $actor)
|
||||
: new DiscussionWasUnlocked($discussion, $actor)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Lock\Notification;
|
||||
|
||||
use Flarum\Discussion\Discussion;
|
||||
use Flarum\Lock\Post\DiscussionLockedPost;
|
||||
use Flarum\Notification\Blueprint\BlueprintInterface;
|
||||
|
||||
class DiscussionLockedBlueprint implements BlueprintInterface
|
||||
{
|
||||
/**
|
||||
* @var DiscussionLockedPost
|
||||
*/
|
||||
protected $post;
|
||||
|
||||
/**
|
||||
* @param DiscussionLockedPost $post
|
||||
*/
|
||||
public function __construct(DiscussionLockedPost $post)
|
||||
{
|
||||
$this->post = $post;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFromUser()
|
||||
{
|
||||
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 Discussion::class;
|
||||
}
|
||||
}
|
79
extensions/lock/src/Post/DiscussionLockedPost.php
Executable file
79
extensions/lock/src/Post/DiscussionLockedPost.php
Executable file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Lock\Post;
|
||||
|
||||
use Flarum\Post\AbstractEventPost;
|
||||
use Flarum\Post\MergeableInterface;
|
||||
use Flarum\Post\Post;
|
||||
|
||||
class DiscussionLockedPost extends AbstractEventPost implements MergeableInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $type = 'discussionLocked';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function saveAfter(Post $previous = null)
|
||||
{
|
||||
// If the previous post is another 'discussion locked' post, and it's
|
||||
// by the same user, then we can merge this post into it. If we find
|
||||
// that we've in fact reverted the locked status, delete it. Otherwise,
|
||||
// update its content.
|
||||
if ($previous instanceof static && $this->user_id === $previous->user_id) {
|
||||
if ($previous->content['locked'] != $this->content['locked']) {
|
||||
$previous->delete();
|
||||
} else {
|
||||
$previous->content = $this->content;
|
||||
|
||||
$previous->save();
|
||||
}
|
||||
|
||||
return $previous;
|
||||
}
|
||||
|
||||
$this->save();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance in reply to a discussion.
|
||||
*
|
||||
* @param int $discussionId
|
||||
* @param int $userId
|
||||
* @param bool $isLocked
|
||||
* @return static
|
||||
*/
|
||||
public static function reply($discussionId, $userId, $isLocked)
|
||||
{
|
||||
$post = new static;
|
||||
|
||||
$post->content = static::buildContent($isLocked);
|
||||
$post->created_at = time();
|
||||
$post->discussion_id = $discussionId;
|
||||
$post->user_id = $userId;
|
||||
|
||||
return $post;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the content attribute.
|
||||
*
|
||||
* @param bool $isLocked Whether or not the discussion is locked.
|
||||
* @return array
|
||||
*/
|
||||
public static function buildContent($isLocked)
|
||||
{
|
||||
return ['locked' => (bool) $isLocked];
|
||||
}
|
||||
}
|
44
extensions/lock/src/Query/LockedFilterGambit.php
Normal file
44
extensions/lock/src/Query/LockedFilterGambit.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Lock\Query;
|
||||
|
||||
use Flarum\Filter\FilterInterface;
|
||||
use Flarum\Filter\FilterState;
|
||||
use Flarum\Search\AbstractRegexGambit;
|
||||
use Flarum\Search\SearchState;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
|
||||
class LockedFilterGambit extends AbstractRegexGambit implements FilterInterface
|
||||
{
|
||||
protected function getGambitPattern()
|
||||
{
|
||||
return 'is:locked';
|
||||
}
|
||||
|
||||
protected function conditions(SearchState $searchState, array $matches, $negate)
|
||||
{
|
||||
$this->constrain($searchState->getQuery(), $negate);
|
||||
}
|
||||
|
||||
public function getFilterKey(): string
|
||||
{
|
||||
return 'locked';
|
||||
}
|
||||
|
||||
public function filter(FilterState $filterState, string $filterValue, bool $negate)
|
||||
{
|
||||
$this->constrain($filterState->getQuery(), $negate);
|
||||
}
|
||||
|
||||
protected function constrain(Builder $query, bool $negate)
|
||||
{
|
||||
$query->where('is_locked', ! $negate);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user