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:
Oops!
Copy to clipboard failed. Open the code and copy it manually.
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");
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:
Oops!
Copy to clipboard failed. Open the code and copy it manually.
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");
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:
Oops!
Copy to clipboard failed. Open the code and copy it manually.
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
Oops!
Copy to clipboard failed. Open the code and copy it manually.