Файловый менеджер - Редактировать - /home/digilove/public_html/41423/com_contenthistory.tar
Назад
css/index.html 0000644 00000000037 15232574452 0007342 0 ustar 00 <!DOCTYPE html><title></title> css/jquery.pretty-text-diff.css 0000644 00000000214 15232574452 0012611 0 ustar 00 /* colors for pretty-text-diff*/ ins { background-color: #c6ffc6; text-decoration: none; } del { background-color: #ffc6c6; } js/admin-history-versions.js 0000644 00000000461 15232574452 0012165 0 ustar 00 /** * @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ window.addEventListener('DOMContentLoaded', function() { document.body.appendChild(document.getElementById('versionsModal')); }); js/diff_match_patch.js 0000644 00000045370 15232574452 0011003 0 ustar 00 (function(){function diff_match_patch(){this.Diff_Timeout=1;this.Diff_EditCost=4;this.Match_Threshold=0.5;this.Match_Distance=1E3;this.Patch_DeleteThreshold=0.5;this.Patch_Margin=4;this.Match_MaxBits=32} diff_match_patch.prototype.diff_main=function(a,b,c,d){"undefined"==typeof d&&(d=0>=this.Diff_Timeout?Number.MAX_VALUE:(new Date).getTime()+1E3*this.Diff_Timeout);if(null==a||null==b)throw Error("Null input. (diff_main)");if(a==b)return a?[[0,a]]:[];"undefined"==typeof c&&(c=!0);var e=c,f=this.diff_commonPrefix(a,b);c=a.substring(0,f);a=a.substring(f);b=b.substring(f);var f=this.diff_commonSuffix(a,b),g=a.substring(a.length-f);a=a.substring(0,a.length-f);b=b.substring(0,b.length-f);a=this.diff_compute_(a, b,e,d);c&&a.unshift([0,c]);g&&a.push([0,g]);this.diff_cleanupMerge(a);return a}; diff_match_patch.prototype.diff_compute_=function(a,b,c,d){if(!a)return[[1,b]];if(!b)return[[-1,a]];var e=a.length>b.length?a:b,f=a.length>b.length?b:a,g=e.indexOf(f);return-1!=g?(c=[[1,e.substring(0,g)],[0,f],[1,e.substring(g+f.length)]],a.length>b.length&&(c[0][0]=c[2][0]=-1),c):1==f.length?[[-1,a],[1,b]]:(e=this.diff_halfMatch_(a,b))?(f=e[0],a=e[1],g=e[2],b=e[3],e=e[4],f=this.diff_main(f,g,c,d),c=this.diff_main(a,b,c,d),f.concat([[0,e]],c)):c&&100<a.length&&100<b.length?this.diff_lineMode_(a,b, d):this.diff_bisect_(a,b,d)}; diff_match_patch.prototype.diff_lineMode_=function(a,b,c){var d=this.diff_linesToChars_(a,b);a=d.chars1;b=d.chars2;d=d.lineArray;a=this.diff_main(a,b,!1,c);this.diff_charsToLines_(a,d);this.diff_cleanupSemantic(a);a.push([0,""]);for(var e=d=b=0,f="",g="";b<a.length;){switch(a[b][0]){case 1:e++;g+=a[b][1];break;case -1:d++;f+=a[b][1];break;case 0:if(1<=d&&1<=e){a.splice(b-d-e,d+e);b=b-d-e;d=this.diff_main(f,g,!1,c);for(e=d.length-1;0<=e;e--)a.splice(b,0,d[e]);b+=d.length}d=e=0;g=f=""}b++}a.pop();return a}; diff_match_patch.prototype.diff_bisect_=function(a,b,c){for(var d=a.length,e=b.length,f=Math.ceil((d+e)/2),g=f,h=2*f,j=Array(h),i=Array(h),k=0;k<h;k++)j[k]=-1,i[k]=-1;j[g+1]=0;i[g+1]=0;for(var k=d-e,q=0!=k%2,r=0,t=0,p=0,w=0,v=0;v<f&&!((new Date).getTime()>c);v++){for(var n=-v+r;n<=v-t;n+=2){var l=g+n,m;m=n==-v||n!=v&&j[l-1]<j[l+1]?j[l+1]:j[l-1]+1;for(var s=m-n;m<d&&s<e&&a.charAt(m)==b.charAt(s);)m++,s++;j[l]=m;if(m>d)t+=2;else if(s>e)r+=2;else if(q&&(l=g+k-n,0<=l&&l<h&&-1!=i[l])){var u=d-i[l];if(m>= u)return this.diff_bisectSplit_(a,b,m,s,c)}}for(n=-v+p;n<=v-w;n+=2){l=g+n;u=n==-v||n!=v&&i[l-1]<i[l+1]?i[l+1]:i[l-1]+1;for(m=u-n;u<d&&m<e&&a.charAt(d-u-1)==b.charAt(e-m-1);)u++,m++;i[l]=u;if(u>d)w+=2;else if(m>e)p+=2;else if(!q&&(l=g+k-n,0<=l&&(l<h&&-1!=j[l])&&(m=j[l],s=g+m-l,u=d-u,m>=u)))return this.diff_bisectSplit_(a,b,m,s,c)}}return[[-1,a],[1,b]]}; diff_match_patch.prototype.diff_bisectSplit_=function(a,b,c,d,e){var f=a.substring(0,c),g=b.substring(0,d);a=a.substring(c);b=b.substring(d);f=this.diff_main(f,g,!1,e);e=this.diff_main(a,b,!1,e);return f.concat(e)}; diff_match_patch.prototype.diff_linesToChars_=function(a,b){function c(a){for(var b="",c=0,f=-1,g=d.length;f<a.length-1;){f=a.indexOf("\n",c);-1==f&&(f=a.length-1);var r=a.substring(c,f+1),c=f+1;(e.hasOwnProperty?e.hasOwnProperty(r):void 0!==e[r])?b+=String.fromCharCode(e[r]):(b+=String.fromCharCode(g),e[r]=g,d[g++]=r)}return b}var d=[],e={};d[0]="";var f=c(a),g=c(b);return{chars1:f,chars2:g,lineArray:d}}; diff_match_patch.prototype.diff_charsToLines_=function(a,b){for(var c=0;c<a.length;c++){for(var d=a[c][1],e=[],f=0;f<d.length;f++)e[f]=b[d.charCodeAt(f)];a[c][1]=e.join("")}};diff_match_patch.prototype.diff_commonPrefix=function(a,b){if(!a||!b||a.charAt(0)!=b.charAt(0))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(f,e)==b.substring(f,e)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e}; diff_match_patch.prototype.diff_commonSuffix=function(a,b){if(!a||!b||a.charAt(a.length-1)!=b.charAt(b.length-1))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(a.length-e,a.length-f)==b.substring(b.length-e,b.length-f)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e}; diff_match_patch.prototype.diff_commonOverlap_=function(a,b){var c=a.length,d=b.length;if(0==c||0==d)return 0;c>d?a=a.substring(c-d):c<d&&(b=b.substring(0,c));c=Math.min(c,d);if(a==b)return c;for(var d=0,e=1;;){var f=a.substring(c-e),f=b.indexOf(f);if(-1==f)return d;e+=f;if(0==f||a.substring(c-e)==b.substring(0,e))d=e,e++}}; diff_match_patch.prototype.diff_halfMatch_=function(a,b){function c(a,b,c){for(var d=a.substring(c,c+Math.floor(a.length/4)),e=-1,g="",h,j,n,l;-1!=(e=b.indexOf(d,e+1));){var m=f.diff_commonPrefix(a.substring(c),b.substring(e)),s=f.diff_commonSuffix(a.substring(0,c),b.substring(0,e));g.length<s+m&&(g=b.substring(e-s,e)+b.substring(e,e+m),h=a.substring(0,c-s),j=a.substring(c+m),n=b.substring(0,e-s),l=b.substring(e+m))}return 2*g.length>=a.length?[h,j,n,l,g]:null}if(0>=this.Diff_Timeout)return null; var d=a.length>b.length?a:b,e=a.length>b.length?b:a;if(4>d.length||2*e.length<d.length)return null;var f=this,g=c(d,e,Math.ceil(d.length/4)),d=c(d,e,Math.ceil(d.length/2)),h;if(!g&&!d)return null;h=d?g?g[4].length>d[4].length?g:d:d:g;var j;a.length>b.length?(g=h[0],d=h[1],e=h[2],j=h[3]):(e=h[0],j=h[1],g=h[2],d=h[3]);h=h[4];return[g,d,e,j,h]}; diff_match_patch.prototype.diff_cleanupSemantic=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=0,h=0,j=0,i=0;f<a.length;)0==a[f][0]?(c[d++]=f,g=j,h=i,i=j=0,e=a[f][1]):(1==a[f][0]?j+=a[f][1].length:i+=a[f][1].length,e&&(e.length<=Math.max(g,h)&&e.length<=Math.max(j,i))&&(a.splice(c[d-1],0,[-1,e]),a[c[d-1]+1][0]=1,d--,d--,f=0<d?c[d-1]:-1,i=j=h=g=0,e=null,b=!0)),f++;b&&this.diff_cleanupMerge(a);this.diff_cleanupSemanticLossless(a);for(f=1;f<a.length;){if(-1==a[f-1][0]&&1==a[f][0]){b=a[f-1][1];c=a[f][1]; d=this.diff_commonOverlap_(b,c);e=this.diff_commonOverlap_(c,b);if(d>=e){if(d>=b.length/2||d>=c.length/2)a.splice(f,0,[0,c.substring(0,d)]),a[f-1][1]=b.substring(0,b.length-d),a[f+1][1]=c.substring(d),f++}else if(e>=b.length/2||e>=c.length/2)a.splice(f,0,[0,b.substring(0,e)]),a[f-1][0]=1,a[f-1][1]=c.substring(0,c.length-e),a[f+1][0]=-1,a[f+1][1]=b.substring(e),f++;f++}f++}}; diff_match_patch.prototype.diff_cleanupSemanticLossless=function(a){function b(a,b){if(!a||!b)return 6;var c=a.charAt(a.length-1),d=b.charAt(0),e=c.match(diff_match_patch.nonAlphaNumericRegex_),f=d.match(diff_match_patch.nonAlphaNumericRegex_),g=e&&c.match(diff_match_patch.whitespaceRegex_),h=f&&d.match(diff_match_patch.whitespaceRegex_),c=g&&c.match(diff_match_patch.linebreakRegex_),d=h&&d.match(diff_match_patch.linebreakRegex_),i=c&&a.match(diff_match_patch.blanklineEndRegex_),j=d&&b.match(diff_match_patch.blanklineStartRegex_); return i||j?5:c||d?4:e&&!g&&h?3:g||h?2:e||f?1:0}for(var c=1;c<a.length-1;){if(0==a[c-1][0]&&0==a[c+1][0]){var d=a[c-1][1],e=a[c][1],f=a[c+1][1],g=this.diff_commonSuffix(d,e);if(g)var h=e.substring(e.length-g),d=d.substring(0,d.length-g),e=h+e.substring(0,e.length-g),f=h+f;for(var g=d,h=e,j=f,i=b(d,e)+b(e,f);e.charAt(0)===f.charAt(0);){var d=d+e.charAt(0),e=e.substring(1)+f.charAt(0),f=f.substring(1),k=b(d,e)+b(e,f);k>=i&&(i=k,g=d,h=e,j=f)}a[c-1][1]!=g&&(g?a[c-1][1]=g:(a.splice(c-1,1),c--),a[c][1]= h,j?a[c+1][1]=j:(a.splice(c+1,1),c--))}c++}};diff_match_patch.nonAlphaNumericRegex_=/[^a-zA-Z0-9]/;diff_match_patch.whitespaceRegex_=/\s/;diff_match_patch.linebreakRegex_=/[\r\n]/;diff_match_patch.blanklineEndRegex_=/\n\r?\n$/;diff_match_patch.blanklineStartRegex_=/^\r?\n\r?\n/; diff_match_patch.prototype.diff_cleanupEfficiency=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=!1,h=!1,j=!1,i=!1;f<a.length;){if(0==a[f][0])a[f][1].length<this.Diff_EditCost&&(j||i)?(c[d++]=f,g=j,h=i,e=a[f][1]):(d=0,e=null),j=i=!1;else if(-1==a[f][0]?i=!0:j=!0,e&&(g&&h&&j&&i||e.length<this.Diff_EditCost/2&&3==g+h+j+i))a.splice(c[d-1],0,[-1,e]),a[c[d-1]+1][0]=1,d--,e=null,g&&h?(j=i=!0,d=0):(d--,f=0<d?c[d-1]:-1,j=i=!1),b=!0;f++}b&&this.diff_cleanupMerge(a)}; diff_match_patch.prototype.diff_cleanupMerge=function(a){a.push([0,""]);for(var b=0,c=0,d=0,e="",f="",g;b<a.length;)switch(a[b][0]){case 1:d++;f+=a[b][1];b++;break;case -1:c++;e+=a[b][1];b++;break;case 0:1<c+d?(0!==c&&0!==d&&(g=this.diff_commonPrefix(f,e),0!==g&&(0<b-c-d&&0==a[b-c-d-1][0]?a[b-c-d-1][1]+=f.substring(0,g):(a.splice(0,0,[0,f.substring(0,g)]),b++),f=f.substring(g),e=e.substring(g)),g=this.diff_commonSuffix(f,e),0!==g&&(a[b][1]=f.substring(f.length-g)+a[b][1],f=f.substring(0,f.length- g),e=e.substring(0,e.length-g))),0===c?a.splice(b-d,c+d,[1,f]):0===d?a.splice(b-c,c+d,[-1,e]):a.splice(b-c-d,c+d,[-1,e],[1,f]),b=b-c-d+(c?1:0)+(d?1:0)+1):0!==b&&0==a[b-1][0]?(a[b-1][1]+=a[b][1],a.splice(b,1)):b++,c=d=0,f=e=""}""===a[a.length-1][1]&&a.pop();c=!1;for(b=1;b<a.length-1;)0==a[b-1][0]&&0==a[b+1][0]&&(a[b][1].substring(a[b][1].length-a[b-1][1].length)==a[b-1][1]?(a[b][1]=a[b-1][1]+a[b][1].substring(0,a[b][1].length-a[b-1][1].length),a[b+1][1]=a[b-1][1]+a[b+1][1],a.splice(b-1,1),c=!0):a[b][1].substring(0, a[b+1][1].length)==a[b+1][1]&&(a[b-1][1]+=a[b+1][1],a[b][1]=a[b][1].substring(a[b+1][1].length)+a[b+1][1],a.splice(b+1,1),c=!0)),b++;c&&this.diff_cleanupMerge(a)};diff_match_patch.prototype.diff_xIndex=function(a,b){var c=0,d=0,e=0,f=0,g;for(g=0;g<a.length;g++){1!==a[g][0]&&(c+=a[g][1].length);-1!==a[g][0]&&(d+=a[g][1].length);if(c>b)break;e=c;f=d}return a.length!=g&&-1===a[g][0]?f:f+(b-e)}; diff_match_patch.prototype.diff_prettyHtml=function(a){for(var b=[],c=/&/g,d=/</g,e=/>/g,f=/\n/g,g=0;g<a.length;g++){var h=a[g][0],j=a[g][1],j=j.replace(c,"&").replace(d,"<").replace(e,">").replace(f,"¶<br>");switch(h){case 1:b[g]='<ins style="background:#e6ffe6;">'+j+"</ins>";break;case -1:b[g]='<del style="background:#ffe6e6;">'+j+"</del>";break;case 0:b[g]="<span>"+j+"</span>"}}return b.join("")}; diff_match_patch.prototype.diff_text1=function(a){for(var b=[],c=0;c<a.length;c++)1!==a[c][0]&&(b[c]=a[c][1]);return b.join("")};diff_match_patch.prototype.diff_text2=function(a){for(var b=[],c=0;c<a.length;c++)-1!==a[c][0]&&(b[c]=a[c][1]);return b.join("")};diff_match_patch.prototype.diff_levenshtein=function(a){for(var b=0,c=0,d=0,e=0;e<a.length;e++){var f=a[e][0],g=a[e][1];switch(f){case 1:c+=g.length;break;case -1:d+=g.length;break;case 0:b+=Math.max(c,d),d=c=0}}return b+=Math.max(c,d)}; diff_match_patch.prototype.diff_toDelta=function(a){for(var b=[],c=0;c<a.length;c++)switch(a[c][0]){case 1:b[c]="+"+encodeURI(a[c][1]);break;case -1:b[c]="-"+a[c][1].length;break;case 0:b[c]="="+a[c][1].length}return b.join("\t").replace(/%20/g," ")}; diff_match_patch.prototype.diff_fromDelta=function(a,b){for(var c=[],d=0,e=0,f=b.split(/\t/g),g=0;g<f.length;g++){var h=f[g].substring(1);switch(f[g].charAt(0)){case "+":try{c[d++]=[1,decodeURI(h)]}catch(j){throw Error("Illegal escape in diff_fromDelta: "+h);}break;case "-":case "=":var i=parseInt(h,10);if(isNaN(i)||0>i)throw Error("Invalid number in diff_fromDelta: "+h);h=a.substring(e,e+=i);"="==f[g].charAt(0)?c[d++]=[0,h]:c[d++]=[-1,h];break;default:if(f[g])throw Error("Invalid diff operation in diff_fromDelta: "+ f[g]);}}if(e!=a.length)throw Error("Delta length ("+e+") does not equal source text length ("+a.length+").");return c};diff_match_patch.prototype.match_main=function(a,b,c){if(null==a||null==b||null==c)throw Error("Null input. (match_main)");c=Math.max(0,Math.min(c,a.length));return a==b?0:a.length?a.substring(c,c+b.length)==b?c:this.match_bitap_(a,b,c):-1}; diff_match_patch.prototype.match_bitap_=function(a,b,c){function d(a,d){var e=a/b.length,g=Math.abs(c-d);return!f.Match_Distance?g?1:e:e+g/f.Match_Distance}if(b.length>this.Match_MaxBits)throw Error("Pattern too long for this browser.");var e=this.match_alphabet_(b),f=this,g=this.Match_Threshold,h=a.indexOf(b,c);-1!=h&&(g=Math.min(d(0,h),g),h=a.lastIndexOf(b,c+b.length),-1!=h&&(g=Math.min(d(0,h),g)));for(var j=1<<b.length-1,h=-1,i,k,q=b.length+a.length,r,t=0;t<b.length;t++){i=0;for(k=q;i<k;)d(t,c+ k)<=g?i=k:q=k,k=Math.floor((q-i)/2+i);q=k;i=Math.max(1,c-k+1);var p=Math.min(c+k,a.length)+b.length;k=Array(p+2);for(k[p+1]=(1<<t)-1;p>=i;p--){var w=e[a.charAt(p-1)];k[p]=0===t?(k[p+1]<<1|1)&w:(k[p+1]<<1|1)&w|((r[p+1]|r[p])<<1|1)|r[p+1];if(k[p]&j&&(w=d(t,p-1),w<=g))if(g=w,h=p-1,h>c)i=Math.max(1,2*c-h);else break}if(d(t+1,c)>g)break;r=k}return h}; diff_match_patch.prototype.match_alphabet_=function(a){for(var b={},c=0;c<a.length;c++)b[a.charAt(c)]=0;for(c=0;c<a.length;c++)b[a.charAt(c)]|=1<<a.length-c-1;return b}; diff_match_patch.prototype.patch_addContext_=function(a,b){if(0!=b.length){for(var c=b.substring(a.start2,a.start2+a.length1),d=0;b.indexOf(c)!=b.lastIndexOf(c)&&c.length<this.Match_MaxBits-this.Patch_Margin-this.Patch_Margin;)d+=this.Patch_Margin,c=b.substring(a.start2-d,a.start2+a.length1+d);d+=this.Patch_Margin;(c=b.substring(a.start2-d,a.start2))&&a.diffs.unshift([0,c]);(d=b.substring(a.start2+a.length1,a.start2+a.length1+d))&&a.diffs.push([0,d]);a.start1-=c.length;a.start2-=c.length;a.length1+= c.length+d.length;a.length2+=c.length+d.length}}; diff_match_patch.prototype.patch_make=function(a,b,c){var d;if("string"==typeof a&&"string"==typeof b&&"undefined"==typeof c)d=a,b=this.diff_main(d,b,!0),2<b.length&&(this.diff_cleanupSemantic(b),this.diff_cleanupEfficiency(b));else if(a&&"object"==typeof a&&"undefined"==typeof b&&"undefined"==typeof c)b=a,d=this.diff_text1(b);else if("string"==typeof a&&b&&"object"==typeof b&&"undefined"==typeof c)d=a;else if("string"==typeof a&&"string"==typeof b&&c&&"object"==typeof c)d=a,b=c;else throw Error("Unknown call format to patch_make."); if(0===b.length)return[];c=[];a=new diff_match_patch.patch_obj;for(var e=0,f=0,g=0,h=d,j=0;j<b.length;j++){var i=b[j][0],k=b[j][1];!e&&0!==i&&(a.start1=f,a.start2=g);switch(i){case 1:a.diffs[e++]=b[j];a.length2+=k.length;d=d.substring(0,g)+k+d.substring(g);break;case -1:a.length1+=k.length;a.diffs[e++]=b[j];d=d.substring(0,g)+d.substring(g+k.length);break;case 0:k.length<=2*this.Patch_Margin&&e&&b.length!=j+1?(a.diffs[e++]=b[j],a.length1+=k.length,a.length2+=k.length):k.length>=2*this.Patch_Margin&& e&&(this.patch_addContext_(a,h),c.push(a),a=new diff_match_patch.patch_obj,e=0,h=d,f=g)}1!==i&&(f+=k.length);-1!==i&&(g+=k.length)}e&&(this.patch_addContext_(a,h),c.push(a));return c};diff_match_patch.prototype.patch_deepCopy=function(a){for(var b=[],c=0;c<a.length;c++){var d=a[c],e=new diff_match_patch.patch_obj;e.diffs=[];for(var f=0;f<d.diffs.length;f++)e.diffs[f]=d.diffs[f].slice();e.start1=d.start1;e.start2=d.start2;e.length1=d.length1;e.length2=d.length2;b[c]=e}return b}; diff_match_patch.prototype.patch_apply=function(a,b){if(0==a.length)return[b,[]];a=this.patch_deepCopy(a);var c=this.patch_addPadding(a);b=c+b+c;this.patch_splitMax(a);for(var d=0,e=[],f=0;f<a.length;f++){var g=a[f].start2+d,h=this.diff_text1(a[f].diffs),j,i=-1;if(h.length>this.Match_MaxBits){if(j=this.match_main(b,h.substring(0,this.Match_MaxBits),g),-1!=j&&(i=this.match_main(b,h.substring(h.length-this.Match_MaxBits),g+h.length-this.Match_MaxBits),-1==i||j>=i))j=-1}else j=this.match_main(b,h,g); if(-1==j)e[f]=!1,d-=a[f].length2-a[f].length1;else if(e[f]=!0,d=j-g,g=-1==i?b.substring(j,j+h.length):b.substring(j,i+this.Match_MaxBits),h==g)b=b.substring(0,j)+this.diff_text2(a[f].diffs)+b.substring(j+h.length);else if(g=this.diff_main(h,g,!1),h.length>this.Match_MaxBits&&this.diff_levenshtein(g)/h.length>this.Patch_DeleteThreshold)e[f]=!1;else{this.diff_cleanupSemanticLossless(g);for(var h=0,k,i=0;i<a[f].diffs.length;i++){var q=a[f].diffs[i];0!==q[0]&&(k=this.diff_xIndex(g,h));1===q[0]?b=b.substring(0, j+k)+q[1]+b.substring(j+k):-1===q[0]&&(b=b.substring(0,j+k)+b.substring(j+this.diff_xIndex(g,h+q[1].length)));-1!==q[0]&&(h+=q[1].length)}}}b=b.substring(c.length,b.length-c.length);return[b,e]}; diff_match_patch.prototype.patch_addPadding=function(a){for(var b=this.Patch_Margin,c="",d=1;d<=b;d++)c+=String.fromCharCode(d);for(d=0;d<a.length;d++)a[d].start1+=b,a[d].start2+=b;var d=a[0],e=d.diffs;if(0==e.length||0!=e[0][0])e.unshift([0,c]),d.start1-=b,d.start2-=b,d.length1+=b,d.length2+=b;else if(b>e[0][1].length){var f=b-e[0][1].length;e[0][1]=c.substring(e[0][1].length)+e[0][1];d.start1-=f;d.start2-=f;d.length1+=f;d.length2+=f}d=a[a.length-1];e=d.diffs;0==e.length||0!=e[e.length-1][0]?(e.push([0, c]),d.length1+=b,d.length2+=b):b>e[e.length-1][1].length&&(f=b-e[e.length-1][1].length,e[e.length-1][1]+=c.substring(0,f),d.length1+=f,d.length2+=f);return c}; diff_match_patch.prototype.patch_splitMax=function(a){for(var b=this.Match_MaxBits,c=0;c<a.length;c++)if(!(a[c].length1<=b)){var d=a[c];a.splice(c--,1);for(var e=d.start1,f=d.start2,g="";0!==d.diffs.length;){var h=new diff_match_patch.patch_obj,j=!0;h.start1=e-g.length;h.start2=f-g.length;""!==g&&(h.length1=h.length2=g.length,h.diffs.push([0,g]));for(;0!==d.diffs.length&&h.length1<b-this.Patch_Margin;){var g=d.diffs[0][0],i=d.diffs[0][1];1===g?(h.length2+=i.length,f+=i.length,h.diffs.push(d.diffs.shift()), j=!1):-1===g&&1==h.diffs.length&&0==h.diffs[0][0]&&i.length>2*b?(h.length1+=i.length,e+=i.length,j=!1,h.diffs.push([g,i]),d.diffs.shift()):(i=i.substring(0,b-h.length1-this.Patch_Margin),h.length1+=i.length,e+=i.length,0===g?(h.length2+=i.length,f+=i.length):j=!1,h.diffs.push([g,i]),i==d.diffs[0][1]?d.diffs.shift():d.diffs[0][1]=d.diffs[0][1].substring(i.length))}g=this.diff_text2(h.diffs);g=g.substring(g.length-this.Patch_Margin);i=this.diff_text1(d.diffs).substring(0,this.Patch_Margin);""!==i&& (h.length1+=i.length,h.length2+=i.length,0!==h.diffs.length&&0===h.diffs[h.diffs.length-1][0]?h.diffs[h.diffs.length-1][1]+=i:h.diffs.push([0,i]));j||a.splice(++c,0,h)}}};diff_match_patch.prototype.patch_toText=function(a){for(var b=[],c=0;c<a.length;c++)b[c]=a[c];return b.join("")}; diff_match_patch.prototype.patch_fromText=function(a){var b=[];if(!a)return b;a=a.split("\n");for(var c=0,d=/^@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@$/;c<a.length;){var e=a[c].match(d);if(!e)throw Error("Invalid patch string: "+a[c]);var f=new diff_match_patch.patch_obj;b.push(f);f.start1=parseInt(e[1],10);""===e[2]?(f.start1--,f.length1=1):"0"==e[2]?f.length1=0:(f.start1--,f.length1=parseInt(e[2],10));f.start2=parseInt(e[3],10);""===e[4]?(f.start2--,f.length2=1):"0"==e[4]?f.length2=0:(f.start2--,f.length2= parseInt(e[4],10));for(c++;c<a.length;){e=a[c].charAt(0);try{var g=decodeURI(a[c].substring(1))}catch(h){throw Error("Illegal escape in patch_fromText: "+g);}if("-"==e)f.diffs.push([-1,g]);else if("+"==e)f.diffs.push([1,g]);else if(" "==e)f.diffs.push([0,g]);else if("@"==e)break;else if(""!==e)throw Error('Invalid patch mode "'+e+'" in: '+g);c++}}return b};diff_match_patch.patch_obj=function(){this.diffs=[];this.start2=this.start1=null;this.length2=this.length1=0}; diff_match_patch.patch_obj.prototype.toString=function(){var a,b;a=0===this.length1?this.start1+",0":1==this.length1?this.start1+1:this.start1+1+","+this.length1;b=0===this.length2?this.start2+",0":1==this.length2?this.start2+1:this.start2+1+","+this.length2;a=["@@ -"+a+" +"+b+" @@\n"];var c;for(b=0;b<this.diffs.length;b++){switch(this.diffs[b][0]){case 1:c="+";break;case -1:c="-";break;case 0:c=" "}a[b+1]=c+encodeURI(this.diffs[b][1])+"\n"}return a.join("").replace(/%20/g," ")}; this.diff_match_patch=diff_match_patch;this.DIFF_DELETE=-1;this.DIFF_INSERT=1;this.DIFF_EQUAL=0;})() js/index.html 0000644 00000000037 15232574452 0007166 0 ustar 00 <!DOCTYPE html><title></title> js/jquery.pretty-text-diff.js 0000644 00000005766 15232574452 0012302 0 ustar 00 // Generated by CoffeeScript 1.4.0 /* @preserve jQuery.PrettyTextDiff 1.0.2 See https://github.com/arnab/jQuery.PrettyTextDiff/ Modified to show with and without HTML: Mark Dexter, Joomla Project. */ (function() { var $; $ = jQuery; $.fn.extend({ prettyTextDiff: function(options) { var dmp, settings; settings = { originalContainer: ".original", changedContainer: ".changed", diffContainer: ".diff", originalHtmlContainer: ".originalhtml", changedHtmlContainer: ".changedhtml", diffHtmlContainer: ".diffhtml", cleanup: true, debug: false }; settings = $.extend(settings, options); $.fn.prettyTextDiff.debug("Options: ", settings, settings); dmp = new diff_match_patch(); return this.each(function() { var changed, diff_as_html, diffs, original, changedhtml, originalhtml, diffshtml; original = $(settings.originalContainer, this).text(); $.fn.prettyTextDiff.debug("Original text found: ", original, settings); changed = $(settings.changedContainer, this).text(); $.fn.prettyTextDiff.debug("Changed text found: ", changed, settings); originalhtml = $(settings.originalHtmlContainer, this).text(); $.fn.prettyTextDiff.debug("Original text found: ", original, settings); changedhtml = $(settings.changedHtmlContainer, this).text(); $.fn.prettyTextDiff.debug("Changed text found: ", changed, settings); diffs = dmp.diff_main(original, changed); diffshtml = dmp.diff_main(originalhtml, changedhtml); if (settings.cleanup) { dmp.diff_cleanupSemantic(diffs); dmp.diff_cleanupSemantic(diffshtml); } $.fn.prettyTextDiff.debug("Diffs: ", diffs, settings); diff_as_html = diffs.map(function(diff) { return $.fn.prettyTextDiff.createHTML(diff); }); diffhtml_as_html = diffshtml.map(function(diff) { return $.fn.prettyTextDiff.createHTML(diff); }); $(settings.diffContainer, this).html(diff_as_html.join('')); $(settings.diffHtmlContainer, this).html(diffhtml_as_html.join('')); return this; }); } }); $.fn.prettyTextDiff.debug = function(message, object, settings) { if (settings.debug) { return console.log(message, object); } }; $.fn.prettyTextDiff.createHTML = function(diff) { var data, html, operation, pattern_amp, pattern_gt, pattern_lt, pattern_para, text; html = []; pattern_amp = /&/g; pattern_lt = /</g; pattern_gt = />/g; pattern_para = /\n/g; operation = diff[0], data = diff[1]; text = data.replace(pattern_amp, '&').replace(pattern_lt, '<').replace(pattern_gt, '>').replace(pattern_para, '<br>'); switch (operation) { case DIFF_INSERT: return '<ins>' + text + '</ins>'; case DIFF_DELETE: return '<del>' + text + '</del>'; case DIFF_EQUAL: return '<span>' + text + '</span>'; } }; }).call(this); js/jquery.pretty-text-diff.min.js 0000644 00000004237 15232574452 0013054 0 ustar 00 (function(){var $;$=jQuery;$.fn.extend({prettyTextDiff:function(options){var dmp,settings;settings={originalContainer:".original",changedContainer:".changed",diffContainer:".diff",originalHtmlContainer:".originalhtml",changedHtmlContainer:".changedhtml",diffHtmlContainer:".diffhtml",cleanup:true,debug:false};settings=$.extend(settings,options);$.fn.prettyTextDiff.debug("Options: ",settings,settings);dmp=new diff_match_patch;return this.each(function(){var changed,diff_as_html,diffs,original,changedhtml, originalhtml,diffshtml;original=$(settings.originalContainer,this).text();$.fn.prettyTextDiff.debug("Original text found: ",original,settings);changed=$(settings.changedContainer,this).text();$.fn.prettyTextDiff.debug("Changed text found: ",changed,settings);originalhtml=$(settings.originalHtmlContainer,this).text();$.fn.prettyTextDiff.debug("Original text found: ",original,settings);changedhtml=$(settings.changedHtmlContainer,this).text();$.fn.prettyTextDiff.debug("Changed text found: ",changed, settings);diffs=dmp.diff_main(original,changed);diffshtml=dmp.diff_main(originalhtml,changedhtml);if(settings.cleanup){dmp.diff_cleanupSemantic(diffs);dmp.diff_cleanupSemantic(diffshtml)}$.fn.prettyTextDiff.debug("Diffs: ",diffs,settings);diff_as_html=diffs.map(function(diff){return $.fn.prettyTextDiff.createHTML(diff)});diffhtml_as_html=diffshtml.map(function(diff){return $.fn.prettyTextDiff.createHTML(diff)});$(settings.diffContainer,this).html(diff_as_html.join(""));$(settings.diffHtmlContainer, this).html(diffhtml_as_html.join(""));return this})}});$.fn.prettyTextDiff.debug=function(message,object,settings){if(settings.debug)return console.log(message,object)};$.fn.prettyTextDiff.createHTML=function(diff){var data,html,operation,pattern_amp,pattern_gt,pattern_lt,pattern_para,text;html=[];pattern_amp=/&/g;pattern_lt=/</g;pattern_gt=/>/g;pattern_para=/\n/g;operation=diff[0],data=diff[1];text=data.replace(pattern_amp,"&").replace(pattern_lt,"<").replace(pattern_gt,">").replace(pattern_para, "<br>");switch(operation){case DIFF_INSERT:return"<ins>"+text+"</ins>";case DIFF_DELETE:return"<del>"+text+"</del>";case DIFF_EQUAL:return"<span>"+text+"</span>"}}}).call(this); index.html 0000644 00000000037 15232574452 0006552 0 ustar 00 <!DOCTYPE html><title></title> controllers/history.php 0000644 00000005723 15234574524 0011346 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; /** * Contenthistory list controller class. * * @since 3.2 */ class ContenthistoryControllerHistory extends JControllerAdmin { /** * Deletes and returns correctly. * * @return void * * @since 3.2 */ public function delete() { $this->checkToken(); // Get items to remove from the request. $cid = (array) $this->input->get('cid', array(), 'int'); // Remove zero values resulting from input filter $cid = array_filter($cid); if (empty($cid)) { JError::raiseWarning(500, JText::_('COM_CONTENTHISTORY_NO_ITEM_SELECTED')); } else { // Get the model. $model = $this->getModel(); // Remove the items. if ($model->delete($cid)) { $this->setMessage(JText::plural('COM_CONTENTHISTORY_N_ITEMS_DELETED', count($cid))); } else { $this->setMessage($model->getError()); } } $this->setRedirect( JRoute::_( 'index.php?option=com_contenthistory&view=history&layout=modal&tmpl=component&item_id=' . $this->input->getInt('item_id') . '&type_id=' . $this->input->getInt('type_id') . '&type_alias=' . $this->input->getCmd('type_alias') . '&' . JSession::getFormToken() . '=1', false ) ); } /** * Proxy for getModel. * * @param string $name The name of the model * @param string $prefix The prefix for the model * @param array $config An additional array of parameters * * @return JModelLegacy The model * * @since 3.2 */ public function getModel($name = 'History', $prefix = 'ContenthistoryModel', $config = array('ignore_request' => true)) { return parent::getModel($name, $prefix, $config); } /** * Toggles the keep forever value for one or more history rows. If it was Yes, changes to No. If No, changes to Yes. * * @return void * * @since 3.2 */ public function keep() { $this->checkToken(); // Get items to remove from the request. $cid = (array) $this->input->get('cid', array(), 'int'); // Remove zero values resulting from input filter $cid = array_filter($cid); if (empty($cid)) { JError::raiseWarning(500, JText::_('COM_CONTENTHISTORY_NO_ITEM_SELECTED')); } else { // Get the model. $model = $this->getModel(); // Remove the items. if ($model->keep($cid)) { $this->setMessage(JText::plural('COM_CONTENTHISTORY_N_ITEMS_KEEP_TOGGLE', count($cid))); } else { $this->setMessage($model->getError()); } } $this->setRedirect( JRoute::_( 'index.php?option=com_contenthistory&view=history&layout=modal&tmpl=component&item_id=' . $this->input->getInt('item_id') . '&type_id=' . $this->input->getInt('type_id') . '&type_alias=' . $this->input->getCmd('type_alias') . '&' . JSession::getFormToken() . '=1', false ) ); } } controllers/index.html 0000644 00000000037 15234574524 0011122 0 ustar 00 <!DOCTYPE html><title></title> controllers/preview.php 0000644 00000001531 15234574524 0011317 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; /** * Contenthistory list controller class. * * @since 3.2 */ class ContenthistoryControllerPreview extends JControllerLegacy { /** * Proxy for getModel. * * @param string $name The name of the model * @param string $prefix The prefix for the model * @param array $config An additional array of parameters * * @return JModelLegacy The model * * @since 3.2 */ public function getModel($name = 'Preview', $prefix = 'ContenthistoryModel', $config = array('ignore_request' => true)) { return parent::getModel($name, $prefix, $config); } } helpers/html/index.html 0000644 00000000037 15234574524 0011162 0 ustar 00 <!DOCTYPE html><title></title> helpers/html/textdiff.php 0000644 00000003216 15234574524 0011515 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('JPATH_PLATFORM') or die; /** * HTML utility class for creating text diffs using jQuery, diff_patch_match.js and jquery.pretty-text-diff.js JavaScript libraries. * * @since 3.2 * * @deprecated 4.0 No replacement */ abstract class JHtmlTextdiff { /** * @var array Array containing information for loaded files * @since 3.2 */ protected static $loaded = array(); /** * Method to load Javascript text diff * * @param string $containerId DOM id of the element where the diff will be rendered * * @return void * * @since 3.2 */ public static function textdiff($containerId) { // Only load once if (isset(static::$loaded[__METHOD__])) { return; } // Depends on jQuery UI JHtml::_('bootstrap.framework'); JHtml::_('script', 'com_contenthistory/diff_match_patch.js', array('version' => 'auto', 'relative' => true)); JHtml::_('script', 'com_contenthistory/jquery.pretty-text-diff.min.js', array('version' => 'auto', 'relative' => true)); JHtml::_('stylesheet', 'com_contenthistory/jquery.pretty-text-diff.css', array('version' => 'auto', 'relative' => true)); // Attach diff to document JFactory::getDocument()->addScriptDeclaration(" (function ($){ $(document).ready(function (){ $('#" . $containerId . " tr').prettyTextDiff(); }); })(jQuery); " ); // Set static array static::$loaded[__METHOD__] = true; return; } } helpers/contenthistory.php 0000644 00000026020 15234574524 0012026 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; /** * Categories helper. * * @since 3.2 */ class ContenthistoryHelper { /** * Method to put all field names, including nested ones, in a single array for easy lookup. * * @param stdClass $object Standard class object that may contain one level of nested objects. * * @return array Associative array of all field names, including ones in a nested object. * * @since 3.2 */ public static function createObjectArray($object) { $result = array(); if ($object === null) { return $result; } foreach ($object as $name => $value) { $result[$name] = $value; if (is_object($value)) { foreach ($value as $subName => $subValue) { $result[$subName] = $subValue; } } } return $result; } /** * Method to decode JSON-encoded fields in a standard object. Used to unpack JSON strings in the content history data column. * * @param stdClass $jsonString Standard class object that may contain one or more JSON-encoded fields. * * @return stdClass Object with any JSON-encoded fields unpacked. * * @since 3.2 */ public static function decodeFields($jsonString) { $object = json_decode($jsonString); if (is_object($object)) { foreach ($object as $name => $value) { if ($subObject = json_decode($value)) { $object->$name = $subObject; } } } return $object; } /** * Method to get field labels for the fields in the JSON-encoded object. * First we see if we can find translatable labels for the fields in the object. * We translate any we can find and return an array in the format object->name => label. * * @param stdClass $object Standard class object in the format name->value. * @param JTableContenttype $typesTable Table object with content history options. * * @return stdClass Contains two associative arrays. * $formValues->labels in the format name => label (for example, 'id' => 'Article ID'). * $formValues->values in the format name => value (for example, 'state' => 'Published'. * This translates the text from the selected option in the form. * * @since 3.2 */ public static function getFormValues($object, JTableContenttype $typesTable) { $labels = array(); $values = array(); $expandedObjectArray = static::createObjectArray($object); static::loadLanguageFiles($typesTable->type_alias); if ($formFile = static::getFormFile($typesTable)) { if ($xml = simplexml_load_file($formFile)) { // Now we need to get all of the labels from the form $fieldArray = $xml->xpath('//field'); $fieldArray = array_merge($fieldArray, $xml->xpath('//fields')); foreach ($fieldArray as $field) { if ($label = (string) $field->attributes()->label) { $labels[(string) $field->attributes()->name] = JText::_($label); } } // Get values for any list type fields $listFieldArray = $xml->xpath('//field[@type="list" or @type="radio"]'); foreach ($listFieldArray as $field) { $name = (string) $field->attributes()->name; if (isset($expandedObjectArray[$name])) { $optionFieldArray = $field->xpath('option[@value="' . $expandedObjectArray[$name] . '"]'); $valueText = null; if (is_array($optionFieldArray) && count($optionFieldArray)) { $valueText = trim((string) $optionFieldArray[0]); } $values[(string) $field->attributes()->name] = JText::_($valueText); } } } } $result = new stdClass; $result->labels = $labels; $result->values = $values; return $result; } /** * Method to get the XML form file for this component. Used to get translated field names for history preview. * * @param JTableContenttype $typesTable Table object with content history options. * * @return mixed JModel object if successful, false if no model found. * * @since 3.2 */ public static function getFormFile(JTableContenttype $typesTable) { $result = false; jimport('joomla.filesystem.file'); jimport('joomla.filesystem.folder'); // First, see if we have a file name in the $typesTable $options = json_decode($typesTable->content_history_options); if (is_object($options) && isset($options->formFile) && JFile::exists(JPATH_ROOT . '/' . $options->formFile)) { $result = JPATH_ROOT . '/' . $options->formFile; } else { $aliasArray = explode('.', $typesTable->type_alias); if (count($aliasArray) == 2) { $component = ($aliasArray[1] == 'category') ? 'com_categories' : $aliasArray[0]; $path = JFolder::makeSafe(JPATH_ADMINISTRATOR . '/components/' . $component . '/models/forms/'); $file = JFile::makeSafe($aliasArray[1] . '.xml'); $result = JFile::exists($path . $file) ? $path . $file : false; } } return $result; } /** * Method to query the database using values from lookup objects. * * @param stdClass $lookup The std object with the values needed to do the query. * @param mixed $value The value used to find the matching title or name. Typically the id. * * @return mixed Value from database (for example, name or title) on success, false on failure. * * @since 3.2 */ public static function getLookupValue($lookup, $value) { $result = false; if (isset($lookup->sourceColumn) && isset($lookup->targetTable) && isset($lookup->targetColumn)&& isset($lookup->displayColumn)) { $db = JFactory::getDbo(); $query = $db->getQuery(true); $query->select($db->quoteName($lookup->displayColumn)) ->from($db->quoteName($lookup->targetTable)) ->where($db->quoteName($lookup->targetColumn) . ' = ' . $db->quote($value)); $db->setQuery($query); try { $result = $db->loadResult(); } catch (Exception $e) { // Ignore any errors and just return false return false; } } return $result; } /** * Method to remove fields from the object based on values entered in the #__content_types table. * * @param stdClass $object Object to be passed to view layout file. * @param JTableContenttype $typeTable Table object with content history options. * * @return stdClass object with hidden fields removed. * * @since 3.2 */ public static function hideFields($object, JTableContenttype $typeTable) { if ($options = json_decode($typeTable->content_history_options)) { if (isset($options->hideFields) && is_array($options->hideFields)) { foreach ($options->hideFields as $field) { unset($object->$field); } } } return $object; } /** * Method to load the language files for the component whose history is being viewed. * * @param string $typeAlias The type alias, for example 'com_content.article'. * * @return void * * @since 3.2 */ public static function loadLanguageFiles($typeAlias) { $aliasArray = explode('.', $typeAlias); if (is_array($aliasArray) && count($aliasArray) == 2) { $component = ($aliasArray[1] == 'category') ? 'com_categories' : $aliasArray[0]; $lang = JFactory::getLanguage(); /** * Loading language file from the administrator/language directory then * loading language file from the administrator/components/extension/language directory */ $lang->load($component, JPATH_ADMINISTRATOR, null, false, true) || $lang->load($component, JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $component), null, false, true); // Force loading of backend global language file $lang->load('joomla', JPath::clean(JPATH_ADMINISTRATOR), null, false, true); } } /** * Method to create object to pass to the layout. Format is as follows: * field is std object with name, value. * * Value can be a std object with name, value pairs. * * @param stdClass $object The std object from the JSON string. Can be nested 1 level deep. * @param stdClass $formValues Standard class of label and value in an associative array. * * @return stdClass Object with translated labels where available * * @since 3.2 */ public static function mergeLabels($object, $formValues) { $result = new stdClass; if ($object === null) { return $result; } $labelsArray = $formValues->labels; $valuesArray = $formValues->values; foreach ($object as $name => $value) { $result->$name = new stdClass; $result->$name->name = $name; $result->$name->value = isset($valuesArray[$name]) ? $valuesArray[$name] : $value; $result->$name->label = isset($labelsArray[$name]) ? $labelsArray[$name] : $name; if (is_object($value)) { $subObject = new stdClass; foreach ($value as $subName => $subValue) { $subObject->$subName = new stdClass; $subObject->$subName->name = $subName; $subObject->$subName->value = isset($valuesArray[$subName]) ? $valuesArray[$subName] : $subValue; $subObject->$subName->label = isset($labelsArray[$subName]) ? $labelsArray[$subName] : $subName; $result->$name->value = $subObject; } } } return $result; } /** * Method to prepare the object for the preview and compare views. * * @param JTableContenthistory $table Table object loaded with data. * * @return stdClass Object ready for the views. * * @since 3.2 */ public static function prepareData(JTableContenthistory $table) { $object = static::decodeFields($table->version_data); $typesTable = JTable::getInstance('Contenttype'); $typesTable->load(array('type_id' => $table->ucm_type_id)); $formValues = static::getFormValues($object, $typesTable); $object = static::mergeLabels($object, $formValues); $object = static::hideFields($object, $typesTable); $object = static::processLookupFields($object, $typesTable); return $object; } /** * Method to process any lookup values found in the content_history_options column for this table. * This allows category title and user name to be displayed instead of the id column. * * @param stdClass $object The std object from the JSON string. Can be nested 1 level deep. * @param JTableContenttype $typesTable Table object loaded with data. * * @return stdClass Object with lookup values inserted. * * @since 3.2 */ public static function processLookupFields($object, JTableContenttype $typesTable) { if ($options = json_decode($typesTable->content_history_options)) { if (isset($options->displayLookup) && is_array($options->displayLookup)) { foreach ($options->displayLookup as $lookup) { $sourceColumn = isset($lookup->sourceColumn) ? $lookup->sourceColumn : false; $sourceValue = isset($object->$sourceColumn->value) ? $object->$sourceColumn->value : false; if ($sourceColumn && $sourceValue && ($lookupValue = static::getLookupValue($lookup, $sourceValue))) { $object->$sourceColumn->value = $lookupValue; } } } } return $object; } } helpers/index.html 0000644 00000000037 15234574524 0010216 0 ustar 00 <!DOCTYPE html><title></title> models/compare.php 0000644 00000010635 15234574524 0010206 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; JLoader::register('ContenthistoryHelper', JPATH_ADMINISTRATOR . '/components/com_contenthistory/helpers/contenthistory.php'); /** * Methods supporting a list of contenthistory records. * * @since 3.2 */ class ContenthistoryModelCompare extends JModelItem { /** * Method to get a version history row. * * @return array|boolean On success, array of populated tables. False on failure. * * @since 3.2 */ public function getItems() { $input = JFactory::getApplication()->input; /** @var JTableContenthistory $table1 */ $table1 = JTable::getInstance('Contenthistory'); /** @var JTableContenthistory $table2 */ $table2 = JTable::getInstance('Contenthistory'); $id1 = $input->getInt('id1'); $id2 = $input->getInt('id2'); if (!$id1 || \is_array($id1) || !$id2 || \is_array($id2)) { $this->setError(\JText::_('COM_CONTENTHISTORY_ERROR_INVALID_ID')); return false; } $result = array(); if ($table1->load($id1) && $table2->load($id2)) { // Get the first history record's content type record so we can check ACL /** @var JTableContenttype $contentTypeTable */ $contentTypeTable = JTable::getInstance('Contenttype'); $ucmTypeId = $table1->ucm_type_id; if (!$contentTypeTable->load($ucmTypeId)) { $this->setError(\JText::_('COM_CONTENTHISTORY_ERROR_FAILED_LOADING_CONTENT_TYPE')); // Assume a failure to load the content type means broken data, abort mission return false; } $user = JFactory::getUser(); // Access check if ($user->authorise('core.edit', $contentTypeTable->type_alias . '.' . (int) $table1->ucm_item_id) || $this->canEdit($table1)) { $return = true; } else { $this->setError(JText::_('JERROR_ALERTNOAUTHOR')); return false; } // All's well, process the records if ($return == true) { foreach (array($table1, $table2) as $table) { $object = new stdClass; $object->data = ContenthistoryHelper::prepareData($table); $object->version_note = $table->version_note; // Let's use custom calendars when present $object->save_date = JHtml::_('date', $table->save_date, JText::_('DATE_FORMAT_LC6')); $dateProperties = array ( 'modified_time', 'created_time', 'modified', 'created', 'checked_out_time', 'publish_up', 'publish_down', ); foreach ($dateProperties as $dateProperty) { if (property_exists($object->data, $dateProperty) && $object->data->$dateProperty->value != '0000-00-00 00:00:00') { $object->data->$dateProperty->value = JHtml::_('date', $object->data->$dateProperty->value, JText::_('DATE_FORMAT_LC6')); } } $result[] = $object; } return $result; } } $this->setError(\JText::_('COM_CONTENTHISTORY_ERROR_VERSION_NOT_FOUND')); return false; } /** * Method to test whether a record is editable * * @param JTableContenthistory $record A JTable object. * * @return boolean True if allowed to edit the record. Defaults to the permission set in the component. * * @since 3.6 */ protected function canEdit($record) { $result = false; if (!empty($record->ucm_type_id)) { // Check that the type id matches the type alias $typeAlias = JFactory::getApplication()->input->get('type_alias'); /** @var JTableContenttype $contentTypeTable */ $contentTypeTable = JTable::getInstance('Contenttype', 'JTable'); if ($contentTypeTable->getTypeId($typeAlias) == $record->ucm_type_id) { /** * Make sure user has edit privileges for this content item. Note that we use edit permissions * for the content item, not delete permissions for the content history row. */ $user = JFactory::getUser(); $result = $user->authorise('core.edit', $typeAlias . '.' . (int) $record->ucm_item_id); } // Finally try session (this catches edit.own case too) if (!$result) { $contentTypeTable->load($record->ucm_type_id); $typeEditables = (array) JFactory::getApplication()->getUserState(str_replace('.', '.edit.', $contentTypeTable->type_alias) . '.id'); $result = in_array((int) $record->ucm_item_id, $typeEditables); } } return $result; } } models/history.php 0000644 00000024204 15234574524 0010256 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; /** * Methods supporting a list of contenthistory records. * * @since 3.2 */ class ContenthistoryModelHistory extends JModelList { /** * Constructor. * * @param array $config An optional associative array of configuration settings. * * @see JControllerLegacy * @since 3.2 */ public function __construct($config = array()) { if (empty($config['filter_fields'])) { $config['filter_fields'] = array( 'version_id', 'h.version_id', 'version_note', 'h.version_note', 'save_date', 'h.save_date', 'editor_user_id', 'h.editor_user_id', ); } parent::__construct($config); } /** * Method to test whether a record is editable * * @param JTableContenthistory $record A JTable object. * * @return boolean True if allowed to edit the record. Defaults to the permission set in the component. * * @since 3.2 */ protected function canEdit($record) { $result = false; if (!empty($record->ucm_type_id)) { // Check that the type id matches the type alias $typeAlias = JFactory::getApplication()->input->get('type_alias'); /** @var JTableContenttype $contentTypeTable */ $contentTypeTable = JTable::getInstance('Contenttype', 'JTable'); if ($contentTypeTable->getTypeId($typeAlias) == $record->ucm_type_id) { /** * Make sure user has edit privileges for this content item. Note that we use edit permissions * for the content item, not delete permissions for the content history row. */ $user = JFactory::getUser(); $result = $user->authorise('core.edit', $typeAlias . '.' . (int) $record->ucm_item_id); } // Finally try session (this catches edit.own case too) if (!$result) { $contentTypeTable->load($record->ucm_type_id); $typeEditables = (array) JFactory::getApplication()->getUserState(str_replace('.', '.edit.', $contentTypeTable->type_alias) . '.id'); $result = in_array((int) $record->ucm_item_id, $typeEditables); } } return $result; } /** * Method to test whether a history record can be deleted. Note that we check whether we have edit permissions * for the content item row. * * @param JTableContenthistory $record A JTable object. * * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. * * @since 3.6 */ protected function canDelete($record) { return $this->canEdit($record); } /** * Method to delete one or more records from content history table. * * @param array $pks An array of record primary keys. * * @return boolean True if successful, false if an error occurs. * * @since 3.2 */ public function delete(&$pks) { $pks = (array) $pks; $table = $this->getTable(); // Iterate the items to delete each one. foreach ($pks as $i => $pk) { if ($table->load($pk)) { if ((int) $table->keep_forever === 1) { unset($pks[$i]); continue; } if ($this->canEdit($table)) { if (!$table->delete($pk)) { $this->setError($table->getError()); return false; } } else { // Prune items that you can't change. unset($pks[$i]); $error = $this->getError(); if ($error) { try { JLog::add($error, JLog::WARNING, 'jerror'); } catch (RuntimeException $exception) { JFactory::getApplication()->enqueueMessage($error, 'warning'); } return false; } else { try { JLog::add(JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED'), JLog::WARNING, 'jerror'); } catch (RuntimeException $exception) { JFactory::getApplication()->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED'), 'warning'); } return false; } } } else { $this->setError($table->getError()); return false; } } // Clear the component's cache $this->cleanCache(); return true; } /** * Method to get an array of data items. * * @return mixed An array of data items on success, false on failure. * * @since 3.4.5 */ public function getItems() { $items = parent::getItems(); $user = JFactory::getUser(); if ($items === false) { return false; } // This should be an array with at least one element if (!is_array($items) || !isset($items[0])) { return $items; } // Get the content type's record so we can check ACL /** @var JTableContenttype $contentTypeTable */ $contentTypeTable = JTable::getInstance('Contenttype'); $ucmTypeId = $items[0]->ucm_type_id; if (!$contentTypeTable->load($ucmTypeId)) { // Assume a failure to load the content type means broken data, abort mission return false; } // Access check if ($user->authorise('core.edit', $contentTypeTable->type_alias . '.' . (int) $items[0]->ucm_item_id) || $this->canEdit($items[0])) { return $items; } else { $this->setError(JText::_('JERROR_ALERTNOAUTHOR')); return false; } } /** * Method to get a table object, load it if necessary. * * @param string $type The table name. Optional. * @param string $prefix The class prefix. Optional. * @param array $config Configuration array for model. Optional. * * @return JTable A JTable object * * @since 3.2 */ public function getTable($type = 'Contenthistory', $prefix = 'JTable', $config = array()) { return JTable::getInstance($type, $prefix, $config); } /** * Method to toggle on and off the keep forever value for one or more records from content history table. * * @param array $pks An array of record primary keys. * * @return boolean True if successful, false if an error occurs. * * @since 3.2 */ public function keep(&$pks) { $pks = (array) $pks; $table = $this->getTable(); // Iterate the items to delete each one. foreach ($pks as $i => $pk) { if ($table->load($pk)) { if ($this->canEdit($table)) { $table->keep_forever = $table->keep_forever ? 0 : 1; if (!$table->store()) { $this->setError($table->getError()); return false; } } else { // Prune items that you can't change. unset($pks[$i]); $error = $this->getError(); if ($error) { try { JLog::add($error, JLog::WARNING, 'jerror'); } catch (RuntimeException $exception) { JFactory::getApplication()->enqueueMessage($error, 'warning'); } return false; } else { try { JLog::add(JText::_('COM_CONTENTHISTORY_ERROR_KEEP_NOT_PERMITTED'), JLog::WARNING, 'jerror'); } catch (RuntimeException $exception) { JFactory::getApplication()->enqueueMessage(JText::_('COM_CONTENTHISTORY_ERROR_KEEP_NOT_PERMITTED'), 'warning'); } return false; } } } else { $this->setError($table->getError()); return false; } } // Clear the component's cache $this->cleanCache(); return true; } /** * Method to auto-populate the model state. * * Note. Calling getState in this method will result in recursion. * * @param string $ordering An optional ordering field. * @param string $direction An optional direction (asc|desc). * * @return void * * @since 3.2 */ protected function populateState($ordering = 'h.save_date', $direction = 'DESC') { $input = JFactory::getApplication()->input; $itemId = $input->get('item_id', 0, 'integer'); $typeId = $input->get('type_id', 0, 'integer'); $typeAlias = $input->get('type_alias', '', 'string'); $this->setState('item_id', $itemId); $this->setState('type_id', $typeId); $this->setState('type_alias', $typeAlias); $this->setState('sha1_hash', $this->getSha1Hash()); // Load the parameters. $params = JComponentHelper::getParams('com_contenthistory'); $this->setState('params', $params); // List state information. parent::populateState($ordering, $direction); } /** * Build an SQL query to load the list data. * * @return JDatabaseQuery * * @since 3.2 */ protected function getListQuery() { // Create a new query object. $db = $this->getDbo(); $query = $db->getQuery(true); // Select the required fields from the table. $query->select( $this->getState( 'list.select', 'h.version_id, h.ucm_item_id, h.ucm_type_id, h.version_note, h.save_date, h.editor_user_id,' . 'h.character_count, h.sha1_hash, h.version_data, h.keep_forever' ) ) ->from($db->quoteName('#__ucm_history') . ' AS h') ->where($db->quoteName('h.ucm_item_id') . ' = ' . (int) $this->getState('item_id')) ->where($db->quoteName('h.ucm_type_id') . ' = ' . (int) $this->getState('type_id')) // Join over the users for the editor ->select('uc.name AS editor') ->join('LEFT', '#__users AS uc ON uc.id = h.editor_user_id'); // Add the list ordering clause. $orderCol = $this->state->get('list.ordering'); $orderDirn = $this->state->get('list.direction'); $query->order($db->quoteName($orderCol) . $orderDirn); return $query; } /** * Get the sha1 hash value for the current item being edited. * * @return string sha1 hash of row data * * @since 3.2 */ protected function getSha1Hash() { $result = false; $typeTable = JTable::getInstance('Contenttype', 'JTable'); $typeId = JFactory::getApplication()->input->getInteger('type_id', 0); $typeTable->load($typeId); $typeAliasArray = explode('.', $typeTable->type_alias); JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/' . $typeAliasArray[0] . '/tables'); $contentTable = $typeTable->getContentTable(); $keyValue = JFactory::getApplication()->input->getInteger('item_id', 0); if ($contentTable && $contentTable->load($keyValue)) { $helper = new JHelper; $dataObject = $helper->getDataObject($contentTable); $result = $this->getTable('Contenthistory', 'JTable')->getSha1(json_encode($dataObject), $typeTable); } return $result; } } models/index.html 0000644 00000000037 15234574524 0010037 0 ustar 00 <!DOCTYPE html><title></title> models/preview.php 0000644 00000007344 15234574524 0010244 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; JLoader::register('ContenthistoryHelper', JPATH_ADMINISTRATOR . '/components/com_contenthistory/helpers/contenthistory.php'); /** * Methods supporting a list of contenthistory records. * * @since 3.2 */ class ContenthistoryModelPreview extends JModelItem { /** * Method to get a version history row. * * @return stdClass|boolean On success, standard object with row data. False on failure. * * @since 3.2 */ public function getItem() { /** @var JTableContenthistory $table */ $table = JTable::getInstance('Contenthistory'); $versionId = JFactory::getApplication()->input->getInt('version_id'); if (!$table->load($versionId)) { return false; } // Get the content type's record so we can check ACL /** @var JTableContenttype $contentTypeTable */ $contentTypeTable = JTable::getInstance('Contenttype'); if (!$contentTypeTable->load($table->ucm_type_id)) { // Assume a failure to load the content type means broken data, abort mission return false; } $user = JFactory::getUser(); // Access check if ($user->authorise('core.edit', $contentTypeTable->type_alias . '.' . (int) $table->ucm_item_id) || $this->canEdit($table)) { $return = true; } else { $this->setError(JText::_('JERROR_ALERTNOAUTHOR')); return false; } // Good to go, finish processing the data if ($return == true) { $result = new stdClass; $result->version_note = $table->version_note; $result->data = ContenthistoryHelper::prepareData($table); // Let's use custom calendars when present $result->save_date = JHtml::_('date', $table->save_date, JText::_('DATE_FORMAT_LC6')); $dateProperties = array ( 'modified_time', 'created_time', 'modified', 'created', 'checked_out_time', 'publish_up', 'publish_down', ); foreach ($dateProperties as $dateProperty) { if (property_exists($result->data, $dateProperty) && $result->data->$dateProperty->value != '0000-00-00 00:00:00') { $result->data->$dateProperty->value = JHtml::_('date', $result->data->$dateProperty->value, JText::_('DATE_FORMAT_LC6')); } } return $result; } } /** * Method to test whether a record is editable * * @param JTableContenthistory $record A JTable object. * * @return boolean True if allowed to edit the record. Defaults to the permission set in the component. * * @since 3.6 */ protected function canEdit($record) { $result = false; if (!empty($record->ucm_type_id)) { // Check that the type id matches the type alias $typeAlias = JFactory::getApplication()->input->get('type_alias'); /** @var JTableContenttype $contentTypeTable */ $contentTypeTable = JTable::getInstance('Contenttype', 'JTable'); if ($contentTypeTable->getTypeId($typeAlias) == $record->ucm_type_id) { /** * Make sure user has edit privileges for this content item. Note that we use edit permissions * for the content item, not delete permissions for the content history row. */ $user = JFactory::getUser(); $result = $user->authorise('core.edit', $typeAlias . '.' . (int) $record->ucm_item_id); } // Finally try session (this catches edit.own case too) if (!$result) { $contentTypeTable->load($record->ucm_type_id); $typeEditables = (array) JFactory::getApplication()->getUserState(str_replace('.', '.edit.', $contentTypeTable->type_alias) . '.id'); $result = in_array((int) $record->ucm_item_id, $typeEditables); } } return $result; } } views/compare/tmpl/compare.php 0000644 00000011402 15234574524 0012453 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; JSession::checkToken('get') or die(JText::_('JINVALID_TOKEN')); $version2 = $this->items[0]; $version1 = $this->items[1]; $object1 = $version1->data; $object2 = $version2->data; JHtml::addIncludePath(JPATH_COMPONENT_ADMINISTRATOR . '/helpers/html'); JHtml::_('textdiff.textdiff', 'diff'); JFactory::getDocument()->addScriptDeclaration(" (function ($){ $(document).ready(function (){ jQuery('.diffhtml, .diffhtml-header').hide(); }); })(jQuery); " ); ?> <fieldset> <legend> <?php echo JText::sprintf('COM_CONTENTHISTORY_COMPARE_TITLE'); ?> <div class="btn-group pull-right"> <button id="toolbar-all-rows" class="btn hasTooltip" title="<?php echo JText::_('COM_CONTENTHISTORY_BUTTON_COMPARE_ALL_ROWS_DESC'); ?>" onclick="jQuery('.items-equal').show(); jQuery('#toolbar-all-rows').hide(); jQuery('#toolbar-changed-rows').show()" style="display:none" > <?php echo JText::_('COM_CONTENTHISTORY_BUTTON_COMPARE_ALL_ROWS'); ?></button> <button id="toolbar-changed-rows" class="btn hasTooltip" title="<?php echo JText::_('COM_CONTENTHISTORY_BUTTON_COMPARE_CHANGED_ROWS_DESC'); ?>" onclick="jQuery('.items-equal').hide(); jQuery('#toolbar-all-rows').show(); jQuery('#toolbar-changed-rows').hide()"> <?php echo JText::_('COM_CONTENTHISTORY_BUTTON_COMPARE_CHANGED_ROWS'); ?></button> <button class="diff-header btn hasTooltip" title="<?php echo JText::_('COM_CONTENTHISTORY_BUTTON_COMPARE_HTML_DESC'); ?>" onclick="jQuery('.diffhtml, .diffhtml-header').show(); jQuery('.diff, .diff-header').hide()"> <span class="icon-wrench" aria-hidden="true"></span> <?php echo JText::_('COM_CONTENTHISTORY_BUTTON_COMPARE_HTML'); ?></button> <button class="diffhtml-header btn hasTooltip" title="<?php echo JText::_('COM_CONTENTHISTORY_BUTTON_COMPARE_TEXT_DESC'); ?>" onclick="jQuery('.diffhtml, .diffhtml-header').hide(); jQuery('.diff, .diff-header').show()"> <span class="icon-pencil" aria-hidden="true"></span> <?php echo JText::_('COM_CONTENTHISTORY_BUTTON_COMPARE_TEXT'); ?></button> </div> </legend> <table id="diff" class="table table-striped table-condensed"> <thead><tr> <th width="25%"><?php echo JText::_('COM_CONTENTHISTORY_PREVIEW_FIELD'); ?></th> <th style="display:none" /> <th style="display:none" /> <th><?php echo JText::sprintf('COM_CONTENTHISTORY_COMPARE_VALUE1', $version1->save_date, $version1->version_note); ?></th> <th><?php echo JText::sprintf('COM_CONTENTHISTORY_COMPARE_VALUE2', $version2->save_date, $version2->version_note); ?></th> <th class="diff-header"><?php echo JText::_('COM_CONTENTHISTORY_COMPARE_DIFF'); ?></th> <th class="diffhtml-header"><?php echo JText::_('COM_CONTENTHISTORY_COMPARE_DIFF'); ?></th> </tr></thead> <tbody> <?php foreach ($object1 as $name => $value) : ?> <?php $rowClass = ($value->value == $object2->$name->value) ? 'items-equal' : 'items-not-equal'; ?> <tr class="<?php echo $rowClass; ?>"> <?php if (is_object($value->value)) : ?> <td><strong><?php echo $value->label; ?></strong></td> <td /><td /><td /> <?php foreach ($value->value as $subName => $subValue) : ?> <?php $newSubValue = isset($object2->$name->value->$subName->value) ? $object2->$name->value->$subName->value : ''; ?> <?php if ($subValue->value || $newSubValue) : ?> <?php $rowClass = ($subValue->value == $newSubValue) ? 'items-equal' : 'items-not-equal'; ?> <tr class="<?php echo $rowClass; ?>"> <td><i> <?php echo $subValue->label; ?></i></td> <td class="originalhtml" style="display:none" ><?php echo htmlspecialchars($subValue->value, ENT_COMPAT, 'UTF-8'); ?></td> <td class="changedhtml" style="display:none" ><?php echo htmlspecialchars($newSubValue, ENT_COMPAT, 'UTF-8'); ?></td> <td class="original"><?php echo $subValue->value; ?></td> <td class="changed"><?php echo $newSubValue; ?></td> <td class="diff" /> <td class="diffhtml" /> </tr> <?php endif; ?> <?php endforeach; ?> <?php else : ?> <td><strong><?php echo $value->label; ?></strong></td> <td class="originalhtml" style="display:none" ><?php echo htmlspecialchars($value->value); ?></td> <?php $object2->$name->value = is_object($object2->$name->value) ? json_encode($object2->$name->value) : $object2->$name->value; ?> <td class="changedhtml" style="display:none" ><?php echo htmlspecialchars($object2->$name->value, ENT_COMPAT, 'UTF-8'); ?></td> <td class="original"><?php echo $value->value; ?></td> <td class="changed"><?php echo $object2->$name->value; ?></td> <td class="diff" /> <td class="diffhtml" /> <?php endif; ?> </tr> <?php endforeach; ?> </tbody> </table> </fieldset> views/compare/tmpl/index.html 0000644 00000000037 15234574524 0012313 0 ustar 00 <!DOCTYPE html><title></title> views/compare/index.html 0000644 00000000037 15234574524 0011337 0 ustar 00 <!DOCTYPE html><title></title> views/compare/view.html.php 0000644 00000001622 15234574524 0011771 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; /** * View class for a list of contenthistory. * * @since 3.2 */ class ContenthistoryViewCompare extends JViewLegacy { protected $items; protected $state; /** * Method to display the view. * * @param string $tpl A template file to load. [optional] * * @return mixed Exception on failure, void on success. * * @since 3.2 */ public function display($tpl = null) { $this->state = $this->get('State'); $this->items = $this->get('Items'); // Check for errors. if (count($errors = $this->get('Errors'))) { throw new Exception(implode("\n", $errors), 500); } return parent::display($tpl); } } views/history/tmpl/index.html 0000644 00000000037 15234574524 0012366 0 ustar 00 <!DOCTYPE html><title></title> views/history/tmpl/modal.php 0000644 00000022240 15234574524 0012176 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; JSession::checkToken('get') or die(JText::_('JINVALID_TOKEN')); JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); JHtml::_('bootstrap.tooltip', '.hasTooltip', array('placement' => 'bottom')); JHtml::_('behavior.multiselect'); JHtml::_('jquery.framework'); $input = JFactory::getApplication()->input; $field = $input->getCmd('field'); $function = 'jSelectContenthistory_' . $field; $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); $message = JText::_('COM_CONTENTHISTORY_BUTTON_SELECT_ONE', true); $compareMessage = JText::_('COM_CONTENTHISTORY_BUTTON_SELECT_TWO', true); JText::script('JLIB_HTML_PLEASE_MAKE_A_SELECTION_FROM_THE_LIST'); $deleteMessage = "alert(Joomla.JText._('JLIB_HTML_PLEASE_MAKE_A_SELECTION_FROM_THE_LIST'));"; $aliasArray = explode('.', $this->state->type_alias); $option = (end($aliasArray) == 'category') ? 'com_categories&extension=' . implode('.', array_slice($aliasArray, 0, count($aliasArray) - 1)) : $aliasArray[0]; $filter = JFilterInput::getInstance(); $task = $filter->clean(end($aliasArray)) . '.loadhistory'; $loadUrl = JRoute::_('index.php?option=' . $filter->clean($option) . '&task=' . $task); $deleteUrl = JRoute::_('index.php?option=com_contenthistory&task=history.delete'); $hash = $this->state->get('sha1_hash'); $formUrl = 'index.php?option=com_contenthistory&view=history&layout=modal&tmpl=component&item_id=' . $this->state->get('item_id') . '&type_id=' . $this->state->get('type_id') . '&type_alias=' . $this->state->get('type_alias') . '&' . JSession::getFormToken() . '=1'; JFactory::getDocument()->addScriptDeclaration(" (function ($){ $(document).ready(function (){ $('#toolbar-load').click(function() { var ids = $('input[id*=\'cb\']:checked'); if (ids.length == 1) { // Add version item id to URL var url = $('#toolbar-load').attr('data-url') + '&version_id=' + ids[0].value; $('#content-url').attr('data-url', url); if (window.parent) { window.parent.location = url; } } else { alert('" . $message . "'); } }); $('#toolbar-preview').click(function() { var windowSizeArray = ['width=800, height=600, resizable=yes, scrollbars=yes']; var ids = $('input[id*=\'cb\']:checked'); if (ids.length == 1) { // Add version item id to URL var url = $('#toolbar-preview').attr('data-url') + '&version_id=' + ids[0].value; $('#content-url').attr('data-url', url); if (window.parent) { window.open(url, '', windowSizeArray); return false; } } else { alert('" . $message . "'); } }); $('#toolbar-compare').click(function() { var windowSizeArray = ['width=1000, height=600, resizable=yes, scrollbars=yes']; var ids = $('input[id*=\'cb\']:checked'); if (ids.length == 2) { // Add version item ids to URL var url = $('#toolbar-compare').attr('data-url') + '&id1=' + ids[0].value + '&id2=' + ids[1].value; $('#content-url').attr('data-url', url); if (window.parent) { window.open(url, '', windowSizeArray); return false; } } else { alert('" . $compareMessage . "'); } }); }); })(jQuery); " ); ?> <div class="container-popup"> <div class="btn-group pull-right"> <button id="toolbar-load" type="submit" class="btn hasTooltip" aria-label="<?php echo JText::_('COM_CONTENTHISTORY_BUTTON_LOAD_DESC'); ?>" title="<?php echo JText::_('COM_CONTENTHISTORY_BUTTON_LOAD_DESC'); ?>" data-url="<?php echo JRoute::_($loadUrl); ?>"> <span class="icon-upload" aria-hidden="true"></span><span class="hidden-phone"><?php echo JText::_('COM_CONTENTHISTORY_BUTTON_LOAD'); ?></span></button> <button id="toolbar-preview" type="button" class="btn hasTooltip" aria-label="<?php echo JText::_('COM_CONTENTHISTORY_BUTTON_PREVIEW_DESC'); ?>" title="<?php echo JText::_('COM_CONTENTHISTORY_BUTTON_PREVIEW_DESC'); ?>" data-url="<?php echo JRoute::_('index.php?option=com_contenthistory&view=preview&layout=preview&tmpl=component&' . JSession::getFormToken() . '=1'); ?>"> <span class="icon-search" aria-hidden="true"></span><span class="hidden-phone"><?php echo JText::_('COM_CONTENTHISTORY_BUTTON_PREVIEW'); ?></span></button> <button id="toolbar-compare" type="button" class="btn hasTooltip" aria-label="<?php echo JText::_('COM_CONTENTHISTORY_BUTTON_COMPARE_DESC'); ?>" title="<?php echo JText::_('COM_CONTENTHISTORY_BUTTON_COMPARE_DESC'); ?>" data-url="<?php echo JRoute::_('index.php?option=com_contenthistory&view=compare&layout=compare&tmpl=component&' . JSession::getFormToken() . '=1'); ?>"> <span class="icon-zoom-in" aria-hidden="true"></span><span class="hidden-phone"><?php echo JText::_('COM_CONTENTHISTORY_BUTTON_COMPARE'); ?></span></button> <button onclick="if (document.adminForm.boxchecked.value==0){<?php echo $deleteMessage; ?>}else{ Joomla.submitbutton('history.keep')}" class="btn pointer hasTooltip" aria-label="<?php echo JText::_('COM_CONTENTHISTORY_BUTTON_KEEP_DESC'); ?>" title="<?php echo JText::_('COM_CONTENTHISTORY_BUTTON_KEEP_DESC'); ?>"> <span class="icon-lock" aria-hidden="true"></span><span class="hidden-phone"><?php echo JText::_('COM_CONTENTHISTORY_BUTTON_KEEP'); ?></span></button> <button onclick="if (document.adminForm.boxchecked.value==0){<?php echo $deleteMessage; ?>}else{ Joomla.submitbutton('history.delete')}" class="btn pointer hasTooltip" aria-label="<?php echo JText::_('COM_CONTENTHISTORY_BUTTON_DELETE_DESC'); ?>" title="<?php echo JText::_('COM_CONTENTHISTORY_BUTTON_DELETE_DESC'); ?>"> <span class="icon-delete" aria-hidden="true"></span><span class="hidden-phone"><?php echo JText::_('COM_CONTENTHISTORY_BUTTON_DELETE'); ?></span></button> </div> <div class="clearfix"></div> <hr class="hr-condensed" /> <form action="<?php echo JRoute::_($formUrl); ?>" method="post" name="adminForm" id="adminForm"> <table class="table table-striped table-condensed"> <thead> <tr> <th width="1%" class="center"> <input type="checkbox" name="checkall-toggle" value="" title="<?php echo JText::_('JGLOBAL_CHECK_ALL'); ?>" onclick="Joomla.checkAll(this)" /> </th> <th width="15%"> <?php echo JText::_('JDATE'); ?> </th> <th width="15%" class="nowrap hidden-phone"> <?php echo JText::_('COM_CONTENTHISTORY_VERSION_NOTE'); ?> </th> <th width="10%" class="nowrap"> <?php echo JText::_('COM_CONTENTHISTORY_KEEP_VERSION'); ?> </th> <th width="15%" class="nowrap hidden-phone"> <?php echo JText::_('JAUTHOR'); ?> </th> <th width="10%" class="nowrap center"> <?php echo JText::_('COM_CONTENTHISTORY_CHARACTER_COUNT'); ?> </th> </tr> </thead> <tfoot> <tr> <td colspan="15"> <?php echo $this->pagination->getListFooter(); ?> </td> </tr> </tfoot> <tbody> <?php $i = 0; ?> <?php foreach ($this->items as $item) : ?> <tr class="row<?php echo $i % 2; ?>"> <td class="center"> <?php echo JHtml::_('grid.id', $i, $item->version_id); ?> </td> <td> <a class="save-date" onclick="window.open(this.href,'win2','width=800,height=600,resizable=yes,scrollbars=yes'); return false;" href="<?php echo JRoute::_('index.php?option=com_contenthistory&view=preview&layout=preview&tmpl=component&' . JSession::getFormToken() . '=1&version_id=' . $item->version_id); ?>"> <?php echo JHtml::_('date', $item->save_date, JText::_('DATE_FORMAT_LC6')); ?> </a> <?php if ($item->sha1_hash == $hash) : ?> <span class="icon-featured" aria-hidden="true"><span class="element-invisible"><?php echo JText::_('JFEATURED'); ?></span></span> <?php endif; ?> </td> <td class="hidden-phone"> <?php echo htmlspecialchars($item->version_note); ?> </td> <td> <?php if ($item->keep_forever) : ?> <a class="btn btn-mini active" rel="tooltip" href="javascript:void(0);" onclick="return listItemTask('cb<?php echo $i; ?>','history.keep')" data-original-title="<?php echo JText::_('COM_CONTENTHISTORY_BUTTON_KEEP_TOGGLE_OFF'); ?>"> <?php echo JText::_('JYES'); ?> <span class="icon-lock" aria-hidden="true"></span> </a> <?php else : ?> <a class="btn btn-mini active" rel="tooltip" href="javascript:void(0);" onclick="return listItemTask('cb<?php echo $i; ?>','history.keep')" data-original-title="<?php echo JText::_('COM_CONTENTHISTORY_BUTTON_KEEP_TOGGLE_ON'); ?>"> <?php echo JText::_('JNO'); ?> </a> <?php endif; ?> </td> <td class="hidden-phone"> <?php echo htmlspecialchars($item->editor); ?> </td> <td class="center"> <?php echo number_format((int) $item->character_count, 0, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR')); ?> </td> </tr> <?php $i++; ?> <?php endforeach; ?> </tbody> </table> <input type="hidden" name="task" value="" /> <input type="hidden" name="boxchecked" value="0" /> <?php echo JHtml::_('form.token'); ?> </form> </div> views/history/index.html 0000644 00000000037 15234574524 0011412 0 ustar 00 <!DOCTYPE html><title></title> views/history/view.html.php 0000644 00000001733 15234574524 0012047 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; /** * View class for a list of contenthistory. * * @since 3.2 */ class ContenthistoryViewHistory extends JViewLegacy { protected $items; protected $pagination; protected $state; /** * Method to display the view. * * @param string $tpl A template file to load. [optional] * * @return mixed Exception on failure, void on success. * * @since 3.2 */ public function display($tpl = null) { $this->state = $this->get('State'); $this->items = $this->get('Items'); $this->pagination = $this->get('Pagination'); // Check for errors. if (count($errors = $this->get('Errors'))) { throw new Exception(implode("\n", $errors), 500); } return parent::display($tpl); } } views/preview/tmpl/index.html 0000644 00000000037 15234574524 0012346 0 ustar 00 <!DOCTYPE html><title></title> views/preview/tmpl/preview.php 0000644 00000002657 15234574524 0012555 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; JSession::checkToken('get') or die(JText::_('JINVALID_TOKEN')); ?> <h3> <?php echo JText::sprintf('COM_CONTENTHISTORY_PREVIEW_SUBTITLE_DATE', $this->item->save_date); ?> <?php if ($this->item->version_note) : ?> <?php echo JText::sprintf('COM_CONTENTHISTORY_PREVIEW_SUBTITLE', $this->item->version_note); ?> <?php endif; ?> </h3> <table class="table table-striped" > <thead><tr> <th width="25%"><?php echo JText::_('COM_CONTENTHISTORY_PREVIEW_FIELD'); ?></th> <th><?php echo JText::_('COM_CONTENTHISTORY_PREVIEW_VALUE'); ?></th> </tr></thead> <tbody> <?php foreach ($this->item->data as $name => $value) : ?> <tr> <?php if (is_object($value->value)) : ?> <td><strong><?php echo $value->label; ?></strong></td> <td></td><tr> <?php foreach ($value->value as $subName => $subValue) : ?> <?php if ($subValue) : ?> <tr> <td><i> <?php echo $subValue->label; ?></i></td> <td><?php echo $subValue->value; ?></td> </tr> <?php endif; ?> <?php endforeach; ?> <?php else : ?> <td><strong><?php echo $value->label; ?></strong></td> <td><?php echo $value->value; ?></td> <?php endif; ?> </tr> <?php endforeach; ?> </tbody> </table> views/preview/index.html 0000644 00000000037 15234574524 0011372 0 ustar 00 <!DOCTYPE html><title></title> views/preview/view.html.php 0000644 00000002140 15234574524 0012020 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; /** * View class for a list of contenthistory. * * @since 1.5 */ class ContenthistoryViewPreview extends JViewLegacy { protected $items; protected $state; /** * Method to display the view. * * @param string $tpl A template file to load. [optional] * * @return mixed Exception on failure, void on success. * * @since 3.2 */ public function display($tpl = null) { $this->state = $this->get('State'); $this->item = $this->get('Item'); if (false === $this->item) { JFactory::getLanguage()->load('com_content', JPATH_SITE, null, true); JError::raiseError(404, JText::_('COM_CONTENT_ERROR_ARTICLE_NOT_FOUND')); return false; } // Check for errors. if (count($errors = $this->get('Errors'))) { throw new Exception(implode("\n", $errors), 500); } return parent::display($tpl); } } views/index.html 0000644 00000000037 15234574524 0007711 0 ustar 00 <!DOCTYPE html><title></title> contenthistory.php 0000644 00000001235 15234574524 0010365 0 ustar 00 <?php /** * @package Joomla.Site * @subpackage com_contenthistory * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; // Load the com_contenthistory language files, default to the admin file and fall back to site if one isn't found $lang = JFactory::getLanguage(); $lang->load('com_contenthistory', JPATH_ADMINISTRATOR, null, false, true) || $lang->load('com_contenthistory', JPATH_SITE, null, false, true); // Hand processing over to the admin base file require_once JPATH_COMPONENT_ADMINISTRATOR . '/contenthistory.php'; contenthistory.xml 0000644 00000002155 15234574524 0010400 0 ustar 00 <?xml version="1.0" encoding="utf-8"?> <extension type="component" version="3.2" method="upgrade"> <name>com_contenthistory</name> <author>Joomla! Project</author> <creationDate>May 2013</creationDate> <copyright>(C) 2013 Open Source Matters, Inc.</copyright> <license>GNU General Public License version 2 or later; see LICENSE.txt</license> <authorEmail>admin@joomla.org</authorEmail> <authorUrl>www.joomla.org</authorUrl> <version>3.2.0</version> <description>COM_CONTENTHISTORY_XML_DESCRIPTION</description> <files folder="site"> <filename>contenthistory.php</filename> <filename>index.html</filename> </files> <administration> <files folder="admin"> <filename>controller.php</filename> <filename>contenthistory.php</filename> <folder>controllers</folder> <folder>helpers</folder> <folder>media</folder> <folder>models</folder> <folder>views</folder> </files> <languages folder="admin"> <language tag="en-GB">language/en-GB.com_contenthistory.ini</language> <language tag="en-GB">language/en-GB.com_contenthistory.sys.ini</language> </languages> </administration> </extension> controller.php 0000644 00000000604 15234574524 0007453 0 ustar 00 <?php /** * @package Joomla.Administrator * @subpackage com_contenthistory * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; /** * Contenthistory Controller * * @since 3.2 */ class ContenthistoryController extends JControllerLegacy { }
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | Генерация страницы: 0.03 |
proxy
|
phpinfo
|
Настройка