inherit
257284
0
Nov 13, 2024 10:37:51 GMT -8
Eton Bones
70
December 2018
etonbones
|
Post by Eton Bones on Apr 5, 2020 9:10:02 GMT -8
I recently saw yet another thread where the owner was lamenting the loss of forum content due to erroneous deletions and wishing for a solution. I know there's a recycle bin plugin in the library but the two major complaints for that plugin is that it cannot backup post deletions only threads and that it is only available in the moderation menu. This plugin addresses the first issue by redirecting post deletions in addition to threads. The second obstacle is however left unaddressed since this plugin uses the move post/thread mechanism which means no normal members only staff with that ability get to use this feature. This is an (alpha) work-in-progress I started tinkering with on my day off yesterday but since I'll be working crazy and long hours during this virus lockdown I can't guarantee there will be any consistent progress on it so I am releasing it so anybody can improve upon it if they have downtime during this lockdown. If you have questions regarding the coding just post them here and I'll try to answer (or someone else might) whenever I find some time. With V6 around the corner the shelf life is unknown. The plugin currently works silently in the background redirecting all eligible deletions to move operations, only error conditions are made visible at the moment. www.dropbox.com/s/xa7nia9vyb8r07q/deletion%20backup.pbp?dl=0(function () { const settings = pb.plugin.get("eton_reprocess_post").settings; const route = pb.data("route"); const page = pb.data("page"); let post_ids=[];
$.ajaxPrefilter(function (options, originalOptions, jqXHR) { if ((options.url == "/posts/dialog/delete" && $('.options_menu').slice(0, 1).filter(function () { return !!$(this).find("." + $(this).idFromClass('post') + "-movePost").length }).length !== 0) || (options.url == "/threads/dialog/delete" && $('.actions .move_thread').length)) { //Redirect deletes so we move instead of delete posts and threads if (settings.move_board /*&& settings.move_thread*/) { //The designated deletion board in plugin settings should still allow permanent deletions without relocation if (void 0 === page.board || page.board && $.isNumeric(settings.move_board) && page.board.id !== parseInt(settings.move_board, 10)) { options.url = /posts/.test(options.url)? "/admin/move_posts_process":"/threads/move"; options.board_id = parseInt(settings.move_board, 10); options.thread_id = parseInt(settings.move_thread, 10); options.merging = options.thread_id ? "merge":"new"; options.merging === "new" && (options.subject="Moved Post" + (page.thread ? " From Thread #"+page.thread.id:"")) post_ids=[]; options.data = decodeURIComponent(options.data).replace(/ids\[\]\=([\d,]+)/g, function (m, p) { //lastDeleted = p; post_ids.push(p); return ""; }); post_ids.length && (options.data = (/threads/.test(options.url)?"thread_ids%5B%5D="+post_ids.join("&thread_ids%5B%5D="):"post_ids="+ encodeURIComponent(JSON.stringify(post_ids)))+ "&merging="+options.merging+"&board_id=" + options.board_id + ($.isNumeric(options.thread_id)? "&thread_id=" + options.thread_id:"") + (options.subject? "&subject="+options.subject.replace("Post","Post #"+post_ids.join(',#')+" "):"")+options.data); options.data = options.data.replace(/\&{2,}/g,"&"); jqXHR.success((xhresponse, xhrstatus, jqXHR) => { $('#confirm-container').dialog("close"); //second dialog with HTML response opens so close it too $(document).one('dialogopen', '#confirm-container', ()=>{$('#confirm-container').dialog("close");}) if(jqXHR.status == 200){ //Refresh post/thread list proboards.listManagers[pb.data("lm_id")].research(); //hide just in case there's a delay on the backend and item still appears in refresh //$("#post-"+post_ids.join(",#post-")).hide(); $('<style>'+"#"+(/thread_ids/.test(options.data)?"thread":"post")+"-"+post_ids.join(",#"+(/thread_ids/.test(options.data)?"thread":"post")+"-")+'{display:none!important;}</style>').appendTo('head'); }else{ pb.window.error('Something went wrong while moving content: status code '+jqXHR.status)} }); //return "json" }
} } }) })()
|
|
inherit
2671
0
May 14, 2013 14:40:03 GMT -8
Peter
🐺
10,615
February 2002
peter3
|
Post by Peter on Apr 6, 2020 1:20:24 GMT -8
What thoughts did you have to improve on it?
I tested it out, works as you described, so am not sure what could be added to improve it.
👍
|
|
inherit
257284
0
Nov 13, 2024 10:37:51 GMT -8
Eton Bones
70
December 2018
etonbones
|
Post by Eton Bones on Apr 6, 2020 22:52:13 GMT -8
- It does away with the two deletion dialogs but does nothing to inform the user that the post or thread was successfully moved instead of deleted. A visual cue prior to clicking that delete button would also suffice to let the user know how this operation is about to unfold (e.g. an icon on the action menu/post options menu letting you know this operation will be redirected as opposed to the normal delete operation).
- A way to override sending to backup and just outright delete (e.g holding SHIFT key)
|
|
inherit
2671
0
May 14, 2013 14:40:03 GMT -8
Peter
🐺
10,615
February 2002
peter3
|
Post by Peter on Apr 7, 2020 4:31:22 GMT -8
- Added "Success" dialog. - Added icon to action and post moderate menu. Note: Added function name to IIFE to prevent Cloudflare WAF blocking the save request. Deletion Backup 0.0.2Who's next in line to help improve it? Some ideas that might improve it further: - Override sending to backup (see post by Chris above). - Maybe cleaning up the dialog flash that happens before the new dialog appears. - Add link to thread / post in the success dialog. - Allow rewording of text in the plugin settings.
|
|
inherit
257284
0
Nov 13, 2024 10:37:51 GMT -8
Eton Bones
70
December 2018
etonbones
|
Post by Eton Bones on Apr 9, 2020 3:13:27 GMT -8
- Added "Success" dialog. - Added icon to action and post moderate menu. Note: Added function name to IIFE to prevent Cloudflare WAF blocking the save request. Deletion Backup 0.0.2Who's next in line to help improve it? Some ideas that might improve it further: - Override sending to backup (see post by Chris above). - Maybe cleaning up the dialog flash that happens before the new dialog appears. - Add link to thread / post in the success dialog. - Allow rewording of text in the plugin settings. Awesome mods as always Peter ; That cloudflare WAF has been bothering me for about a month but luckily I've been too busy to take it personal --heh UPDATES (v0.0.3): - Added shift key override - Added link to destination thread or board (depends on whether user opted to set a thread_id as well as a board_id[required]) - I also added an auto-close countdown for the dialog (to save the user a click and turn it into a true notification dialog) but wanted to hear some opinions on impact to accessibility and portability to mobile platforms. (function eton_deletion_backup() { // Added function name for IIFE to stop getting blocked by Cloudflare WAF const plugin = pb.plugin.get("eton_reprocess_post"); const settings = plugin.settings; const images = plugin.images; const route = pb.data("route"); const page = pb.data("page"); const route_name = route.name;
let post_ids = []; let shiftKey = null;
$.ajaxPrefilter(function (options, originalOptions, jqXHR) { if ((options.url == "/posts/dialog/delete" && $('.options_menu').slice(0, 1).filter(function () { return !!$(this).find("." + $(this).idFromClass('post') + "-movePost").length }).length !== 0) || (options.url == "/threads/dialog/delete" && $('.actions .move_thread').length)) { let item_type = (options.url.indexOf("/threads/") > -1) ? "Thread" : "Post";
// Redirect deletes so we move instead of delete posts and threads // Provided a destination board has been chosen in plugin setting and shift key override is not being employed if (settings.move_board && !shiftKey) {
// The designated deletion board in plugin settings should still allow permanent deletions without relocation
if (void 0 === page.board || page.board && $.isNumeric(settings.move_board) && page.board.id !== parseInt(settings.move_board, 10)) { options.url = item_type == "Post" ? "/admin/move_posts_process" : "/threads/move"; options.board_id = parseInt(settings.move_board, 10); options.thread_id = parseInt(settings.move_thread, 10); options.merging = options.thread_id ? "merge" : "new"; options.merging === "new" && (options.subject = "Moved Post" + (page.thread ? " From Thread #" + page.thread.id : "")) post_ids = []; options.data = decodeURIComponent(options.data).replace(/ids\[\]\=([\d,]+)/g, function (m, p) { post_ids.push(p); return ""; }); post_ids.length && (options.data = (item_type === "Thread" ? "thread_ids%5B%5D=" + post_ids.join("&thread_ids%5B%5D=") : "post_ids=" + encodeURIComponent(JSON.stringify(post_ids))) + "&merging=" + options.merging + "&board_id=" + options.board_id + ($.isNumeric(options.thread_id) ? "&thread_id=" + options.thread_id : "") + (options.subject ? "&subject=" + options.subject.replace("Post", "Post #" + post_ids.join(',#') + " ") : "") + options.data); options.data = options.data.replace(/\&{2,}/g, "&");
jqXHR.success((xhresponse, xhrstatus, jqXHR) => { let act_type = item_type;
act_type += (post_ids.length == 1) ? "" : "s";
// Show "deleted" dialog
$("<div id='success_move'>Successfully moved " + act_type.toLowerCase() + " to the <a target='_blank' " + (options.thread_id ? "href='/post/" + post_ids[0] + "/thread'>backup thread</a>" : "href='/board/" + options.board_id + "'>backup board</a>") + "</div>").dialog({
title: "Success", resizeable: false, draggable: false, modal: true, width: 400, height: 150,
// Don't really need a button, but will be consistent
buttons: {
"Close": function () { clearTimeout($(this).data('timeout')) $(this).dialog("close").remove(); // Remove it just to clean up the DOM }
}
}) .each(function (i, e) { function auto_close_dialog($notification_dialog, milliseconds = 10000, buttonIndex = -1, step = 500) { let $button = $notification_dialog.closest('.ui-dialog') .on('mouseenter', () => { clearInterval($notification_dialog.data('interval')); buttonCounter.text(""); }) .on('mouseleave', () => { $notification_dialog.data('interval', setInterval(countdown, step)); }) .find('.ui-dialog-buttonset .ui-button-text-only').eq(buttonIndex) let buttonCounter = $('<span />', { class: 'pad-right-double' }).prependTo($button); let counter = milliseconds;
$notification_dialog.data('interval', setInterval(countdown, step));
function pad(c, d = 2) { return ((new Array(d)).join("0") + (!!Number(c) ? c : 0)).slice(-1 * d) }
function countdown() { counter -= step; if (counter <= 0) { buttonCounter.text("") clearInterval($notification_dialog.data('interval')); setTimeout(() => { $notification_dialog.dialog('close'); }, 500) } else { buttonCounter.text(pad(counter / 1000 / 60 >> 0) + ":" + pad(counter / 1000 >> 0)); } } } auto_close_dialog($(e)) })
// Close original deletion dialog $('#confirm-container').dialog("close");
// Second dialog with HTML response opens so close that as well
$(document).one('dialogopen', '#confirm-container', () => { $('#confirm-container').dialog("close"); }) if (jqXHR.status == 200) {
// Refresh post/thread list
proboards.listManagers[pb.data("lm_id")].research();
// Hide just in case there's a delay on the backend and item still appear after refresh
$('<style>' + "#" + (/thread_ids/.test(options.data) ? "thread" : "post") + "-" + post_ids.join(",#" + (/thread_ids/.test(options.data) ? "thread" : "post") + "-") + '{display:none!important;}</style>').appendTo('head');
} else {
pb.window.error('Something went wrong while moving content: status code ' + jqXHR.status);
} }); //return "json" }
} } })
// Add icon to the actions menu
$(() => {
let $img_recycle = $("<img />").attr("src", images.move).addClass("action-recycle-img");
if (pb.data('proboards.thread')) { $(".delete_thread").on('click', (_event) => { shiftKey = _event.shiftKey; }).find(">a .icon").prepend($img_recycle) }
function add_to_moderate_menu() { let pb_posts if ((pb_posts = pb.data('proboards.post'))) { // let $options_menu = $(".options_menu");
for (let id in pb_posts) { if (pb_posts.hasOwnProperty(id)) { $("." + parseInt(id, 10) + "-deletePost").on('click', (_event) => { shiftKey = _event.shiftKey; }).find(">a .icon").prepend($img_recycle.clone()); } }
} }
add_to_moderate_menu(); proboards.on("afterSearch", add_to_moderate_menu);
});
})();
Improvements?: - dialog flash seems unavoidable especially now that shift key can override delete interceptions and thus allow the normal process to flow. By the time the ajax request is intercepted and a decision to let flow or redirect is made the dialog has already been on the screen awaiting user confirmation to continue the deletion process. Hiding all deletion dialogs from the get-go then showing if allowing to continue might be the answer but it seems prone to mistaken identities. On the plus side, this could be viewed as a visceral cue that a redirect occurred, one could subconsciously register what just happened while multitasking and not have to stop to read/click on a dialog. If someone else gets an idea for this then go for it. - Allow rewording of text in the plugin settings
|
|
inherit
262250
0
May 21, 2022 13:36:20 GMT -8
intender
The only way to fix it is to flush it all away
12
September 2020
intender
|
Post by intender on Sept 27, 2020 15:06:32 GMT -8
So I was directed to this by another user and if I am reading this correct this just redirects a deletion to another board that we pick? If so this is awesome. I am interested in adding this to a forum I run. Do you think it would break something if one of my moderators were to accidentally delete a 2000+ post thread
Edit:
Just wanted to throw out this bit of info after adding it to my forum. Using the "Delete All Posts" function to delete posts by guest accounts they are not being caught by the plugin. The posts were permanently deleted and did no go to the board I setup to catch deleted posts. Not sure if this is related to the fact that I used Delete All Posts or if it was because it was a Guest account.
Second thing I noticed is that after deleting the post I get the popup box over the "successful" notification box saying
Error The thread you are trying to access could not be found.
I see this from time to time on proboards when deleting posts, but this has shown up on the handful of posts that I ran a test on in my test forum before adding it to my forum and the 3 posts I have had to delete from my forum since adding.
|
|
inherit
257284
0
Nov 13, 2024 10:37:51 GMT -8
Eton Bones
70
December 2018
etonbones
|
Post by Eton Bones on Sept 29, 2020 4:09:28 GMT -8
So I was directed to this by another user and if I am reading this correct this just redirects a deletion to another board that we pick? If so this is awesome. I am interested in adding this to a forum I run. Do you think it would break something if one of my moderators were to accidentally delete a 2000+ post thread Edit:
Just wanted to throw out this bit of info after adding it to my forum. Using the "Delete All Posts" function to delete posts by guest accounts they are not being caught by the plugin. The posts were permanently deleted and did no go to the board I setup to catch deleted posts. Not sure if this is related to the fact that I used Delete All Posts or if it was because it was a Guest account.
Second thing I noticed is that after deleting the post I get the popup box over the "successful" notification box saying
Error The thread you are trying to access could not be found.
I see this from time to time on proboards when deleting posts, but this has shown up on the handful of posts that I ran a test on in my test forum before adding it to my forum and the 3 posts I have had to delete from my forum since adding.
Hi intender , I'm not familiar with this "Delete All Post" function, is it a forum cleanup thing you're referring to? FYI: forum admin panel is a no code zone, plugins, template modifications, etc. are disabled in there, this way if you have an unruly code you can easily disable it without it preventing you from entering your admin panel. This also means a plugin cannot intercept any actions taken in the admin panel only actions taken on the forum itself are in play here. Just to clarify, the "thread not found" error is it a popup or is it one of those standard "Oops" platform errors ( "The thread you are looking for could not be found") I'll venture a guess that this is from deleting an entire thread via the actions menu while viewing the thread and I can see where refreshing the list would generate an error (the plugin refreshes through Ajax to update the view, Proboards in that situation would drop you at the parent board thread list instead) and that would conceivably be a quick fix by checking if we're in a single thread context or multiple (viewing thread list in a board and deleting multiple via the checkboxes and action menu) while deleting a thread. Not the issue since that scenario brings us back to the moved thread but with an updated breadcrumb upon listmanager refresh. This might very well be a case of mistaken correlation versus causation due to the mention of it happening prior to installation of the plugin. In any event I and others who have tested the plugin are unable to replicate this error thus calling into question the specifics of your particular setup which is an unknown at the moment (forum url [to see who else is on the playground], browser make, model and version, browsing practices (multitab evangelist/monogamous surfer), republican/democrat/other, great taste/less filling, etc.)I will investigate this when I get some free time since I neglected to test deleting the thread itself in that single thread context just tested deleting posts, so possibly never saw that error. Thanks for the feedback, if my guess is way off then please elaborate so we can get to the bottom of it.
|
|
inherit
262250
0
May 21, 2022 13:36:20 GMT -8
intender
The only way to fix it is to flush it all away
12
September 2020
intender
|
Post by intender on Oct 6, 2020 22:07:47 GMT -8
Just wanted to touch base back with you after a good bit of use and let you know about my experience so far. 1. The Delete all function is only available when deleting non member "guest" posts. You can see it in the image above. So if a guest jumps in and spams 20 links to (and this is literally something I have seen this weeK) buy a Vietnamese bride, I can click select all and then it will prompt to make sure you want to delete and you have to type the word delete. I actually appreciate the fact that your software plugin doesn't effect the way this works. It would just cause more work having to go back through and delete them all again after they are posted. As is if I use that choice they are gone forever with a few clicks and a word.
2. The error in question about the thread not being found is something I often see just when regularly deleting a post, particularly if it was the only post in the thread. Its like the forum software occasionally pops up this message and I think its because its trying to redirect you back to the same post your were in but its not there anymore. Most likely a pro boards issue.
3. Seems to be working perfrectly fine so far for me. Used it to delete a lot of spam and everything that was deleted 1 post at a time or 1 thread at a time moved to the board I have all of them set to go to. Very useful tool. Glad to have it available. Look forward to your future work.
|
|