Merge branch 'guest-handles'

v1.18.x
Julian Lam 10 years ago
commit 1ddb90720c

@ -90,6 +90,7 @@
"fork_success": "Successfully forked topic! Click here to go to the forked topic.",
"composer.title_placeholder": "Enter your topic title here...",
"composer.handle_placeholder": "Name",
"composer.discard": "Discard",
"composer.submit": "Submit",
"composer.replying_to": "Replying to %1",

@ -154,6 +154,8 @@ define('composer', [
push({
pid: pid,
uid: threadData.uid,
handle: threadData.handle,
title: $('<div/>').html(threadData.title).text(),
body: threadData.body,
modified: false,
@ -213,9 +215,11 @@ define('composer', [
}
function createNewComposer(post_uuid) {
var allowTopicsThumbnail = config.allowTopicsThumbnail && composer.posts[post_uuid].isMain && (config.hasImageUploadPlugin || config.allowFileUploads);
var isTopic = composer.posts[post_uuid] ? !!composer.posts[post_uuid].cid : false;
var isMain = composer.posts[post_uuid] ? !!composer.posts[post_uuid].isMain : false;
var allowTopicsThumbnail = config.allowTopicsThumbnail && composer.posts[post_uuid].isMain && (config.hasImageUploadPlugin || config.allowFileUploads),
isTopic = composer.posts[post_uuid] ? !!composer.posts[post_uuid].cid : false,
isMain = composer.posts[post_uuid] ? !!composer.posts[post_uuid].isMain : false,
isEditing = composer.posts[post_uuid] ? !!composer.posts[post_uuid].pid : false,
isGuestPost = composer.posts[post_uuid] ? composer.posts[post_uuid].uid === '0' : null;
composer.bsEnvironment = utils.findBootstrapEnvironment();
@ -224,7 +228,9 @@ define('composer', [
var data = {
allowTopicsThumbnail: allowTopicsThumbnail,
showTags: isTopic || isMain,
isTopic: isTopic
isTopic: isTopic,
showHandleInput: (app.user.uid === 0 || (isEditing && isGuestPost && app.user.isAdmin)) && config.allowGuestHandles,
handle: composer.posts[post_uuid] ? composer.posts[post_uuid].handle || '' : undefined
};
parseAndTranslate(template, data, function(composerTemplate) {
@ -377,6 +383,7 @@ define('composer', [
function post(post_uuid) {
var postData = composer.posts[post_uuid],
postContainer = $('#cmp-uuid-' + post_uuid),
handleEl = postContainer.find('.handle'),
titleEl = postContainer.find('.title'),
bodyEl = postContainer.find('textarea'),
thumbEl = postContainer.find('input#topic-thumb-url');
@ -405,6 +412,7 @@ define('composer', [
if (parseInt(postData.cid, 10) > 0) {
composerData = {
handle: handleEl ? handleEl.val() : undefined,
title: titleEl.val(),
content: bodyEl.val(),
topic_thumb: thumbEl.val() || '',
@ -423,6 +431,7 @@ define('composer', [
} else if (parseInt(postData.tid, 10) > 0) {
composerData = {
tid: postData.tid,
handle: handleEl ? handleEl.val() : undefined,
content: bodyEl.val(),
toPid: postData.toPid
};
@ -432,6 +441,7 @@ define('composer', [
} else if (parseInt(postData.pid, 10) > 0) {
composerData = {
pid: postData.pid,
handle: handleEl ? handleEl.val() : undefined,
content: bodyEl.val(),
title: titleEl.val(),
topic_thumb: thumbEl.val() || '',

@ -30,6 +30,7 @@ apiController.getConfig = function(req, res, next) {
config.maximumSignatureLength = meta.config.maximumSignatureLength;
config.useOutgoingLinksPage = parseInt(meta.config.useOutgoingLinksPage, 10) === 1;
config.allowGuestSearching = parseInt(meta.config.allowGuestSearching, 10) === 1;
config.allowGuestHandles = parseInt(meta.config.allowGuestHandles, 10) === 1;
config.allowFileUploads = parseInt(meta.config.allowFileUploads, 10) === 1;
config.allowTopicsThumbnail = parseInt(meta.config.allowTopicsThumbnail, 10) === 1;
config.allowAccountDelete = parseInt(meta.config.allowAccountDelete, 10) === 1;

@ -18,21 +18,22 @@ var winston = require('winston'),
(function(PostTools) {
PostTools.edit = function(uid, pid, title, content, options, callback) {
options = options || {};
PostTools.edit = function(data, callback) {
var options = data.options || {},
title = data.title.trim();
async.waterfall([
function (next) {
privileges.posts.canEdit(pid, uid, next);
privileges.posts.canEdit(data.pid, data.uid, next);
},
function(canEdit, next) {
if (!canEdit) {
return next(new Error('[[error:no-privileges]]'));
}
posts.getPostData(pid, next);
posts.getPostData(data.pid, next);
},
function(postData, next) {
postData.content = content;
postData.content = data.content;
plugins.fireHook('filter:post.save', postData, next);
}
], function(err, postData) {
@ -42,15 +43,16 @@ var winston = require('winston'),
async.parallel({
post: function(next) {
posts.setPostFields(pid, {
posts.setPostFields(data.pid, {
edited: Date.now(),
editor: uid,
editor: data.uid,
handle: data.handle,
content: postData.content
}, next);
},
topic: function(next) {
var tid = postData.tid;
posts.isMain(pid, function(err, isMainPost) {
posts.isMain(data.pid, function(err, isMainPost) {
if (err) {
return next(err);
}
@ -64,11 +66,9 @@ var winston = require('winston'),
});
}
title = title.trim();
var topicData = {
tid: tid,
mainPid: pid,
mainPid: data.pid,
title: title,
slug: tid + '/' + utils.slugify(title)
};
@ -96,7 +96,7 @@ var winston = require('winston'),
});
},
postData: function(next) {
PostTools.parsePost(postData, uid, next);
PostTools.parsePost(postData, data.uid, next);
}
}, function(err, results) {
if (err) {

@ -14,10 +14,10 @@ module.exports = function(Posts) {
Posts.create = function(data, callback) {
var uid = data.uid,
tid = data.tid,
handle = data.uid ? null : data.handle, // Only guests have handles!
content = data.content,
timestamp = data.timestamp || Date.now();
if (!uid && parseInt(uid, 10) !== 0) {
return callback(new Error('[[error:invalid-uid]]'));
}
@ -51,6 +51,10 @@ module.exports = function(Posts) {
postData.ip = data.ip;
}
if (handle) {
postData.handle = handle;
}
plugins.fireHook('filter:post.save', postData, next);
},
function(postData, next) {

@ -35,7 +35,7 @@ SocketModules.composer.push = function(socket, pid, callback) {
if (err || !canRead) {
return callback(err || new Error('[[error:no-privileges]]'));
}
posts.getPostFields(pid, ['content', 'tid'], function(err, postData) {
posts.getPostFields(pid, ['content', 'tid', 'uid', 'handle'], function(err, postData) {
if(err || (!postData && !postData.content)) {
return callback(err || new Error('[[error:invalid-pid]]'));
}
@ -61,6 +61,8 @@ SocketModules.composer.push = function(socket, pid, callback) {
callback(null, {
pid: pid,
uid: postData.uid,
handle: parseInt(meta.config.allowGuestHandles, 10) ? postData.handle : undefined,
body: postData.content,
title: results.topic.title,
topic_thumb: results.topic.thumb,

@ -257,13 +257,25 @@ SocketPosts.edit = function(socket, data, callback) {
return callback(new Error('[[error:content-too-short, ' + meta.config.minimumPostLength + ']]'));
}
postTools.edit(socket.uid, data.pid, data.title, data.content, {topic_thumb: data.topic_thumb, tags: data.tags}, function(err, results) {
// uid, pid, title, content, options
postTools.edit({
uid: socket.uid,
handle: data.handle,
pid: data.pid,
title: data.title,
content: data.content,
options: {
topic_thumb: data.topic_thumb,
tags: data.tags
}
}, function(err, results) {
if (err) {
return callback(err);
}
websockets.in('topic_' + results.topic.tid).emit('event:post_edited', {
pid: data.pid,
handle: data.handle,
title: results.topic.title,
isMainPost: results.topic.isMainPost,
tags: results.topic.tags,

@ -27,6 +27,7 @@ SocketTopics.post = function(socket, data, callback) {
topics.post({
uid: socket.uid,
handle: data.handle,
title: data.title,
content: data.content,
cid: data.category_id,

@ -93,6 +93,7 @@ module.exports = function(Topics) {
Topics.post = function(data, callback) {
var uid = data.uid,
handle = data.handle,
title = data.title,
content = data.content,
cid = data.cid;
@ -134,7 +135,7 @@ module.exports = function(Topics) {
Topics.create({uid: uid, title: title, cid: cid, thumb: data.thumb, tags: data.tags}, next);
},
function(tid, next) {
Topics.reply({uid:uid, tid:tid, content:content, req: data.req}, next);
Topics.reply({uid:uid, tid:tid, handle: handle, content:content, req: data.req}, next);
},
function(postData, next) {
async.parallel({
@ -184,6 +185,7 @@ module.exports = function(Topics) {
var tid = data.tid,
uid = data.uid,
toPid = data.toPid,
handle = data.handle,
content = data.content,
postData;
@ -226,7 +228,7 @@ module.exports = function(Topics) {
checkContentLength(content, next);
},
function(next) {
posts.create({uid: uid, tid: tid, content: content, toPid: toPid, ip: data.req ? data.req.ip : null}, next);
posts.create({uid: uid, tid: tid, handle: handle, content: content, toPid: toPid, ip: data.req ? data.req.ip : null}, next);
},
function(data, next) {
postData = data;
@ -258,6 +260,11 @@ module.exports = function(Topics) {
postData.user = results.userInfo[0];
postData.topic = results.topicInfo;
// Username override for guests, if enabled
if (parseInt(meta.config.allowGuestHandles, 10) === 1 && parseInt(postData.uid, 10) === 0 && data.handle) {
postData.user.username = data.handle;
}
if (results.settings.followTopicsOnReply) {
threadTools.follow(postData.tid, uid);
}

@ -4,12 +4,14 @@
var async = require('async'),
winston = require('winston'),
_ = require('underscore'),
db = require('../database'),
user = require('../user'),
favourites = require('../favourites'),
posts = require('../posts'),
privileges = require('../privileges');
privileges = require('../privileges'),
meta = require('../meta');
module.exports = function(Topics) {
@ -110,25 +112,32 @@ module.exports = function(Topics) {
return callback(err);
}
for (var i = 0; i < postData.length; ++i) {
if (postData[i]) {
postData[i].index = results.indices[i];
postData[i].deleted = parseInt(postData[i].deleted, 10) === 1;
postData[i].user = results.userData[postData[i].uid];
postData[i].editor = postData[i].editor ? results.editors[postData[i].editor] : null;
postData[i].favourited = results.favourites[i];
postData[i].upvoted = results.voteData.upvotes[i];
postData[i].downvoted = results.voteData.downvotes[i];
postData[i].votes = postData[i].votes || 0;
postData[i].display_moderator_tools = results.privileges[i].editable;
postData[i].display_move_tools = results.privileges[i].move && postData[i].index !== 0;
postData[i].selfPost = parseInt(uid, 10) === parseInt(postData[i].uid, 10);
if(postData[i].deleted && !results.privileges[i].view_deleted) {
postData[i].content = '[[topic:post_is_deleted]]';
postData = postData.map(function(postObj, i) {
if (postObj) {
postObj.index = results.indices[i];
postObj.deleted = parseInt(postObj.deleted, 10) === 1;
postObj.user = _.clone(results.userData[postObj.uid]);
postObj.editor = postObj.editor ? results.editors[postObj.editor] : null;
postObj.favourited = results.favourites[i];
postObj.upvoted = results.voteData.upvotes[i];
postObj.downvoted = results.voteData.downvotes[i];
postObj.votes = postObj.votes || 0;
postObj.display_moderator_tools = results.privileges[i].editable;
postObj.display_move_tools = results.privileges[i].move && postObj.index !== 0;
postObj.selfPost = parseInt(uid, 10) === parseInt(postObj.uid, 10);
if(postObj.deleted && !results.privileges[i].view_deleted) {
postObj.content = '[[topic:post_is_deleted]]';
}
// Username override for guests, if enabled
if (parseInt(meta.config.allowGuestHandles, 10) === 1 && parseInt(postObj.uid, 10) === 0 && postObj.handle) {
postObj.user.username = postObj.handle;
}
}
}
return postObj;
}).filter(Boolean);
callback(null, postData);
});

@ -101,95 +101,7 @@
<div class="wrapper">
<div id="main-menu" class="nano">
<div class="nano-content">
<div class="sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header"><i class="fa fa-fw fa-dashboard"></i> General</li>
<li class="active"><a href="{relative_path}/admin/general/dashboard">Dashboard</a></li>
<li><a href="{relative_path}/admin/general/languages">Languages</a></li>
<li><a href="{relative_path}/admin/general/sounds">Sounds</a></li>
</ul>
</div>
<div class="sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header"><i class="fa fa-fw fa-comments-o"></i> Manage</li>
<li><a href="{relative_path}/admin/manage/categories/active">Categories</a></li>
<li><a href="{relative_path}/admin/manage/tags">Tags</a></li>
<li><a href="{relative_path}/admin/manage/users">Users</a></li>
<li><a href="{relative_path}/admin/manage/groups">Groups</a></li>
<li><a href="{relative_path}/admin/manage/flags">Flags</a></li>
</ul>
</div>
<div class="sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header"><i class="fa fa-fw fa-cogs"></i> Settings</li>
<li><a href="{relative_path}/admin/settings/general">General</a></li>
<li><a href="{relative_path}/admin/settings/reputation">Reputation</a></li>
<li><a href="{relative_path}/admin/settings/email">Email</a></li>
<li><a href="{relative_path}/admin/settings/user">User</a></li>
<li><a href="{relative_path}/admin/settings/post">Post</a></li>
<li><a href="{relative_path}/admin/settings/pagination">Pagination</a></li>
<li><a href="{relative_path}/admin/settings/tags">Tags</a></li>
<li><a href="{relative_path}/admin/settings/notifications">Notifications</a></li>
<li><a href="{relative_path}/admin/settings/web-crawler">Web Crawler</a></li>
<li><a href="{relative_path}/admin/settings/sockets">Sockets</a></li>
<li><a href="{relative_path}/admin/settings/advanced">Advanced</a></li>
</ul>
</div>
<div class="sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header"><i class="fa fa-fw fa-paint-brush"></i> Appearance</li>
<li><a href="{relative_path}/admin/appearance/themes">Themes</a></li>
<li><a href="{relative_path}/admin/appearance/skins">Skins</a></li>
<li><a href="{relative_path}/admin/appearance/customise">Custom HTML & CSS</a></li>
</ul>
</div>
<div class="sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header"><i class="fa fa-fw fa-wrench"></i> Extend</li>
<li><a href="{relative_path}/admin/extend/plugins">Plugins</a></li>
<li><a href="{relative_path}/admin/extend/widgets">Widgets</a></li>
</ul>
</div>
<div class="sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header"><i class="fa fa-fw fa-hdd-o"></i> Advanced</li>
<li><a href="{relative_path}/admin/advanced/database">Database</a></li>
<li><a href="{relative_path}/admin/advanced/events">Events</a></li>
<li><a href="{relative_path}/admin/advanced/logs">Logs</a></li>
</ul>
</div>
<!-- IF authentication.length -->
<div class="sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header"><i class="fa fa-fw fa-facebook-square"></i> Social Authentication</li>
<!-- BEGIN authentication -->
<li>
<a href="{relative_path}/admin{authentication.route}">{authentication.name}</a>
</li>
<!-- END authentication -->
</ul>
</div>
<!-- ENDIF authentication.length -->
<!-- IF plugins.length -->
<div class="sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header"><i class="fa fa-fw fa-th"></i> Installed Plugins</li>
<!-- BEGIN plugins -->
<li>
<a href="{relative_path}/admin{plugins.route}">{plugins.name}</a>
</li>
<!-- END plugins -->
</ul>
</div>
<!-- ENDIF plugins.length -->
<!-- IF env -->
<div class="sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header"><i class="fa fa-fw fa-th"></i> Development</li>
<li><a href="{relative_path}/admin/development/logger">Logger</a></li>
</ul>
</div>
<!-- ENDIF env -->
<!-- IMPORT admin/partials/menu.tpl -->
</div>
</div>
<div class="col-sm-12" id="content">

@ -0,0 +1,90 @@
<div class="sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header"><i class="fa fa-fw fa-dashboard"></i> General</li>
<li class="active"><a href="{relative_path}/admin/general/dashboard">Dashboard</a></li>
<li><a href="{relative_path}/admin/general/languages">Languages</a></li>
<li><a href="{relative_path}/admin/general/sounds">Sounds</a></li>
</ul>
</div>
<div class="sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header"><i class="fa fa-fw fa-comments-o"></i> Manage</li>
<li><a href="{relative_path}/admin/manage/categories">Categories</a></li>
<li><a href="{relative_path}/admin/manage/tags">Tags</a></li>
<li><a href="{relative_path}/admin/manage/users">Users</a></li>
<li><a href="{relative_path}/admin/manage/groups">Groups</a></li>
<li><a href="{relative_path}/admin/manage/flags">Flags</a></li>
</ul>
</div>
<div class="sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header"><i class="fa fa-fw fa-cogs"></i> Settings</li>
<li><a href="{relative_path}/admin/settings/general">General</a></li>
<li><a href="{relative_path}/admin/settings/reputation">Reputation</a></li>
<li><a href="{relative_path}/admin/settings/email">Email</a></li>
<li><a href="{relative_path}/admin/settings/user">User</a></li>
<li><a href="{relative_path}/admin/settings/guest">Guest</a></li>
<li><a href="{relative_path}/admin/settings/post">Post</a></li>
<li><a href="{relative_path}/admin/settings/pagination">Pagination</a></li>
<li><a href="{relative_path}/admin/settings/tags">Tags</a></li>
<li><a href="{relative_path}/admin/settings/notifications">Notifications</a></li>
<li><a href="{relative_path}/admin/settings/web-crawler">Web Crawler</a></li>
<li><a href="{relative_path}/admin/settings/sockets">Sockets</a></li>
<li><a href="{relative_path}/admin/settings/advanced">Advanced</a></li>
</ul>
</div>
<div class="sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header"><i class="fa fa-fw fa-paint-brush"></i> Appearance</li>
<li><a href="{relative_path}/admin/appearance/themes">Themes</a></li>
<li><a href="{relative_path}/admin/appearance/skins">Skins</a></li>
<li><a href="{relative_path}/admin/appearance/customise">Custom HTML &amp; CSS</a></li>
</ul>
</div>
<div class="sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header"><i class="fa fa-fw fa-wrench"></i> Extend</li>
<li><a href="{relative_path}/admin/extend/plugins">Plugins</a></li>
<li><a href="{relative_path}/admin/extend/widgets">Widgets</a></li>
</ul>
</div>
<div class="sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header"><i class="fa fa-fw fa-hdd-o"></i> Advanced</li>
<li><a href="{relative_path}/admin/advanced/database">Database</a></li>
<li><a href="{relative_path}/admin/advanced/events">Events</a></li>
<li><a href="{relative_path}/admin/advanced/logs">Logs</a></li>
</ul>
</div>
<!-- IF authentication.length -->
<div class="sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header"><i class="fa fa-fw fa-facebook-square"></i> Social Authentication</li>
<!-- BEGIN authentication -->
<li>
<a href="{relative_path}/admin{authentication.route}">{authentication.name}</a>
</li>
<!-- END authentication -->
</ul>
</div>
<!-- ENDIF authentication.length -->
<!-- IF plugins.length -->
<div class="sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header"><i class="fa fa-fw fa-th"></i> Installed Plugins</li>
<!-- BEGIN plugins -->
<li>
<a href="{relative_path}/admin{plugins.route}">{plugins.name}</a>
</li>
<!-- END plugins -->
</ul>
</div>
<!-- ENDIF plugins.length -->
<!-- IF env -->
<div class="sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header"><i class="fa fa-fw fa-th"></i> Development</li>
<li><a href="{relative_path}/admin/development/logger">Logger</a></li>
</ul>
</div>
<!-- ENDIF env -->

@ -0,0 +1,25 @@
<!-- IMPORT admin/settings/header.tpl -->
<div class="panel panel-default">
<div class="panel-heading">Guests</div>
<div class="panel-body">
<p class="alert alert-info">
These options affect guest users as a whole. Control over which categories a guest can see or post to is handled in
the categories themselves
</p>
<form role="form">
<div class="checkbox">
<label>
<input type="checkbox" data-field="allowGuestHandles"> <strong>Allow guest handles</strong>
<p class="help-block">
This option exposes a new field that allows guests to pick a name to associate with each post they make. If disabled,
the will simply be called "Guest" (or the equivalent in the forum&apos;s selected language)
</p>
</label>
</div>
</form>
</div>
</div>
<!-- IMPORT admin/settings/footer.tpl -->
Loading…
Cancel
Save