// multiorphan Admin Plugin Script (function($){ var canBeStopped = false, $orphanForm = null, $currentPagesAndMedia, $currentResults; var ORPHANACTIONS = { view : function(type) { return { label: 'View', actionId: 'view', click: function() { var $link = $(this); if (type === 'Page' || type === 'URL') { return true; } request({'do':'view'+type, 'link':decodeURIComponent($link.attr('elementid'))}, function(response){ if ( response.dialogContent ) { $('
').attr('id', 'multiorphan__preview_dialog').appendTo('body').dialog({ title:'Preview', height: Math.min(700,$(window).height()-50), width: Math.min(700,$(window).width()-50), autoOpen:true, closeOnEscape:true, modal:true, close: function() { $(this).dialog('close').remove(); } }).html(response.dialogContent); } }); return false; } } }, delete : function(type) { return { label: 'Delete', click: function() { var $link = $(this); request({'do':'delete'+type , 'link':decodeURIComponent($link.attr('elementid'))}, function(response){ $link.parents('.entry[elementid="'+$link.attr('elementid')+'"]').addClass('deleted disabled'); $link.parent('.actions').remove(); }); return false; } } }, clear: function() { return { label: 'Clear', click: function() { var $link = $(this); $link.parents('.entry[elementid="'+$link.attr('elementid')+'"]').remove(); return false; } } } }; var init = function() { $orphanForm = $('form#multiorphan').submit(loadpages); $orphanForm.find( ".multiorphan__result_group" ).accordion({ collapsible: true, active: false, heightStyle: "content" }); reset(); }; /** * Load all pages and media * Cycle the result. */ var loadpages = function(event) { if ( canBeStopped ) { canBeStopped = false; $currentPagesAndMedia.stop = true; $orphanForm.find('button[type=submit]').text(getLang('start')); errorLog(getLang('request-aborted')); return false; } reset(true); canBeStopped = true; event.stopPropagation(); $orphanForm.find('button[type=submit]').text(getLang('stop')); request({'do':'loadpages'}, function( $result ){ // Start cycling pages $currentPagesAndMedia = $result; $currentPagesAndMedia.interval = 1;//Math.floor($currentPagesAndMedia.pages.length / 10); checkpagesandmedia($.makeArray($result.pages)); }); return false; }; /** * Time Check while running */ var prevTime = 0; var getTimeDifference = function(){ var newTime = Date.now(); var time = (newTime - (prevTime||newTime)) / 1000; prevTime = newTime; return time + "s"; }; /** * Walk the current elements Tree */ var checkpagesandmedia = function(elements) { var throttleValue = 0; // Cycle pages. Media is implicite. var validateElement = function(result) { // Check if we still have elements in the elements list (cycle-list) and in the resultList (could be stopped.) if ( elements && elements.length && !($currentPagesAndMedia && $currentPagesAndMedia.stop) ) { var element = elements.pop(); status(getLang('checking-page') + " ("+($currentPagesAndMedia.pages.length-elements.length)+"/"+($currentPagesAndMedia.pages.length)+" " + getTimeDifference() + ")" + (throttleValue > 0 ? ' ' + getLang('throttled') + '' : '') + ":
" + element); window.setTimeout(function() { request({'do':'checkpage','id':element}, function(response) { checkResponseForWantedAndLinked(response, element); // Every 10 pages //if ( elements && elements.length && elements.length % $currentPagesAndMedia.interval == 0 ) { findOrphans(); //} }).always(validateElement); }, Math.max(0, throttleValue) * 1000 ); } else { // All done. Check for Orphans. findOrphans(true); // Now we can leave. status(getLang('checking-done')); reset(); } }; validateElement(); throttleValue = parseInt( $orphanForm.find('input[name=throttle]').val() ); }; var buildUrl = function (id) { var cleanedID = decodeURIComponent(id); var schemeSepPos = cleanedID.indexOf('://'); if (schemeSepPos > -1) { var scheme = cleanedID.substr(0, schemeSepPos); if (JSINFO.schemes.indexOf(scheme) > -1) { // we have an external url return cleanedID; } } return DOKU_BASE + 'doku.php?id=' + id; }; var guiElementActions = function(actions, id, url, $insertPoint) { // Add actions var $buttonSet = $('
').addClass('actions').appendTo($insertPoint); $.each(actions||[], function(idx, action) { const attrs = { href: url || buildUrl(id), elementid: id }; if (action.actionId === 'view') { attrs.target = '_blank'; } var $link = $('').attr(attrs).text(action.label).appendTo($buttonSet).click(action.click); if ( action.process ) { action.process($link); } }) }; /** * Add an entry to the accordion of the according type. */ var addGUIEntry = function($insertPoint, name, url, requestPage, requestPageURL, actions) { var id = encodeURIComponent(name); var $header = $insertPoint.prev('.header'); $header.attr('count', parseInt($header.attr('count')||0)+1); var $appendTo = $insertPoint.find('.entry[elementid="'+id+'"] > ul'); if ( !$appendTo.length ) { var $wrapper = $('
').addClass('entry').attr('elementid', id).appendTo($insertPoint); $('').text(name).appendTo($wrapper); guiElementActions(actions.concat([ORPHANACTIONS.clear()]), id, url, $wrapper); $appendTo = $('
    ').appendTo($wrapper); } if ( requestPage && requestPage.length ) { var $pageId = $('').text(requestPage); var $entry = $('
  • ').addClass('requestPage').append($pageId).appendTo($appendTo); guiElementActions(actions, requestPage, requestPageURL, $entry); } }; /** * Build up the structure for linked and wanted pages */ var checkResponseForWantedAndLinked = function(response, requestPage) { // Fill the $currentResults object with information. var checkResponse = function( name, url, amount, object, $output, actions ) { var checkId = name.split( '#', 2 ).shift(); var checkPoint = amount == 0 ? object.wanted : object.linked; if ( !Array.isArray(checkPoint[checkId]) ) { checkPoint[checkId] = []; } if ( checkPoint[checkId].indexOf(requestPage) == -1 ) { checkPoint[checkId].push(requestPage); } addGUIEntry($output.find('.multiorphan__result.' + (amount == 0 ? 'wanted' : 'linked')), name, url, requestPage, (response||{}).href, actions); }; var $pagesOut = $orphanForm.find('.multiorphan__result_group.pages'); var $mediaOut = $orphanForm.find('.multiorphan__result_group.media'); $.each((response||{}).pages||[], function(page, data){ checkResponse(page, data.href, data.amount, $currentResults.pages, $pagesOut, [ORPHANACTIONS.view('Page')]); }); $.each((response||{}).urls||[], function(page, data){ checkResponse(page, data.href, data.amount, $currentResults.pages, $pagesOut, [ORPHANACTIONS.view('URL')]); }); $.each((response||{}).media||[], function(media, data){ checkResponse(media, data.href, data.amount, $currentResults.media, $mediaOut, [ORPHANACTIONS.view('Media')]); }); }; /** * walk all linked pages and remove them from the ones that actually exist in the wiki * assign the result to the array. */ var findOrphans = function(processCompleted) { // Sort out all not var orphaned = function(linked, original) { if ( !original || !original.length ) return []; var orphaned = $.makeArray(original); // make copy $.each(linked, function(link) { if ( (idx = orphaned.indexOf(link)) > -1 ) { orphaned.splice(idx, 1); } }); return orphaned; }; status(getLang('checking-orphans')); $currentResults.pages.orphan = orphaned($currentResults.pages.linked, $currentPagesAndMedia.pages); $currentResults.media.orphan = orphaned($currentResults.media.linked, $currentPagesAndMedia.media); var $pagesOut = $orphanForm.find('.multiorphan__result_group.pages .multiorphan__result.orphan'); var $mediaOut = $orphanForm.find('.multiorphan__result_group.media .multiorphan__result.orphan'); $orphanForm.find('.multiorphan__result_group .orphan.header').attr('count', null); if ( processCompleted == true ) { $orphanForm.find('.multiorphan__result_group .multiorphan__result.orphan').html(''); $.each($currentResults.pages.orphan, function(idx, orphan){ addGUIEntry($pagesOut, orphan, null, null, null, [ORPHANACTIONS.view('Page'), ORPHANACTIONS.delete('Page')]); }); $.each($currentResults.media.orphan, function(idx, orphan){ addGUIEntry($mediaOut, orphan, null, null, null, [ORPHANACTIONS.view('Media'), ORPHANACTIONS.delete('Media')]); }); } else { $orphanForm.find('.multiorphan__result_group .multiorphan__result.orphan').append($('
    ').html(getLang('please-wait-orphan'))); $pagesOut.prev('.header').attr('count', $currentResults.pages.orphan.length); $mediaOut.prev('.header').attr('count', $currentResults.media.orphan.length); } }; /** * Send a request to the plugin. */ var request = function(data, success) { data['ns'] = $orphanForm.find('input[name=ns]').val(); data['filter'] = $orphanForm.find('input[name=filter]').val(); data['sectok'] = $orphanForm.find('input[name=sectok]').val(); if ( $orphanForm.find('input[name=purge]').is(':checked') ) { data['purge'] = true } if ( $orphanForm.find('input[name=checkExternal]').is(':checked') ) { data['checkExternal'] = true } if ( $orphanForm.find('input[name=includeWindowsShares]').is(':checked') ) { data['includeWindowsShares'] = true } if ( $orphanForm.find('input[name=includeHidden]').is(':checked') ) { data['includeHidden'] = true } // data['type'] = $orphanForm.find('select[name=type]').val() || 'both'; data['call'] = 'multiorphan'; throbber(true); return $.post(DOKU_BASE + 'lib/exe/ajax.php', data, handleResponse(success)).always(function(){ throbber(false); }); }; /** * Handles Reponses with JSON from AJAX requests. * Also takes care of errors. */ var handleResponse = function( next ) { return function( response ) { // Check for errors var $result; try { $result = $.parseJSON(response); } catch( e ) { throbber(false); return errorLog( getLang('error-parsing') + "\n" + response + "\n\n" + e ); } delete response; if ( $result && $result.error ) { reset(); return errorLog( $result.error ); } else { return next( $result ); } } }; /** * Set text for status */ var status = function(text) { $('#multiorphan__out').html(text).removeClass('error'); }; /** * Log errors into container */ var errorLog = function(text) { if (!text || !text.length) { return; } if (!$('#multiorphan__errorlog').size()) { $('#multiorphan__out').parent().append($('
    ')); } var msg = text.split("\n"); for ( var int = 0; int < msg.length; int++) { var txtMsg = msg[int]; txtMsg = txtMsg.replace(new RegExp("^runtime error:", "i"), ""); if (txtMsg.length == 0) { continue; } $('#multiorphan__errorlog').append($('

    ').text(txtMsg.replace(new RegExp("", "ig"), ""))); } }; var resetErrorLog = function() { $('#multiorphan__errorlog').remove(); }; /** * Display the loading gif */ var throbberCount = 0; var throbber = function(on) { throbberCount = Math.max(0, throbberCount + (on?1:-1)); $('#multiorphan__throbber').css('visibility', throbberCount>0 ? 'visible' : 'hidden'); }; var reset = function(fullReset) { canBeStopped = false; // Result Object $currentResults = { pages: { linked: {}, wanted: {}, orphan: [] }, media: { linked: {}, wanted: {}, orphan: [] } }; // All pages and Media from DW $currentPagesAndMedia = {}; throbber(false); $orphanForm.find('button[type=submit]').text(getLang('start')); if ( fullReset === true ) { resetErrorLog(); $orphanForm.find('.multiorphan__result_group .header').attr('count', null); $orphanForm.find('.multiorphan__result_group .multiorphan__result').html(''); } }; var getLang = function(key) { return LANG.plugins.multiorphan ? LANG.plugins.multiorphan[key] : key; }; $(document).ready(init); })(jQuery);