Technical migration manual from version 2.1.x to version 2.2.x or 2.3.x


  1. Data model
    1. Teaching organization
    2. Multiple course attachments
  2. Workflow
  3. Export CDM-fr internships

Data model

Teaching organization

To be consistent with the Pedagogical Elements, the 5 checkboxes for Training content: Initial Training, Continuing Training, Non-Diploma Continuing Training, Work-linked Training and Vocational Training have been grouped together in a"Teaching Organization" multiple-choice list presenting the 5 options.

To migrate existing content, the following script must be run in the workspace repository console:

importClass(org.ametys.plugins.repository.RepositoryConstants);
var unlock = function(node)
{
    var lockToken = node.getProperty(RepositoryConstants.METADATA_LOCKTOKEN).getString();
      
    var lockManager = node.getSession().getWorkspace().getLockManager();
      
    lockManager.addLockToken(lockToken);
      
    lockManager.unlock(node.getPath());
      
    // Remove residual properties
    node["setProperty(java.lang.String,javax.jcr.Value)"](RepositoryConstants.METADATA_LOCKTOKEN, null);
    node["setProperty(java.lang.String,javax.jcr.Value)"](RepositoryConstants.METADATA_LOCKOWNER, null);
      
    node.getSession().save();
}
var migrate = function(node, propName, value, values, values_remote)
{
    var sync = false;
    
    var localValue = null;
    var remoteValue = null;
    
    if (node.hasProperty(propName) && node.getProperty(propName).getBoolean())
    {
    	// Stocker la valeur locale.
        localValue = value;
    }
    if (node.hasProperty(propName + '_remote') && node.getProperty(propName + '_remote').getBoolean())
    {
    	// Remplir le tableau des valeurs synchro et stocker la valeur synchro.
        values_remote.push(value);
        remoteValue = value;
    }
    if (node.hasProperty(propName + '_sync') && node.getProperty(propName + '_sync').getBoolean())
    {
    	// Le champ est synchronisé : mettre dans la nouvelle valeur locale la valeur synchronisée.
        if (remoteValue != null)
        {
        	values.push(remoteValue);
    	}
        
        sync = true;
    }
    else
    {
    	// Le champ n'est pas synchronisé : recopier la valeur locale.
        if (localValue != null)
        {
        	values.push(localValue);
    	}
    }
     
    return sync;
}
var qm = session.getWorkspace().getQueryManager();
var query = qm.createQuery("//element(*, ametys:content)[@ametys-internal:contentType = 'org.ametys.plugins.odf.Content.program' or @ametys-internal:contentType = 'org.ametys.plugins.odf.Content.subProgram']", javax.jcr.query.Query.XPATH);
var nodes = query.execute().getNodes();
var all_synchronized_props = [];
var nodeCount = 0;
while (nodes.hasNext())
{
    var node = nodes.next();
     
    var values = [];
    var values_remote = [];
    var sync = true;
    
    // On synchronise le nouveau champ si les 5 champs étaient synchronisés.
    sync = migrate(node, 'ametys:initialEducation', '1', values, values_remote) && sync;
    sync = migrate(node, 'ametys:continuingEducation', '2', values, values_remote) && sync;
    sync = migrate(node, 'ametys:noDegreeContinuingEducation', '3', values, values_remote) && sync;
    sync = migrate(node, 'ametys:apprenticeship', '4', values, values_remote) && sync;
    sync = migrate(node, 'ametys:vocationalEducation', '5', values, values_remote) && sync;
     
    if (node.isLocked())
    {
        unlock(node);
    }
     
    node["setProperty(java.lang.String,java.lang.String[])"]('ametys:formofteachingOrg', values);
    node["setProperty(java.lang.String,java.lang.String[])"]('ametys:formofteachingOrg_remote', values_remote);
    node["setProperty(java.lang.String,boolean)"]('ametys:formofteachingOrg_sync', sync);
     
    nodeCount++;
}
session.save();
println(nodeCount + " contenus formation ont été migrés.\n");

