Migration technique

  • Pour permettre la création d'une fiche utilisateur depuis le service d'inscription, il faut rajouter l'action de workflow 1111 dans le workflow des utilisateurs (fichier WEB-INF/param/workflows/user.xml)

    <action id="1111" name="plugin.user-directory:WORKFLOW_ACTION_CREATE_ACCOUNT">
                <pre-functions>
                    <function type="avalon">
                        <arg name="role">org.ametys.web.workflow.CreateContentFunction</arg>
                    </function>
                    <function type="avalon">
                        <arg name="role">org.ametys.cms.workflow.EditContentFunction</arg>
                    </function>
                </pre-functions>
                <results>
                    <unconditional-result old-status=" " status=" " step="3" />
                </results>
                <post-functions>
                    <function type="avalon">
                        <arg name="role">org.ametys.cms.workflow.SetCurrentStepIdAndNotifyFunction</arg>
                    </function>
                    <function type="avalon">
                        <arg name="role">org.ametys.cms.workflow.CreateVersionFunction</arg>
                    </function>
                    <function type="avalon">
                        <arg name="role">org.ametys.web.workflow.ValidateContentFunction</arg>
                    </function>
                    <function type="avalon">
                        <arg name="role">org.ametys.cms.workflow.ValidationStepFunction</arg>
                    </function>
                </post-functions>
    </action>
  • Relation entité et utilisateurs de l'annuaire

    Avant de commencer la migration, veuillez vous assurer que vous avez fait la migration suivante : plugin-contentIO

    Action de synchronisation des utilisateurs :

    On a rajouté un nouveau paramètre pour la synchronisation des entités (Source SQL des entités).

    Ce paramètre est : 'Action de synchronisation des utilisateurs'.
    Le paramètre par défaut est 800. Dans la plupart des cas, il faut laisser 800.

    Il vous faut donc pour chaque synchronisation de contenu de type "Source SQL des entités" cliquer sur 'Modifier' puis sur 'Enregistrer et fermer' pour prendre en compte ce nouveau paramètre.

    Nouveau cycle de vie pour les utilisateurs :

    Un nouveau cycle de vie pour les utilisateurs a été rajouté ici

    Il est conseillé de passer tous vos contenus utilisateurs sur ce cycle de vie. Voir la documentation

    Ensuite, il faut définir la clé i18n associée pour lui donner un nom dans WEB-INF/i18n/applications.xml :

    <message key="WORKFLOW_user">Cycle de vie des utilisateurs</message>                 

    Puis passer le script de migration suivant :

    Attention, si vous aviez déjà définie un cycle de vie différent pour les utilisateurs (autre que le cycle de vie 'contentio'), il faut adapter ce script et changer le nom du worfklow (variable defaultWorkflowName)

                
     var defaultWorkflowName = "contentio";                
     var contentTypeEP = serviceManager.lookup('org.ametys.cms.contenttype.ContentTypeExtensionPoint');                
                    
     var request = "@ametys-internal:contentType='org.ametys.plugins.userdirectory.Content.user'";                
     contentTypeEP.getSubTypes('org.ametys.plugins.userdirectory.Content.user').forEach(function(contentTypeId) {                
         request += " or @ametys-internal:contentType='" + contentTypeId + "'"                
     });                
                    
     var qm = session.getWorkspace().getQueryManager();                
     var query = qm.createQuery("//element(*, ametys:content)[" + request + "]", javax.jcr.query.Query.XPATH);                
     var nodes = query.execute().getNodes();                
                    
     var nbUserChanged = 0;                
     while (nodes.hasNext())                
     {                
         var content = nodes.next();                
         if (content.hasNode("ametys-internal:workflows"))                
         {                
             var workflows = content.getNode("ametys-internal:workflows");                
             var workflowNodes = workflows.getNodes();                
                    
             var hasChanged = false;                
             while (workflowNodes.hasNext())                
             {                
                 var workflowNode = workflowNodes.next();                
                 var workflowName = workflowNode.getProperty("oswf:workflowName").getString();                
                 if (workflowName == defaultWorkflowName)                
                 {                
                     workflowNode.setProperty("oswf:workflowName", "user");                
                     hasChanged = true;                
                 }                
             }                
    
             if (hasChanged)                
             {                
                 content.save();                
                 nbUserChanged++;                
             }                
         }                
     }                
                    
     print(nbUserChanged + " contenu(s) 'utilisateur' changé(s)");                       

    Il vous reste plus qu'à modifier la synchronisation des contenus de vos utilisateurs en définissant le bon cycle de vie associé :

     

    Cycle de vie pour les entités : 

    Vous pouvez supprimer l'action 22 de votre fichier de workflow (WEB-INF/param/workflows/udorgunit.xml). 

    Nouveau champs pour le contenu 'utilisateur' :

    On a maintenant un lien bi-directionnel entre les entités et les utilisateurs. Pour cela, on a rajouté une donnée "orgunits" dans le type de contenu org.ametys.plugins.userdirectory.Content.user.xml :

    <cms:metadata name="orgunits" invert="users/user" type="content" contentType="org.ametys.plugins.userdirectory.Content.udorgunit" multiple="true">         
       <label i18n="true">PLUGINS_USER_DIRECTORY_CONTENT_TYPE_ORGUNITS_LABEL_TITLE</label>         
       <description i18n="true">PLUGINS_USER_DIRECTORY_CONTENT_TYPE_ORGUNITS_LABEL_DESC</description>         
     </cms:metadata>         

    Dans votre projet, votre type de contenu 'utilisateur' étend celui là. Il faudra donc rajouter cette donnée dans tous les metadataSet de votre type de contenu.

  • Type de contenu Utilisateur

    Le type abstrait "Utilisateur" a changé.
    Il apporte maintenant la donnée "user" qui est de type "user".

    Pour les projets qui ont défini leur propre type de contenu "utilisateur" qui étend "org.ametys.plugins.userdirectory.Content.user", il faudra changer les metadataset du contenu pour prendre en compte la donnée "user" :

    • Il faut surtout la positionner sur le metadataset "creation" en édition.
    • Et éviter de la positionner sur les autres metadataset en édition.

    Les SCC

    Si les utilisateurs de votre annuaire sont liés aux utilisateurs du CMS :

    • Changer la définition de vos SCC dans l'administration :

      • Si c'est une "Source de données SQL", sélectionner à la place "Annuaire des utilisateurs : entités depuis une source de données SQL" et renseigner les champs
      • Si c'est une "Source de données LDAP", sélectionner à la place "Annuaire des utilisateurs : entités depuis une source de données LDAP" et renseigner les champs
      • Si c'est une "Annuaire des utilisateurs : utilisateurs depuis une population Ametys", juste modifier et enregistrer.

    Lorsque vous allez changer le type de la SCC, certains paramètres vont se réinitialiser. Pour voir les anciens paramètres, vous pouvez regarder le fichier "synchronizable-collection.xml" dans le dossier /data/config.
    Ce fichier sera écrasé au moment où vous sauvegardez.

    • Passer le script de migration suivant en paramétrant :
      • Le type de contenu à migrer
      • L'identifiant de la SCC
      • La donnée du contenu qui porte le champs unique du contenu (la plupart du temps c'est login)
    var contentType = "org.ametys.plugin.defaultud.Content.uduser"; // TODO set this field              
      var sccId = "utilisateurs"; // TODO set this field              
      var fieldId = "login"; // TODO set this field        
    
      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 qm = session.getWorkspace().getQueryManager();              
      var query = qm.createQuery("//element(*, ametys:content)[@ametys-internal:contentType='" + contentType + "' "              
      + "and @ametys-internal:scc = '" + sccId + "']", javax.jcr.query.Query.XPATH);              
      var nodes = query.execute().getNodes();              
    
      var nbContent = 0;              
      while (nodes.hasNext())              
      {              
        var content = nodes.next();              
                  
        if (content.isLocked())              
        {              
          unlock(content);              
        }              
                  
        content.setProperty("ametys:uniqueId", content.getProperty("ametys:" + fieldId).getString());              
        content.save();              
                  
        nbContent++;              
      }              
    
      print(nbContent + " contenu(s) changé(s)");           
    
      queryPage = qm.createQuery("//element(*, ametys:defaultPage)[@ametys-internal:virtual ='org.ametys.plugins.userdirectory.page.VirtualUserDirectoryPageFactory']", javax.jcr.query.Query.XPATH);          
      var nodePages = queryPage.execute().getNodes();          
      var nbPage = 0;          
      while (nodePages.hasNext())          
      {          
        var page = nodePages.next();          
        var metadata = page.getProperty("ametys:user-directory-root-classification-metadata").getString();          
              
        if (metadata == fieldId)          
        {          
          page.setProperty("ametys:user-directory-root-classification-metadata", "uniqueId");          
          page.save();          
              
          nbPage++;          
        }          
      }          
              
      print(nbPage + " page(s) changée(s)");                                
    • Relancer une synchronisation de contenu pour finaliser la migration.

     

    Le UserXSLTHelper

    Il est fort probable que dans vos projet, vous ayez créé votre propre helper XSLT pour surcharger la méthode getCurrentUserContent.
    Vous pouvez maintenant supprimer cette surcharge et utiliser la méthode noyau getCurrentUserContent du helper org.ametys.plugins.userdirectory.transformation.xslt.UserXSLTHelper.

    Il faudra aussi bien penser à remettre ce helper noyau dans vos XSL à la place du helper projet

    De plus, il y a surement une condition de workflow qui a été créé dans votre projet pour faire appel à votre Helper personnalisé (cette condition est souvent appelée CheckCurrentUserContentCondition)
    Elle n'est plus utile non plus, vous pouvez la supprimer (avec sa déclaration dans le plugin.xml)

    Et vous pouvez à nouveau appeler la condition noyau org.ametys.plugins.userdirectory.workflow.CheckCurrentUserContentCondition.