diff --git a/package.json b/package.json index 68da7bd634..9c491af2a0 100644 --- a/package.json +++ b/package.json @@ -56,8 +56,8 @@ "nodebb-plugin-spam-be-gone": "0.4.6", "nodebb-rewards-essentials": "0.0.8", "nodebb-theme-lavender": "3.0.9", - "nodebb-theme-persona": "4.0.118", - "nodebb-theme-vanilla": "5.0.63", + "nodebb-theme-persona": "4.0.119", + "nodebb-theme-vanilla": "5.0.64", "nodebb-widget-essentials": "2.0.9", "nodemailer": "2.0.0", "nodemailer-sendmail-transport": "1.0.0", diff --git a/public/language/en_GB/user.json b/public/language/en_GB/user.json index a6ae357177..cb0f3d27e0 100644 --- a/public/language/en_GB/user.json +++ b/public/language/en_GB/user.json @@ -112,7 +112,7 @@ "follow_topics_you_reply_to": "Follow topics that you reply to", "follow_topics_you_create": "Follow topics you create", - "grouptitle": "Select the group title you would like to display", + "grouptitle": "Group Title", "no-group-title": "No group title", "select-skin": "Select a Skin", diff --git a/public/src/client/account/edit.js b/public/src/client/account/edit.js index de5b01e809..385d5e0ed1 100644 --- a/public/src/client/account/edit.js +++ b/public/src/client/account/edit.js @@ -36,6 +36,7 @@ define('forum/account/edit', ['forum/account/header', 'uploader', 'translator'], website: $('#inputWebsite').val(), birthday: $('#inputBirthday').val(), location: $('#inputLocation').val(), + groupTitle: $('#groupTitle').val(), signature: $('#inputSignature').val(), aboutme: $('#inputAboutMe').val() }; diff --git a/src/controllers/accounts/edit.js b/src/controllers/accounts/edit.js index 2ae429b248..9f63df0894 100644 --- a/src/controllers/accounts/edit.js +++ b/src/controllers/accounts/edit.js @@ -10,6 +10,7 @@ var user = require('../../user'); var meta = require('../../meta'); var plugins = require('../../plugins'); var helpers = require('../helpers'); +var groups = require('../../groups'); var accountHelpers = require('./helpers'); var editController = {}; @@ -25,7 +26,13 @@ editController.get = function(req, res, callback) { userData.maximumProfileImageSize = parseInt(meta.config.maximumProfileImageSize, 10); userData.allowProfileImageUploads = parseInt(meta.config.allowProfileImageUploads) === 1; userData.allowAccountDelete = parseInt(meta.config.allowAccountDelete, 10) === 1; - + + userData.groups = userData.groups.filter(function(group) { + return group && group.userTitleEnabled && !groups.isPrivilegeGroup(group.name) && group.name !== 'registered-users'; + }); + userData.groups.forEach(function(group) { + group.selected = group.name === userData.groupTitle; + }); userData.title = '[[pages:account/edit, ' + userData.username + ']]'; userData.breadcrumbs = helpers.buildBreadcrumbs([{text: userData.username, url: '/user/' + userData.userslug}, {text: '[[user:edit]]'}]); @@ -33,7 +40,7 @@ editController.get = function(req, res, callback) { plugins.fireHook('filter:user.account.edit', userData, function(err, userData) { if (err) { - return next(err); + return callback(err); } res.render('account/edit', userData); @@ -121,7 +128,7 @@ editController.uploadPicture = function (req, res, next) { if (!isAllowed) { return helpers.notAllowed(req, res); } - + user.uploadPicture(updateUid, userPhoto, next); } ], function(err, image) { diff --git a/src/controllers/accounts/helpers.js b/src/controllers/accounts/helpers.js index 8acbdc08c8..2502d7fdd0 100644 --- a/src/controllers/accounts/helpers.js +++ b/src/controllers/accounts/helpers.js @@ -133,7 +133,7 @@ helpers.getBaseUser = function(userslug, callerUID, callback) { async.parallel({ user: function(next) { - user.getUserFields(uid, ['uid', 'username', 'userslug', 'picture', 'cover:url', 'cover:position', 'status', 'lastonline'], next); + user.getUserFields(uid, ['uid', 'username', 'userslug', 'picture', 'cover:url', 'cover:position', 'status', 'lastonline', 'groupTitle'], next); }, isAdmin: function(next) { user.isAdministrator(callerUID, next); diff --git a/src/groups/membership.js b/src/groups/membership.js index 747fa9d3d7..96962695a1 100644 --- a/src/groups/membership.js +++ b/src/groups/membership.js @@ -1,16 +1,17 @@ 'use strict'; -var async = require('async'), - winston = require('winston'), - _ = require('underscore'), +var async = require('async'); +var winston = require('winston'); +var _ = require('underscore'); - user = require('../user'), - utils = require('../../public/src/utils'), - plugins = require('../plugins'), - notifications = require('../notifications'), - db = require('./../database'); +var user = require('../user'); +var utils = require('../../public/src/utils'); +var plugins = require('../plugins'); +var notifications = require('../notifications'); +var db = require('./../database'); module.exports = function(Groups) { + Groups.join = function(groupName, uid, callback) { function join() { var tasks = [ @@ -39,7 +40,7 @@ module.exports = function(Groups) { async.parallel(tasks, next); }, function(results, next) { - user.setGroupTitle(groupName, uid, next); + setGroupTitleIfNotSet(groupName, uid, next); }, function(next) { plugins.fireHook('action:group.join', { @@ -80,6 +81,20 @@ module.exports = function(Groups) { }); }; + function setGroupTitleIfNotSet(groupName, uid, callback) { + if (groupName === 'registered-users') { + return callback(); + } + + db.getObjectField('user:' + uid, 'groupTitle', function(err, currentTitle) { + if (err || (currentTitle || currentTitle === '')) { + return callback(err); + } + + user.setUserField(uid, 'groupTitle', groupName, callback); + }); + } + Groups.requestMembership = function(groupName, uid, callback) { async.waterfall([ async.apply(inviteOrRequestMembership, groupName, uid, 'request'), @@ -414,7 +429,7 @@ module.exports = function(Groups) { } db.getSetMembers('group:' + groupName + ':pending', callback); }; - + Groups.kick = function(uid, groupName, isOwner, callback) { if (isOwner) { // If the owners set only contains one member, error out! diff --git a/src/posts/user.js b/src/posts/user.js index cd675cbfa3..275264f808 100644 --- a/src/posts/user.js +++ b/src/posts/user.js @@ -1,66 +1,49 @@ 'use strict'; -var async = require('async'), - validator = require('validator'), - - db = require('../database'), - user = require('../user'), - groups = require('../groups'), - meta = require('../meta'), - plugins = require('../plugins'); +var async = require('async'); +var validator = require('validator'); +var user = require('../user'); +var groups = require('../groups'); +var meta = require('../meta'); +var plugins = require('../plugins'); module.exports = function(Posts) { Posts.getUserInfoForPosts = function(uids, uid, callback) { var groupsMap = {}; - var userSettings; - async.parallel({ - groupTitles: function(next) { - var keys = uids.map(function(uid) { - return 'user:' + uid + ':settings'; - }); - async.waterfall([ - function (next) { - db.getObjectsFields(keys, ['groupTitle'], next); - }, - function (_userSettings, next) { - userSettings = _userSettings; - var groupKeys = userSettings.filter(function(userSetting) { - return userSetting && userSetting.groupTitle; - }).map(function(userSetting) { - return userSetting.groupTitle; - }).filter(function(groupTitle, index, array) { - return groupTitle && array.indexOf(groupTitle) === index; - }); - groups.getGroupsData(groupKeys, next); - }, - function (groupsData, next) { - groupsData.forEach(function(group) { - if (group && group.userTitleEnabled) { - groupsMap[group.name] = { - name: group.name, - slug: group.slug, - labelColor: group.labelColor, - icon: group.icon, - userTitle: group.userTitle - }; - } - }); - next(null, userSettings); - } - ], next); + var userData; + async.waterfall([ + function(next) { + user.getUsersFields(uids, ['uid', 'username', 'fullname', 'userslug', 'reputation', 'postcount', 'picture', 'signature', 'banned', 'status', 'lastonline', 'groupTitle'], next); }, - userData: function(next) { - user.getUsersFields(uids, ['uid', 'username', 'fullname', 'userslug', 'reputation', 'postcount', 'picture', 'signature', 'banned', 'status', 'lastonline'], next); + function(_userData, next) { + userData = _userData; + var groupTitles = userData.map(function(userData) { + return userData && userData.groupTitle; + }).filter(function(groupTitle, index, array) { + return groupTitle && array.indexOf(groupTitle) === index; + }); + groups.getGroupsData(groupTitles, next); } - }, function(err, results) { + ], function(err, groupsData) { if (err) { return callback(err); } - var userData = results.userData; - userData.forEach(function(userData, i) { + groupsData.forEach(function(group) { + if (group && group.userTitleEnabled) { + groupsMap[group.name] = { + name: group.name, + slug: group.slug, + labelColor: group.labelColor, + icon: group.icon, + userTitle: group.userTitle + }; + } + }); + + userData.forEach(function(userData) { userData.uid = userData.uid || 0; userData.username = userData.username || '[[global:guest]]'; userData.userslug = userData.userslug || ''; @@ -69,7 +52,6 @@ module.exports = function(Posts) { userData.banned = parseInt(userData.banned, 10) === 1; userData.picture = userData.picture || ''; userData.status = user.getStatus(userData); - userData.groupTitle = results.groupTitles[i].groupTitle; userData.signature = validator.escape(userData.signature || ''); userData.fullname = validator.escape(userData.fullname || ''); }); @@ -77,7 +59,7 @@ module.exports = function(Posts) { async.map(userData, function(userData, next) { async.parallel({ isMemberOfGroup: function (next) { - if (!userData.groupTitle) { + if (!userData.groupTitle || !groupsMap[userData.groupTitle]) { return next(); } groups.isMember(userData.uid, userData.groupTitle, next); diff --git a/src/upgrade.js b/src/upgrade.js index f6f1ce0093..68f830ef3c 100644 --- a/src/upgrade.js +++ b/src/upgrade.js @@ -10,7 +10,7 @@ var db = require('./database'), schemaDate, thisSchemaDate, // IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema - latestSchema = Date.UTC(2016, 1, 25); + latestSchema = Date.UTC(2016, 3, 14); Upgrade.check = function(callback) { db.get('schemaDate', function(err, value) { @@ -438,6 +438,44 @@ Upgrade.upgrade = function(callback) { winston.info('[2016/02/25] Social: Post Sharing skipped!'); next(); } + }, + function(next) { + thisSchemaDate = Date.UTC(2016, 3, 14); + + if (schemaDate < thisSchemaDate) { + updatesMade = true; + winston.info('[2016/04/14] Group title from settings to user profile'); + + var user = require('./user'); + var batch = require('./batch'); + var count = 0; + batch.processSortedSet('users:joindate', function(uids, next) { + winston.info('upgraded ' + count + ' users'); + user.getMultipleUserSettings(uids, function(err, settings) { + if (err) { + return next(err); + } + count += uids.length; + settings = settings.filter(function(setting) { + return setting && setting.groupTitle; + }); + + async.each(settings, function(setting, next) { + db.setObjectField('user:' + setting.uid, 'groupTitle', setting.groupTitle, next); + }, next); + }); + }, {}, function(err) { + if (err) { + return next(err); + } + + winston.info('[2016/04/14] Group title from settings to user profile done'); + Upgrade.update(thisSchemaDate, next); + }); + } else { + winston.info('[2016/04/14] Group title from settings to user profile skipped!'); + next(); + } } // Add new schema updates here // IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema IN LINE 24!!! diff --git a/src/user/profile.js b/src/user/profile.js index 50aa92c1d0..e24d5f08d0 100644 --- a/src/user/profile.js +++ b/src/user/profile.js @@ -12,7 +12,7 @@ var plugins = require('../plugins'); module.exports = function(User) { User.updateProfile = function(uid, data, callback) { - var fields = ['username', 'email', 'fullname', 'website', 'location', 'birthday', 'signature', 'aboutme']; + var fields = ['username', 'email', 'fullname', 'website', 'location', 'groupTitle', 'birthday', 'signature', 'aboutme']; plugins.fireHook('filter:user.updateProfile', {uid: uid, data: data, fields: fields}, function(err, data) { if (err) { diff --git a/src/user/settings.js b/src/user/settings.js index e37e012f7e..8cd38d3a01 100644 --- a/src/user/settings.js +++ b/src/user/settings.js @@ -1,10 +1,10 @@ 'use strict'; -var async = require('async'), - meta = require('../meta'), - db = require('../database'), - plugins = require('../plugins'); +var async = require('async'); +var meta = require('../meta'); +var db = require('../database'); +var plugins = require('../plugins'); module.exports = function(User) { @@ -162,17 +162,4 @@ module.exports = function(User) { User.setSetting = function(uid, key, value, callback) { db.setObjectField('user:' + uid + ':settings', key, value, callback); }; - - User.setGroupTitle = function(groupName, uid, callback) { - if (groupName === 'registered-users') { - return callback(); - } - db.getObjectField('user:' + uid + ':settings', 'groupTitle', function(err, currentTitle) { - if (err || (currentTitle || currentTitle === '')) { - return callback(err); - } - - User.setSetting(uid, 'groupTitle', groupName, callback); - }); - }; };