Par cohérence avec les Eléments Pédagogiques, les 5 cases à cocher des contenus Formation : Formation initiale, Formation continue, Formation continue non diplômante, Formation 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 :
Oups !
La copie dans le presse papier a échouée. Ouvrez le code et copier-le manuellement.
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");
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");
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:
Oups !
La copie dans le presse papier a échouée. Ouvrez le code et copier-le manuellement.
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");
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");
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:
Oups !
La copie dans le presse papier a échouée. Ouvrez le code et copier-le manuellement.
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
Oups !
La copie dans le presse papier a échouée. Ouvrez le code et copier-le manuellement.
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:
Oups !
La copie dans le presse papier a échouée. Ouvrez le code et copier-le manuellement.
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 :
Oups !
La copie dans le presse papier a échouée. Ouvrez le code et copier-le manuellement.