diff --git a/public/language/en_GB/error.json b/public/language/en_GB/error.json index 25e3afa69f..288ac0f4f2 100644 --- a/public/language/en_GB/error.json +++ b/public/language/en_GB/error.json @@ -57,6 +57,13 @@ "post-edit-duration-expired-days": "You are only allowed to edit posts for %1 day(s) after posting", "post-edit-duration-expired-days-hours": "You are only allowed to edit posts for %1 day(s) %2 hour(s) after posting", + "post-delete-duration-expired": "You are only allowed to delete posts for %1 second(s) after posting", + "post-delete-duration-expired-minutes": "You are only allowed to delete posts for %1 minute(s) after posting", + "post-delete-duration-expired-minutes-seconds": "You are only allowed to delete posts for %1 minute(s) %2 second(s) after posting", + "post-delete-duration-expired-hours": "You are only allowed to delete posts for %1 hour(s) after posting", + "post-delete-duration-expired-hours-minutes": "You are only allowed to delete posts for %1 hour(s) %2 minute(s) after posting", + "post-delete-duration-expired-days": "You are only allowed to delete posts for %1 day(s) after posting", + "post-delete-duration-expired-days-hours": "You are only allowed to delete posts for %1 day(s) %2 hour(s) after posting", "content-too-short": "Please enter a longer post. Posts should contain at least %1 character(s).", "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 character(s).", diff --git a/public/src/client/topic/postTools.js b/public/src/client/topic/postTools.js index 7136c32c27..c954dd2402 100644 --- a/public/src/client/topic/postTools.js +++ b/public/src/client/topic/postTools.js @@ -171,42 +171,54 @@ define('forum/topic/postTools', ['share', 'navigator', 'components', 'translator var timestamp = parseInt(getData(btn, 'data-timestamp'), 10); var postEditDuration = parseInt(ajaxify.data.postEditDuration, 10); - if (!ajaxify.data.privileges.isAdminOrMod && postEditDuration && Date.now() - timestamp > postEditDuration * 1000) { - var numDays = Math.floor(postEditDuration / 86400); - var numHours = Math.floor((postEditDuration % 86400) / 3600); - var numMinutes = Math.floor(((postEditDuration % 86400) % 3600) / 60); - var numSeconds = ((postEditDuration % 86400) % 3600) % 60; - var msg = '[[error:post-edit-duration-expired, ' + postEditDuration + ']]'; + + if (checkDuration(postEditDuration, timestamp, 'post-edit-duration-expired')) { + $(window).trigger('action:composer.post.edit', { + pid: getData(btn, 'data-pid') + }); + } + }); + + postContainer.on('click', '[component="post/delete"]', function() { + var btn = $(this); + var timestamp = parseInt(getData(btn, 'data-timestamp'), 10); + var postDeleteDuration = parseInt(ajaxify.data.postDeleteDuration, 10); + if (checkDuration(postDeleteDuration, timestamp, 'post-delete-duration-expired')) { + togglePostDelete($(this), tid); + } + }); + + function checkDuration(duration, postTimestamp, languageKey) { + if (!ajaxify.data.privileges.isAdminOrMod && duration && Date.now() - postTimestamp > duration * 1000) { + var numDays = Math.floor(duration / 86400); + var numHours = Math.floor((duration % 86400) / 3600); + var numMinutes = Math.floor(((duration % 86400) % 3600) / 60); + var numSeconds = ((duration % 86400) % 3600) % 60; + var msg = '[[error:' + languageKey + ', ' + duration + ']]'; if (numDays) { if (numHours) { - msg = '[[error:post-edit-duration-expired-days-hours, ' + numDays + ', ' + numHours + ']]'; + msg = '[[error:' + languageKey + '-days-hours, ' + numDays + ', ' + numHours + ']]'; } else { - msg = '[[error:post-edit-duration-expired-days, ' + numDays + ']]'; + msg = '[[error:' + languageKey + '-days, ' + numDays + ']]'; } } else if (numHours) { if (numMinutes) { - msg = '[[error:post-edit-duration-expired-hours-minutes, ' + numHours + ', ' + numMinutes + ']]'; + msg = '[[error:' + languageKey + '-hours-minutes, ' + numHours + ', ' + numMinutes + ']]'; } else { - msg = '[[error:post-edit-duration-expired-hours, ' + numHours + ']]'; + msg = '[[error:' + languageKey + '-hours, ' + numHours + ']]'; } } else if (numMinutes) { if (numSeconds) { - msg = '[[error:post-edit-duration-expired-minutes-seconds, ' + numMinutes + ', ' + numSeconds + ']]'; + msg = '[[error:' + languageKey + '-minutes-seconds, ' + numMinutes + ', ' + numSeconds + ']]'; } else { - msg = '[[error:post-edit-duration-expired-minutes, ' + numMinutes + ']]'; + msg = '[[error:' + languageKey + '-minutes, ' + numMinutes + ']]'; } } - return app.alertError(msg); + app.alertError(msg); + return false; } - - $(window).trigger('action:composer.post.edit', { - pid: getData(btn, 'data-pid') - }); - }); - - postContainer.on('click', '[component="post/delete"]', function() { - togglePostDelete($(this), tid); - }); + return true; + } postContainer.on('click', '[component="post/restore"]', function() { togglePostDelete($(this), tid); @@ -394,9 +406,9 @@ define('forum/topic/postTools', ['share', 'navigator', 'components', 'translator } function togglePostDelete(button, tid) { - var pid = getData(button, 'data-pid'), - postEl = components.get('post', 'pid', pid), - action = !postEl.hasClass('deleted') ? 'delete' : 'restore'; + var pid = getData(button, 'data-pid'); + var postEl = components.get('post', 'pid', pid); + var action = !postEl.hasClass('deleted') ? 'delete' : 'restore'; postAction(action, pid, tid); } diff --git a/src/controllers/topics.js b/src/controllers/topics.js index f36c1d5ed0..1e41cfe981 100644 --- a/src/controllers/topics.js +++ b/src/controllers/topics.js @@ -264,7 +264,8 @@ topicsController.get = function(req, res, callback) { data['downvote:disabled'] = parseInt(meta.config['downvote:disabled'], 10) === 1; data['feeds:disableRSS'] = parseInt(meta.config['feeds:disableRSS'], 10) === 1; data.bookmarkThreshold = parseInt(meta.config.bookmarkThreshold, 10) || 5; - data.postEditDuration = parseInt(meta.config.postEditDuration, 10); + data.postEditDuration = parseInt(meta.config.postEditDuration, 10) || 0; + data.postDeleteDuration = parseInt(meta.config.postDeleteDuration, 10) || 0; data.scrollToMyPost = settings.scrollToMyPost; data.rssFeedUrl = nconf.get('relative_path') + '/topic/' + data.tid + '.rss'; data.pagination = pagination.create(currentPage, pageCount); diff --git a/src/posts/tools.js b/src/posts/tools.js index 64ddf155d7..40d150d049 100644 --- a/src/posts/tools.js +++ b/src/posts/tools.js @@ -34,10 +34,10 @@ module.exports = function(Posts) { return next(new Error('[[error:post-already-restored]]')); } - privileges.posts.canEdit(pid, uid, next); + privileges.posts.canDelete(pid, uid, next); }, - function (canEdit, next) { - if (!canEdit) { + function (canDelete, next) { + if (!canDelete) { return next(new Error('[[error:no-privileges]]')); } diff --git a/src/privileges/posts.js b/src/privileges/posts.js index 6270b6e99e..17fcb1fc74 100644 --- a/src/privileges/posts.js +++ b/src/privileges/posts.js @@ -150,6 +150,38 @@ module.exports = function(privileges) { }); }; + privileges.posts.canDelete = function(pid, uid, callback) { + var postData; + async.waterfall([ + function(next) { + posts.getPostFields(pid, ['tid', 'timestamp'], next); + }, + function(_postData, next) { + postData = _postData; + async.parallel({ + isAdminOrMod: async.apply(isAdminOrMod, pid, uid), + isLocked: async.apply(topics.isLocked, postData.tid), + isOwner: async.apply(posts.isOwner, pid, uid) + }, next); + } + ], function(err, results) { + if (err) { + return callback(err); + } + if (results.isAdminOrMod) { + return callback(null, true); + } + if (results.isLocked) { + return callback(new Error('[[error:topic-locked]]')); + } + var postDeleteDuration = parseInt(meta.config.postDeleteDuration, 10); + if (postDeleteDuration && (Date.now() - parseInt(postData.timestamp, 10) > postDeleteDuration * 1000)) { + return callback(new Error('[[error:post-delete-duration-expired, ' + meta.config.postDeleteDuration + ']]')); + } + callback(null, results.isOwner); + }); + }; + privileges.posts.canMove = function(pid, uid, callback) { posts.isMain(pid, function(err, isMain) { if (err || isMain) { diff --git a/src/views/admin/settings/post.tpl b/src/views/admin/settings/post.tpl index 0855a34333..4ac9aa3d2a 100644 --- a/src/views/admin/settings/post.tpl +++ b/src/views/admin/settings/post.tpl @@ -48,6 +48,10 @@ +
+ + +