cancel
Showing results for 
Search instead for 
Did you mean: 

VersionHistory and JavaScript?

sacco
Champ in-the-making
Champ in-the-making
It still doesn't appear to be possible to get at Version History through the
JavaScript API.  Is this intentional, and oversight, or am I missing something?

It does seem a bit silly, given that (with a sufficiently high pain threshold) one
can drag the information out through the keyhole from Freemarker:

versionLabel = doc.processTemplate( '${document.versionHistory[0].versionLabel}' );
5 REPLIES 5

martin_cowie
Champ in-the-making
Champ in-the-making
I have found a means to getting the version history of a node in Javascript … it's a bit ugly though …

function getHistory( doc )
{
   // *BEWARE* - HERE BE DRAGONS
   var field = doc.getClass().getDeclaredField( "services" );
   field.setAccessible( true ); // ick - yuck - nasty - but necessary
   var versionService = field.get( doc ).getVersionService();

   return versionService.getVersionHistory( doc.nodeRef ).getAllVersions().toArray();
}

This returns a JavaScript array of org.alfresco.service.cmr.version.Version Java objects.

louise
Champ in-the-making
Champ in-the-making
So, that is a very nice workaround, but i've trouble while processing answered array.

I would like to access variables, but only these defined:
- ver.versionLabel
- ver.creator

How can i process this array with javascript API or Freemarker?

Variable versionhistory is filled by your function:

    <#list versionhistory as ver>
            {   "versionLabel":"${ver.versionLabel}",
                <#if ver.name??>"name":"${ver.name}",</#if>
                <#if ver.created??>"created":"${ver.created}",</#if>
                <#if ver.description??><#if ver.description!="">"description":"${ver.description}",</#if></#if>
                <#if ver.modified??>"modified":"${ver.modified}",</#if>
                <#if ver.frozenNodeId??>"frozenNodeId":"${ver.frozenNodeId}",</#if>            
                "creator":"${ver.creator}"
            }<#if ver_has_next>,</#if>
    </#list>

This is ver[0]:

