From cb4fb62d4a476c941c96f54638cbef7972cd03b3 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Mon, 29 Dec 2014 15:52:32 -0500 Subject: [PATCH 1/7] moved ACP menu into a partial --- src/views/admin/header.tpl | 90 +------------------------------ src/views/admin/partials/menu.tpl | 89 ++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 89 deletions(-) create mode 100644 src/views/admin/partials/menu.tpl diff --git a/src/views/admin/header.tpl b/src/views/admin/header.tpl index 2b14ff8e1f..dfa2dc9c89 100644 --- a/src/views/admin/header.tpl +++ b/src/views/admin/header.tpl @@ -101,95 +101,7 @@
\ No newline at end of file diff --git a/src/views/admin/partials/menu.tpl b/src/views/admin/partials/menu.tpl new file mode 100644 index 0000000000..af9acc8e12 --- /dev/null +++ b/src/views/admin/partials/menu.tpl @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + \ No newline at end of file From fcbb48bb773ca50f3fdeb69126b6e42d71a28b67 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Wed, 31 Dec 2014 12:16:20 -0500 Subject: [PATCH 2/7] acp setting for allowGuestHandles #2569 --- src/views/admin/partials/menu.tpl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/views/admin/partials/menu.tpl b/src/views/admin/partials/menu.tpl index af9acc8e12..7059ad6ba0 100644 --- a/src/views/admin/partials/menu.tpl +++ b/src/views/admin/partials/menu.tpl @@ -23,6 +23,7 @@
  • Reputation
  • Email
  • User
  • +
  • Guest
  • Post
  • Pagination
  • Tags
  • From 7dc309fc16088fa0462f83c4fe394a9fa1c96480 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Wed, 31 Dec 2014 12:36:25 -0500 Subject: [PATCH 3/7] template in composer #2569 --- public/language/en_GB/topic.json | 1 + public/src/modules/composer.js | 3 ++- src/controllers/api.js | 1 + src/views/admin/settings/guest.tpl | 25 +++++++++++++++++++++++++ 4 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 src/views/admin/settings/guest.tpl diff --git a/public/language/en_GB/topic.json b/public/language/en_GB/topic.json index 88b1662e3b..5488475e10 100644 --- a/public/language/en_GB/topic.json +++ b/public/language/en_GB/topic.json @@ -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": "Enter your guest handle", "composer.discard": "Discard", "composer.submit": "Submit", "composer.replying_to": "Replying to %1", diff --git a/public/src/modules/composer.js b/public/src/modules/composer.js index e9ae8e8b5d..1a62a5e6e6 100644 --- a/public/src/modules/composer.js +++ b/public/src/modules/composer.js @@ -224,7 +224,8 @@ define('composer', [ var data = { allowTopicsThumbnail: allowTopicsThumbnail, showTags: isTopic || isMain, - isTopic: isTopic + isTopic: isTopic, + allowGuestHandles: config.allowGuestHandles }; parseAndTranslate(template, data, function(composerTemplate) { diff --git a/src/controllers/api.js b/src/controllers/api.js index 2648f944b4..52bfd6233f 100644 --- a/src/controllers/api.js +++ b/src/controllers/api.js @@ -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; diff --git a/src/views/admin/settings/guest.tpl b/src/views/admin/settings/guest.tpl new file mode 100644 index 0000000000..a212547164 --- /dev/null +++ b/src/views/admin/settings/guest.tpl @@ -0,0 +1,25 @@ + + +
    +
    Guests
    +
    +

    + 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 +

    + +
    +
    + +
    +
    +
    +
    + + \ No newline at end of file From b97c9e4467522e3e6e718b992b2631a5a4cbca39 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Wed, 31 Dec 2014 12:44:26 -0500 Subject: [PATCH 4/7] shorter language string for composer guest handle placeholder, #2569 --- public/language/en_GB/topic.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/language/en_GB/topic.json b/public/language/en_GB/topic.json index 5488475e10..1320e21923 100644 --- a/public/language/en_GB/topic.json +++ b/public/language/en_GB/topic.json @@ -90,7 +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": "Enter your guest handle", + "composer.handle_placeholder": "Name", "composer.discard": "Discard", "composer.submit": "Submit", "composer.replying_to": "Replying to %1", From 325815a78d25f21b1be3c2d5872b219f3d9f6aff Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Wed, 31 Dec 2014 16:27:35 -0500 Subject: [PATCH 5/7] showing guest handles in frontend UI #2569 --- public/src/modules/composer.js | 4 ++++ src/postTools.js | 23 ++++++++++--------- src/posts/create.js | 6 ++++- src/socket.io/posts.js | 12 +++++++++- src/socket.io/topics.js | 1 + src/topics/create.js | 6 +++-- src/topics/posts.js | 40 ++++++++++++++++++++-------------- 7 files changed, 60 insertions(+), 32 deletions(-) diff --git a/public/src/modules/composer.js b/public/src/modules/composer.js index 1a62a5e6e6..6615c51df5 100644 --- a/public/src/modules/composer.js +++ b/public/src/modules/composer.js @@ -378,6 +378,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'); @@ -406,6 +407,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() || '', @@ -424,6 +426,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 }; @@ -433,6 +436,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() || '', diff --git a/src/postTools.js b/src/postTools.js index 0e8d3934ce..c9e7648ea9 100644 --- a/src/postTools.js +++ b/src/postTools.js @@ -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,15 @@ var winston = require('winston'), async.parallel({ post: function(next) { - posts.setPostFields(pid, { + posts.setPostFields(data.pid, { edited: Date.now(), - editor: uid, + editor: data.uid, 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 +65,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 +95,7 @@ var winston = require('winston'), }); }, postData: function(next) { - PostTools.parsePost(postData, uid, next); + PostTools.parsePost(postData, data.uid, next); } }, function(err, results) { if (err) { diff --git a/src/posts/create.js b/src/posts/create.js index d9040e443e..198b9baae4 100644 --- a/src/posts/create.js +++ b/src/posts/create.js @@ -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) { diff --git a/src/socket.io/posts.js b/src/socket.io/posts.js index 1b7193ccf0..de66e6a5e3 100644 --- a/src/socket.io/posts.js +++ b/src/socket.io/posts.js @@ -257,7 +257,17 @@ 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, + 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); } diff --git a/src/socket.io/topics.js b/src/socket.io/topics.js index e5222e04a5..fe2c313452 100644 --- a/src/socket.io/topics.js +++ b/src/socket.io/topics.js @@ -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, diff --git a/src/topics/create.js b/src/topics/create.js index 71a1dddec4..25053ef819 100644 --- a/src/topics/create.js +++ b/src/topics/create.js @@ -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; diff --git a/src/topics/posts.js b/src/topics/posts.js index 0666303630..6653c15934 100644 --- a/src/topics/posts.js +++ b/src/topics/posts.js @@ -4,6 +4,7 @@ var async = require('async'), winston = require('winston'), + _ = require('underscore'), db = require('../database'), user = require('../user'), @@ -110,25 +111,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); + 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(postData[i].deleted && !results.privileges[i].view_deleted) { - postData[i].content = '[[topic:post_is_deleted]]'; + if(postObj.deleted && !results.privileges[i].view_deleted) { + postObj.content = '[[topic:post_is_deleted]]'; + } + + // Username override for guests, if enabled + if (parseInt(postObj.uid, 10) === 0 && postObj.handle) { + postObj.user.username = postObj.handle; } } - } + + return postObj; + }).filter(Boolean); callback(null, postData); }); From 9befa6aca74e0ba53f2859d28ec30f82ab8b247f Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Wed, 31 Dec 2014 20:48:32 -0500 Subject: [PATCH 6/7] proper handling of post editing, integration with ACP toggle, #2569 --- public/src/modules/composer.js | 11 +++++++---- src/socket.io/modules.js | 3 ++- src/topics/posts.js | 5 +++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/public/src/modules/composer.js b/public/src/modules/composer.js index 6615c51df5..a07af172f1 100644 --- a/public/src/modules/composer.js +++ b/public/src/modules/composer.js @@ -154,6 +154,7 @@ define('composer', [ push({ pid: pid, + uid: threadData.uid, title: $('
    ').html(threadData.title).text(), body: threadData.body, modified: false, @@ -213,9 +214,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(); @@ -225,7 +228,7 @@ define('composer', [ allowTopicsThumbnail: allowTopicsThumbnail, showTags: isTopic || isMain, isTopic: isTopic, - allowGuestHandles: config.allowGuestHandles + showHandleInput: (app.user.uid === 0 || (isEditing && isGuestPost && app.user.isAdmin)) && config.allowGuestHandles }; parseAndTranslate(template, data, function(composerTemplate) { diff --git a/src/socket.io/modules.js b/src/socket.io/modules.js index a922613ac3..7c74530e3e 100644 --- a/src/socket.io/modules.js +++ b/src/socket.io/modules.js @@ -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'], function(err, postData) { if(err || (!postData && !postData.content)) { return callback(err || new Error('[[error:invalid-pid]]')); } @@ -61,6 +61,7 @@ SocketModules.composer.push = function(socket, pid, callback) { callback(null, { pid: pid, + uid: postData.uid, body: postData.content, title: results.topic.title, topic_thumb: results.topic.thumb, diff --git a/src/topics/posts.js b/src/topics/posts.js index 6653c15934..c6e7829e5d 100644 --- a/src/topics/posts.js +++ b/src/topics/posts.js @@ -10,7 +10,8 @@ var async = require('async'), user = require('../user'), favourites = require('../favourites'), posts = require('../posts'), - privileges = require('../privileges'); + privileges = require('../privileges'), + meta = require('../meta'); module.exports = function(Topics) { @@ -130,7 +131,7 @@ module.exports = function(Topics) { } // Username override for guests, if enabled - if (parseInt(postObj.uid, 10) === 0 && postObj.handle) { + if (parseInt(meta.config.allowGuestHandles, 10) === 1 && parseInt(postObj.uid, 10) === 0 && postObj.handle) { postObj.user.username = postObj.handle; } } From 23b9b21cddcf8e1a03473662b0bf70335f9154e0 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Wed, 31 Dec 2014 21:27:41 -0500 Subject: [PATCH 7/7] better handling of guest handles in frontend, #2569 --- public/src/modules/composer.js | 4 +++- src/postTools.js | 1 + src/socket.io/modules.js | 3 ++- src/socket.io/posts.js | 2 ++ src/topics/create.js | 5 +++++ 5 files changed, 13 insertions(+), 2 deletions(-) diff --git a/public/src/modules/composer.js b/public/src/modules/composer.js index a07af172f1..5a80616517 100644 --- a/public/src/modules/composer.js +++ b/public/src/modules/composer.js @@ -155,6 +155,7 @@ define('composer', [ push({ pid: pid, uid: threadData.uid, + handle: threadData.handle, title: $('
    ').html(threadData.title).text(), body: threadData.body, modified: false, @@ -228,7 +229,8 @@ define('composer', [ allowTopicsThumbnail: allowTopicsThumbnail, showTags: isTopic || isMain, isTopic: isTopic, - showHandleInput: (app.user.uid === 0 || (isEditing && isGuestPost && app.user.isAdmin)) && config.allowGuestHandles + 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) { diff --git a/src/postTools.js b/src/postTools.js index c9e7648ea9..b157ead650 100644 --- a/src/postTools.js +++ b/src/postTools.js @@ -46,6 +46,7 @@ var winston = require('winston'), posts.setPostFields(data.pid, { edited: Date.now(), editor: data.uid, + handle: data.handle, content: postData.content }, next); }, diff --git a/src/socket.io/modules.js b/src/socket.io/modules.js index 7c74530e3e..71a44f36bd 100644 --- a/src/socket.io/modules.js +++ b/src/socket.io/modules.js @@ -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', 'uid'], 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]]')); } @@ -62,6 +62,7 @@ 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, diff --git a/src/socket.io/posts.js b/src/socket.io/posts.js index de66e6a5e3..97b8e7ea74 100644 --- a/src/socket.io/posts.js +++ b/src/socket.io/posts.js @@ -260,6 +260,7 @@ SocketPosts.edit = function(socket, data, callback) { // uid, pid, title, content, options postTools.edit({ uid: socket.uid, + handle: data.handle, pid: data.pid, title: data.title, content: data.content, @@ -274,6 +275,7 @@ SocketPosts.edit = function(socket, data, callback) { 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, diff --git a/src/topics/create.js b/src/topics/create.js index 25053ef819..9fd7354b17 100644 --- a/src/topics/create.js +++ b/src/topics/create.js @@ -260,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); }