mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-31 02:55:58 +01:00 
			
		
		
		
	feat: #8900, postQueue setting for category
This commit is contained in:
		| @@ -20,6 +20,7 @@ | |||||||
|     "chatDeleteDuration": 0, |     "chatDeleteDuration": 0, | ||||||
|     "chatMessageDelay": 200, |     "chatMessageDelay": 200, | ||||||
|     "newbiePostDelayThreshold": 3, |     "newbiePostDelayThreshold": 3, | ||||||
|  |     "postQueue": 0, | ||||||
|     "postQueueReputationThreshold": 0, |     "postQueueReputationThreshold": 0, | ||||||
|     "groupsExemptFromPostQueue": ["administrators", "Global Moderators"], |     "groupsExemptFromPostQueue": ["administrators", "Global Moderators"], | ||||||
|     "minimumPostLength": 8, |     "minimumPostLength": 8, | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ | |||||||
| 	"num-recent-replies": "# of Recent Replies", | 	"num-recent-replies": "# of Recent Replies", | ||||||
| 	"ext-link": "External Link", | 	"ext-link": "External Link", | ||||||
| 	"is-section": "Treat this category as a section", | 	"is-section": "Treat this category as a section", | ||||||
|  | 	"post-queue": "Post queue", | ||||||
| 	"tag-whitelist": "Tag Whitelist", | 	"tag-whitelist": "Tag Whitelist", | ||||||
| 	"upload-image": "Upload Image", | 	"upload-image": "Upload Image", | ||||||
| 	"delete-image": "Remove", | 	"delete-image": "Remove", | ||||||
|   | |||||||
| @@ -21,7 +21,6 @@ topicsAPI.create = async function (caller, data) { | |||||||
| 	const payload = { ...data }; | 	const payload = { ...data }; | ||||||
| 	payload.tags = payload.tags || []; | 	payload.tags = payload.tags || []; | ||||||
| 	payload.uid = caller.uid; | 	payload.uid = caller.uid; | ||||||
| 	payload.uid = caller.uid; |  | ||||||
| 	payload.req = apiHelpers.buildReqObject(caller); | 	payload.req = apiHelpers.buildReqObject(caller); | ||||||
| 	payload.timestamp = Date.now(); | 	payload.timestamp = Date.now(); | ||||||
| 	payload.fromQueue = false; | 	payload.fromQueue = false; | ||||||
|   | |||||||
| @@ -5,11 +5,12 @@ const validator = require('validator'); | |||||||
| const db = require('../database'); | const db = require('../database'); | ||||||
| const meta = require('../meta'); | const meta = require('../meta'); | ||||||
| const plugins = require('../plugins'); | const plugins = require('../plugins'); | ||||||
|  | const utils = require('../utils'); | ||||||
|  |  | ||||||
| const intFields = [ | const intFields = [ | ||||||
| 	'cid', 'parentCid', 'disabled', 'isSection', 'order', | 	'cid', 'parentCid', 'disabled', 'isSection', 'order', | ||||||
| 	'topic_count', 'post_count', 'numRecentReplies', | 	'topic_count', 'post_count', 'numRecentReplies', | ||||||
| 	'minTags', 'maxTags', | 	'minTags', 'maxTags', 'postQueue', | ||||||
| ]; | ]; | ||||||
|  |  | ||||||
| module.exports = function (Categories) { | module.exports = function (Categories) { | ||||||
| @@ -63,12 +64,13 @@ module.exports = function (Categories) { | |||||||
| 	}; | 	}; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| function defaultMinMaxTags(category, fields, fieldName, defaultField) { | function defaultIntField(category, fields, fieldName, defaultField) { | ||||||
| 	if (!fields.length || fields.includes(fieldName)) { | 	if (!fields.length || fields.includes(fieldName)) { | ||||||
| 		const useDefault = !category.hasOwnProperty(fieldName) || | 		const useDefault = !category.hasOwnProperty(fieldName) || | ||||||
| 			category[fieldName] === null || | 			category[fieldName] === null || | ||||||
| 			category[fieldName] === '' || | 			category[fieldName] === '' || | ||||||
| 			!parseInt(category[fieldName], 10); | 			!utils.isNumber(category[fieldName]); | ||||||
|  |  | ||||||
| 		category[fieldName] = useDefault ? meta.config[defaultField] : category[fieldName]; | 		category[fieldName] = useDefault ? meta.config[defaultField] : category[fieldName]; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -78,8 +80,9 @@ function modifyCategory(category, fields) { | |||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	defaultMinMaxTags(category, fields, 'minTags', 'minimumTagsPerTopic'); | 	defaultIntField(category, fields, 'minTags', 'minimumTagsPerTopic'); | ||||||
| 	defaultMinMaxTags(category, fields, 'maxTags', 'maximumTagsPerTopic'); | 	defaultIntField(category, fields, 'maxTags', 'maximumTagsPerTopic'); | ||||||
|  | 	defaultIntField(category, fields, 'postQueue', 'postQueue'); | ||||||
|  |  | ||||||
| 	db.parseIntFields(category, intFields, fields); | 	db.parseIntFields(category, intFields, fields); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ const categories = require('../../categories'); | |||||||
| const analytics = require('../../analytics'); | const analytics = require('../../analytics'); | ||||||
| const plugins = require('../../plugins'); | const plugins = require('../../plugins'); | ||||||
| const translator = require('../../translator'); | const translator = require('../../translator'); | ||||||
|  | const meta = require('../../meta'); | ||||||
|  |  | ||||||
| const categoriesController = module.exports; | const categoriesController = module.exports; | ||||||
|  |  | ||||||
| @@ -42,6 +43,7 @@ categoriesController.get = async function (req, res, next) { | |||||||
| 		categories: data.allCategories, | 		categories: data.allCategories, | ||||||
| 		selectedCategory: selectedCategory, | 		selectedCategory: selectedCategory, | ||||||
| 		customClasses: data.customClasses, | 		customClasses: data.customClasses, | ||||||
|  | 		postQueueEnabled: !!meta.config.postQueue, | ||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -15,9 +15,15 @@ const socketHelpers = require('../socket.io/helpers'); | |||||||
|  |  | ||||||
| module.exports = function (Posts) { | module.exports = function (Posts) { | ||||||
| 	Posts.shouldQueue = async function (uid, data) { | 	Posts.shouldQueue = async function (uid, data) { | ||||||
| 		const userData = await user.getUserFields(uid, ['uid', 'reputation', 'postcount']); | 		const [userData, isMemberOfExempt, categoryQueueEnabled] = await Promise.all([ | ||||||
| 		const isMemberOfExempt = await groups.isMemberOfAny(userData.uid, meta.config.groupsExemptFromPostQueue); | 			user.getUserFields(uid, ['uid', 'reputation', 'postcount']), | ||||||
| 		const shouldQueue = meta.config.postQueue && !isMemberOfExempt && (!userData.uid || userData.reputation < meta.config.postQueueReputationThreshold || userData.postcount <= 0); | 			groups.isMemberOfAny(uid, meta.config.groupsExemptFromPostQueue), | ||||||
|  | 			isCategoryQueueEnabled(data), | ||||||
|  | 		]); | ||||||
|  |  | ||||||
|  | 		const shouldQueue = meta.config.postQueue && categoryQueueEnabled && | ||||||
|  | 			!isMemberOfExempt && | ||||||
|  | 			(!userData.uid || userData.reputation < meta.config.postQueueReputationThreshold || userData.postcount <= 0); | ||||||
| 		const result = await plugins.hooks.fire('filter:post.shouldQueue', { | 		const result = await plugins.hooks.fire('filter:post.shouldQueue', { | ||||||
| 			shouldQueue: !!shouldQueue, | 			shouldQueue: !!shouldQueue, | ||||||
| 			uid: uid, | 			uid: uid, | ||||||
| @@ -26,6 +32,24 @@ module.exports = function (Posts) { | |||||||
| 		return result.shouldQueue; | 		return result.shouldQueue; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
|  | 	async function isCategoryQueueEnabled(data) { | ||||||
|  | 		const type = getType(data); | ||||||
|  | 		const cid = await getCid(type, data); | ||||||
|  | 		if (!cid) { | ||||||
|  | 			throw new Error('[[error:invalid-cid]]'); | ||||||
|  | 		} | ||||||
|  | 		return await categories.getCategoryField(cid, 'postQueue'); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	function getType(data) { | ||||||
|  | 		if (data.tid && data.content) { | ||||||
|  | 			return 'reply'; | ||||||
|  | 		} else if (data.cid && data.title && data.content) { | ||||||
|  | 			return 'topic'; | ||||||
|  | 		} | ||||||
|  | 		throw new Error('[[error:invalid-type]]'); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	async function removeQueueNotification(id) { | 	async function removeQueueNotification(id) { | ||||||
| 		await notifications.rescind('post-queue-' + id); | 		await notifications.rescind('post-queue-' + id); | ||||||
| 		const data = await getParsedObject(id); | 		const data = await getParsedObject(id); | ||||||
| @@ -46,7 +70,7 @@ module.exports = function (Posts) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Posts.addToQueue = async function (data) { | 	Posts.addToQueue = async function (data) { | ||||||
| 		const type = data.title ? 'topic' : 'reply'; | 		const type = getType(data); | ||||||
| 		const now = Date.now(); | 		const now = Date.now(); | ||||||
| 		const id = type + '-' + now; | 		const id = type + '-' + now; | ||||||
| 		await canPost(type, data); | 		await canPost(type, data); | ||||||
|   | |||||||
| @@ -80,16 +80,6 @@ | |||||||
| 							<input id="cid-{category.cid}-link" type="text" class="form-control" placeholder="http://domain.com" data-name="link" value="{category.link}" /> | 							<input id="cid-{category.cid}-link" type="text" class="form-control" placeholder="http://domain.com" data-name="link" value="{category.link}" /> | ||||||
| 						</div> | 						</div> | ||||||
| 					</div> | 					</div> | ||||||
| 					<div class="col-sm-6 col-xs-12"> |  | ||||||
| 						<div class="form-group"> |  | ||||||
| 							<div class="checkbox"> |  | ||||||
| 								<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect"> |  | ||||||
| 									<input type="checkbox" class="mdl-switch__input" id="cid-{category.cid}-isSection" data-name="isSection" <!-- IF category.isSection -->checked<!-- ENDIF category.isSection --> /> |  | ||||||
| 									<span class="mdl-switch__label"><strong>[[admin/manage/categories:is-section]]</strong></span> |  | ||||||
| 								</label> |  | ||||||
| 							</div> |  | ||||||
| 						</div> |  | ||||||
| 					</div> |  | ||||||
| 				</fieldset> | 				</fieldset> | ||||||
| 				<fieldset class="row"> | 				<fieldset class="row"> | ||||||
| 					<div class="col-sm-6 col-xs-12"> | 					<div class="col-sm-6 col-xs-12"> | ||||||
| @@ -111,10 +101,36 @@ | |||||||
| 				</fieldset> | 				</fieldset> | ||||||
| 				<fieldset class="row"> | 				<fieldset class="row"> | ||||||
| 					<div class="col-lg-12"> | 					<div class="col-lg-12"> | ||||||
| 						<label for="tag-whitelist">[[admin/manage/categories:tag-whitelist]]</label><br /> | 						<div class="form-group"> | ||||||
| 						<input id="tag-whitelist" type="text" class="form-control" data-name="tagWhitelist" value="" /> | 							<label for="tag-whitelist">[[admin/manage/categories:tag-whitelist]]</label><br /> | ||||||
|  | 							<input id="tag-whitelist" type="text" class="form-control" data-name="tagWhitelist" value="" /> | ||||||
|  | 						</div> | ||||||
| 					</div> | 					</div> | ||||||
| 				</fieldset> | 				</fieldset> | ||||||
|  | 				<fieldset class="row"> | ||||||
|  | 					<div class="col-lg-6"> | ||||||
|  | 						<div class="form-group"> | ||||||
|  | 							<div class="checkbox"> | ||||||
|  | 								<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect"> | ||||||
|  | 									<input type="checkbox" class="mdl-switch__input" id="cid-{category.cid}-isSection" data-name="isSection" <!-- IF category.isSection -->checked<!-- ENDIF category.isSection --> /> | ||||||
|  | 									<span class="mdl-switch__label"><strong>[[admin/manage/categories:is-section]]</strong></span> | ||||||
|  | 								</label> | ||||||
|  | 							</div> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 					{{{ if postQueueEnabled }}} | ||||||
|  | 					<div class="col-lg-6"> | ||||||
|  | 						<div class="form-group"> | ||||||
|  | 							<div class="checkbox"> | ||||||
|  | 								<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect"> | ||||||
|  | 									<input type="checkbox" class="mdl-switch__input" data-name="postQueue" {{{ if category.postQueue }}}checked{{{ end }}} /> | ||||||
|  | 									<span class="mdl-switch__label"><strong>[[admin/manage/categories:post-queue]]</strong></span> | ||||||
|  | 								</label> | ||||||
|  | 							</div> | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 					{{{ end }}} | ||||||
|  | 				</fieldset> | ||||||
| 			</div> | 			</div> | ||||||
| 		</div> | 		</div> | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user