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


  1. Data model
    1. Organisation de l'enseignement
    2. Pièces jointes multiples sur les parcours
  2. Workflow
  3. Export CDM-fr des stages

Data model

Organisation de l'enseignement

Par cohérence avec les Eléments Pédagogiques, les 5 cases à cocher des contenus Formation : Formation initialeFormation continueFormation continue non diplômanteFormation en alternance et Formation professionnelle ont été regroupées en une liste à choix multiple "Organisation de l'enseignement" présentant les 5 options.

Pour migrer les contenus existants, le script suivant doit être exécuté dans la console du workspace repository :

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");

Pour les contenus dont toutes les cases à cocher n'étaient pas synchronisées, le statut de synchronisation sera perdu. A la fin de la migration, le script affichera les contenus concernés dans l'onglet "Sortie standard".

Pièces jointes multiples sur les parcours

Les fichiers à télécharger sur un parcours deviennent multiple.

Exécutez le script suivant pour migrer les pièces jointes existantes:

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");

Si vous avez surchargé la définition des contenus "subProgram" (WEB-INF/param/content-types/_override/*.xml), pensez à modifier les références à la métadonnée "ametys:attachment" qui devient:

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

 

Workflow

Si votre appplication ODF utilise le plugin ODF-Sync pour la synchronisation des formations avec une base apogée ou avec des fichiers CDMfr / ROF, vous devez rajouter les deux actions de workflow suivantes dans la section <initial-actions> du fichier 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 des stages

Les informations supplémentaires sur les stages et stages à l'étranger (valeur énumérée sur le caractère obligatoire ou facultatif + durée) sont désormais exporté dans le CDM-fr.

Pour information, voici un exemple d'extrait du CDMfr concernant ces informations:

<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>

Afin d'exporter correctement ces informations, veuillez rajouter dans le fichier WEB-INF/param/odf/intership.xml le libellé CDMfr pour chaque valeur énumérée :

<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