{created=Thu Jun 12 14:45:27 CEST 2008, store-protocol=workspace, frozenNodeStoreProtocol=workspace, modifier=admin, frozenAspects=[{http://www.alfresco.org/model/content/1.0}versionable, {http://www.alfresco.org/model/content/1.0}auditable, {http://www.alfresco.org/model/content/1.0}titled, {http://www.alfresco.org/model/content/1.0}lockable, {http://www.alfresco.org/model/system/1.0}referenceable, {http://www.alfresco.org/model/application/1.0}inlineeditable, {http://www.alfresco.org/model/content/1.0}author], versionLabel=1.17, versionType=MINOR, store-identifier=lightWeightVersionStore, frozenNodeStoreId=SpacesStore, node-dbid=5081, modified=Thu Jun 12 14:45:27 CEST 2008, creator=admin, description=, node-uuid=6ec6751d-387d-11dd-bc28-4995248d87ef, frozenNodeId=6153e995-3849-11dd-bc28-4995248d87ef, name=6ec6751d-387d-11dd-bc28-4995248d87ef, versionNumber=164, frozenNodeType={http://www.alfresco.org/model/content/1.0}content}

sacco
Champ in-the-making
Champ in-the-making
Here's how you might get at the version history in JavaScript without
getting involved with Java objects (but this isn't that pretty either).

You can pick out other variables by adding them into the Freemarker
template and then picking them out oft the split array when you build
your object with  versionRecord() .




//  n  is  null  (or undefined)
function isNull(n) { return ( n == undefined || n == null ) };

//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  Scrape Version History via Freemarker  ~~
//  date-time formats (Java)
const  DT_ISO_8601 = 'yyyy-MM-dd\'T\'HH:mm:ss.SSS zzzzz' ;
const  DT_RFC_1123 = 'dd MMM yyyy HH:mm:ss ZZZZZ' ;
const  DT_GMT_8601 = 'yyyy-MM-dd\'T\'HH:mm:ss.SSS \'GMT\'ZZZZZ' ;

//  To add:
//  '<#setting datetime_format=\"' + DT_ISO_8601 + '\" >'
function vHistory( verLabel )
{ return (
'<#setting time_zone=\"UTC\" >'
+ '<#list document.versionHistory?sort_by("createdDate")?reverse as record>'
+(isNull(verLabel)? '' : '<#if record.versionLabel == \"' + verLabel + '\" >')
  + '${record.id}'
  +'\\\\'+ '${record.nodeRef}'
  +'\\\\'+ '${record.name}'
  +'\\\\'+ '${record.type}'
  +'\\\\'+ '${record.createdDate?string(\"' + DT_ISO_8601 + '\")}'
  +'\\\\'+ '${record.creator}'
  +'\\\\'+ '${record.versionLabel}'
  +'\\\\'+ '${record.isMajorVersion?string(\'true\',\'false\')}'
  +'\\\\'+ '${record.url}'
  +'\\\\'+ '<#if record.description?exists>${record.description}</#if>'
  +'\\\\'+ '${record.hasAspect("cm:versionable")?string(\'true\',\'false\')}'
  +'\\\\'+
    '${record.properties["cm:modified"]?string(\"' + DT_ISO_8601 + '\")}'
  +'\\\\'+ '${record.properties.content.size?c}'
  + '\\%%\\'
+(isNull(verLabel)? '' : '<#break></#if>')
+ '</#list>' );
}

function  dateFromStringISO8601( dateString )  {
  var DS = dateString.split("[-:T .]", 9);
  var DP = DS.slice( 0, 7).map( Number );
  return (
    new Date(Date.UTC(DP[0], DP[1]-1, DP[2], DP[3], DP[4], DP[5], DP[6]))
  );
}

function  versionRecord( verProps )
{ //  Constructor for  versionRecord Object
  this.id       = verProps[0];
  this.createdDate    = dateFromStringISO8601( verProps[4] );
  this.nodeRef       = verProps[1];
  this.name       = verProps[2];
  this.type       = verProps[3];
  this.creator       = verProps[5];
  this.versionlabel    = verProps[6];
  this.description    = verProps[9];
  this.url       = verProps[8];
  this.majorVersion   = (verProps[7]  == "true" ? true : false);
  this.versionable   = (verProps[10] == "true" ? true : false);
  this.modified    = dateFromStringISO8601( verProps[11] );
  this.size       = Number(verProps[12]);
}

//  Return array of  versionRecord Objects (most recent first)
function versionHist(doc) {
  var  versionList = new Object();
  versionList.versionCount = 0;
  if  ( doc.hasAspect("cm:versionable") )  {
    doc.processTemplate( vHistory() ).split( "\\\\%%\\\\" ).forEach(
   function(element, index, array) {
     versionList[index] = new versionRecord(element.split("\\\\\\\\"));
     versionList.versionCount += 1;} )
    return  versionList;     //  An array of  versionRecord Objects
  } else  return null;
}

//  Return  versionRecord  of current version
function versionRec(doc) {
  if  ( doc.hasAspect("cm:versionable")  &&
     ! isNull( doc.properties["cm:versionLabel"]) &&
     doc.properties["cm:versionLabel"].length > 0 )  {
    var versionLabel = doc.properties["cm:versionLabel"];
    var verRecs =
      doc.processTemplate( vHistory( versionLabel) ).split( "\\\\%%\\\\"
   ).map(
     function(element, index, array)  {
      return element.split( "\\\\\\\\" ) }
   ).filter(
     function(element, index, array)  {
      return ( element[6] == versionLabel ) }
   ) ;
    if  ( verRecs.length >= 1 ) 
      return  new versionRecord( verRecs[0] );
  };
  return  null;
}

//  Return  versionRecord : -1 is most recent,  0 is first version
function versionRec2(doc, verLabel) {
  if  ( doc.hasAspect("cm:versionable") )  {
    if  ( isNull(verLabel)  &&
     ! isNull( doc.properties["cm:versionLabel"]) &&
     doc.properties["cm:versionLabel"].length > 0 ) 
      verLabel = doc.properties["cm:versionLabel"];     //  current version
    var verRecs =
      doc.processTemplate( vHistory() ).split( "\\\\%%\\\\" ).map(
     function(element, index, array)  {
      return element.split( "\\\\\\\\" ) } );
    if  ( verRecs.length >= 1 )  {
      if  ( verLabel < 0 )        //  start from most recent
     return  new versionRecord( verRecs[ -verLabel - 1 ] );
      else if  ( verLabel == 0 )     //  start from oldest at end of array
     return  new versionRecord( verRecs[ verRecs.length - 1 - verLabel ] );
      else {              //  match  verLabel
     verRecs = verRecs.filter(
     function(element, index, array)  {
      return ( element[6] == verLabel ) } ) ;
     if  ( verRecs.length >= 1 )
     return  new versionRecord( verRecs[0] );
  } } };
  return  null;
}

louise
Champ in-the-making
Champ in-the-making
hi sacco,

that is lifesaver for me, thanks! Smiley Happy


"versionHistory":[
    <#list node.versionHistory as ver>
            {   "versionLabel":"${ver.versionLabel}",
                <#if ver.name??>"name":"${ver.name}",</#if>
                <#if ver.createdDate??>"createdDate":"${ver.createdDate?date}",</#if>
                <#if ver.description??><#if ver.description!="">"description":"${ver.description}",</#if></#if>
                <#if ver.url??>"url":"${ver.url}",</#if>
                <#if ver.frozenNodeId??>"frozenNodeId":"${ver.frozenNodeId}",</#if>            
                <#if ver.nodeRef??>"nodeRef":"${ver.nodeRef}",</#if>
                "creator":"${ver.creator}"
            }<#if ver_has_next>,</#if>
    </#list>
]

sacco
Champ in-the-making
Champ in-the-making
hi sacco,
that is lifesaver for me, thanks! Smiley Happy

You're welcome.  Glad it helps.

I've made a very slight change to the function  dateFromStringISO8601( dateString ) 
since I posted it (but the original version will also work).


function  dateFromStringISO8601( dateString )  {
  var DS = dateString.split("[-:T .]", 9);
  var DP = DS.slice( 0, 7).map( Number );
  return (
    new Date(Date.UTC(DP[0], DP[1]-1, DP[2], DP[3], DP[4], DP[5], DP[6]))
  );
}