For content whose checkboxes were not all synchronized, the synchronization status will be lost. At the end of the migration, script will display the content concerned in the "Standard output" tab.

Multiple course attachments

Files to download on a route become multiple.

Run the following script to migrate existing attachments:

var query = session.getWorkspace().getQueryManager().createQuery("//element(*, ametys:defaultContent)[@ametys-internal:contentType = 'org.ametys.plugins.odf.Content.subProgram']", javax.jcr.query.Query.XPATH);
  
var nodes = query.execute().getNodes();
   
var count = 0;
while (nodes.hasNext())
{
   var program = nodes.next();
   
   if (program.hasNode("ametys:attachment") && !program.hasNode("ametys:attachments"))
   {
       var attachNode = program.getNode("ametys:attachment");
       var entryNode = program.addNode("ametys:attachments", "ametys:compositeMetadata").addNode("ametys:1", "ametys:compositeMetadata");
       // Move node
       attachNode.getSession().move(attachNode.getPath(), entryNode.getPath() + "/ametys:attachment");
      
       program.save();
       count++;
   } 
}
 
println(count + " attachments have been moved");

If you have overloaded the "subProgram" content definition(WEB-INF/param/content-types/_override/*.xml), remember to change the references to the "ametys:attachment" metadata to:

<cms:metadata-ref name="attachments">
    <cms:metadata-ref name="attachment"/>
    <cms:metadata-ref name="attachment-text"/>
</cms:metadata-ref>

 

Workflow

If your appplication ODF uses plugin ODF -Sync to synchronize courses with an apogee database or with CDMfr / ROF files, you must add the following two workflow actions in the section <initial-actions> file WEB-INF/params/workflow-program.xml

<initial-actions>
	[...]
    <action id="110" name="plugin.odf:WORKFLOW_ACTION_CREATE">
        <pre-functions>
        	<function type="avalon">
            	<arg name="role">org.ametys.odf.workflow.CreateSubProgramFunction</arg>
            </function>
		</pre-functions>
        <results>
        	<unconditional-result old-status=" " status=" " step="0" />
      	</results>
    </action>
	<action id="120" name="plugin.odf:WORKFLOW_ACTION_CREATE">
         <pre-functions>
         	<function type="avalon">
            	<arg name="role">org.ametys.odf.workflow.CreateContainerFunction</arg>
			</function>
		</pre-functions>
        <results>
        	<unconditional-result old-status=" " status=" " step="0" />
        </results>
	</action>
</initial-actions>

Export CDM-fr internships

Additional information on internships and work placements abroad (enumerated value for compulsory or optional + duration) is now exported to CDM-fr.

For your information, here is an example of an extract from the CDMfr concerning this information:

<infoBlock userDefined="ametys-extension">
   <extension>
        <ametys-cdm:training>
          	<ametys-cdm:trainingInfo value="internship_mandatory">Obligatoire</ametys-cdm:trainingInfo>
          	<ametys-cdm:trainingDuration>6 mois</ametys-cdm:trainingDuration>
          	<ametys-cdm:trainingAbroadInfo value="internship_possible">Possible</ametys-cdm:trainingAbroadInfo>
          	<ametys-cdm:trainingAbroadDuration>3 à 6 mois</ametys-cdm:trainingAbroadDuration>
        </ametys-cdm:training>
	</extension>
</infoBlock>

In order to export this information correctly, please add to the WEB-INF/param/odf/intership file .xml the CDMfr label for each value listed:

<items i18n-catalog="application"> 
    <item code="internship_possible" i18n-key="APPLICATION_ODF_INTERNSHIP_POSSIBLE" cdmValue="Possible"/>
    <item code="internship_mandatory" i18n-key="APPLICATION_ODF_INTERNSHIP_MANDATORY" cdmValue="Obligatoire"/>
</items>

 

 

Back to top