Correction of parent/child links for Apogée


This page should only be applied if the application asks you to pass the manual migration plugin.odfsync.import.apogee.jcr.20210929T0000
Once you have passed the manual migration, you must restart Ametys to continue the automatic migration process.

See also the technical migration here in the section Fixing parent/child links for Apogee.

This script manual migration detects content whose current state is validated, but whose children in their Live version are different from their current version. They are then returned to draft status.

This also resets content in validated state that does not have a defunct Live version to draft status.

On the following script , set the handle variable to false first, to check the changes that will be made.
If you're happy with this, set handle to true, and the changes will be made.
Otherwise, ignore the manual migration with the script at the end of this content (you'll still need to restart).

The script below must be run with a user who has content modification rights ODF.

// Set to true to execute
let handle = false;

// Imports
const Optional = Java.type("java.util.Optional");
const Stream = Java.type("java.util.stream.Stream");
const Collectors = Java.type("java.util.stream.Collectors");

// Logger
const logger = Ametys.getLogger("org.ametys.core.migration.MigrationExtensionPoint.odf2995.inconsistent.live");

logger.info("Start migrating inconsistent live contents");

let versionManager = Repository.session.getWorkspace().getVersionManager();

let count = 0;
let condition = "@ametys-internal:contentType='org.ametys.plugins.odf.Content.program'";
condition += " or @ametys-internal:contentType='org.ametys.plugins.odf.Content.orgunit'";
condition += " or @ametys-internal:contentType='org.ametys.plugins.odf.Content.container'";
condition += " or @ametys-internal:contentType='org.ametys.plugins.odf.Content.course'";
condition += " or @ametys-internal:contentType='org.ametys.plugins.odf.Content.subProgram'";
condition += " or @ametys-internal:contentType='org.ametys.plugins.odf.Content.courseList'";
Repository.query("//element(*, ametys:content)[" + condition + "]").forEach(
    content =>
    {
        if (content.getCurrentStepId() == 3)
        {
            if (hasInconsistentLive(content))
            {
                count++;
                logger.info("[" + content.getId() + "][" + content.getTitle() + "] Set the content workflow state to draft");
                if (handle)
                {
                    Content.doWorkflowAction(content, 2);
                }
            }
        }
    }
);

if (handle)
{
    Migration.jcr.addVersion("plugin.odfsync.import.apogee.jcr", "20210929T0000", "Manual migration for ODF-2995 on Apogée SCC");
}

logger.info(count + " content(s) migrated");
logger.info("End migrating inconsistent live content");

function hasInconsistentLive(content)
{
    let versionHistory = versionManager.getVersionHistory(content.getNode().getPath());
    if (!versionHistory.hasVersionLabel("Live"))
    {
        logger.warn("[" + content.getId() + "][" + content.getTitle() + "] This content has a validate state but no Live version");
        return true;
    }

    let childAttribute = getChildAttribute(content);
    
    let currentValues = Optional.of(content)
        .map(c => c.getValue(childAttribute))
        .map(v => Stream.of(v))
        .orElseGet(() => Stream.empty())
        .map(v => v.getContentId())
        .collect(Collectors.toList());
  
  let versionNode = versionHistory.getVersionByLabel("Live").getFrozenNode();
    if (versionNode.hasProperty("ametys:" + childAttribute))
    {
        for (let value of versionNode.getProperty("ametys:" + childAttribute).getValues())
        {
            if (!currentValues.remove(value.getString()))
            {
                return false;
            }
        }
    }
    
    return currentValues.size() > 0;
}

function getChildAttribute(content)
{
    switch (content.getTypes()[0])
    {
        case "org.ametys.plugins.odf.Content.course": return "courseLists";
        case "org.ametys.plugins.odf.Content.courseList": return "courses";
        case "org.ametys.plugins.odf.Content.orgunit": return "childOrgUnits";
        default: return "childProgramParts";
    }
}

Ignore manual migration

If the target version is 4.6 or lower :

Migration.jcr.addVersion("plugin.odfsync.import.apogee.jcr", "20210929T0000", "Ignore Manual migration for ODF-2995 on Apogée SCC");

If the target version is 4.7 or higher :

Migration.addVersion("plugin.odfsync.import.apogee.jcr", null, null, "20210929T0000", "Ignore Manual migration for ODF-2995 on Apogée SCC");
Back to top