• Action de workflow pour la création d'une fiche utilisateur via le service d'inscription

      Action de workflow pour la création d'une fiche utilisateur via le service d'inscription

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

      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.

    • Relation utilisateur du CMS et contenu utilisateur

      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.

    • Suppression des relations entre utilisateurs et entités

      Suppression des relations entre utilisateurs et entités

      Une nouvelle action du cycle de vie est à rajouter dans vos fichiers de cycles de vie "utilisateurs" et "entités". Cette action est appelée lors de la suppression de relations lors qu'on supprime un contenu de l'annuaire.

      Il faut donc ajouter l'action commune 200 ci-dessous dans vos fichier de cycle de vie :

      • WEB-INF/param/workflows/udorgunit.xml (exemple)
      • WEB-INF/param/workflows/user.xml (exemple)

      Ajouter l'action suivante dans la section <common-actions>

      <!-- Edit references -->     
      <action id="200" name="plugin.user-directory:WORKFLOW_ACTION_EDIT_REFERENCES">     
          <restrict-to>     
              <conditions type="AND">     
                  <condition type="avalon">     
                      <arg name="role">org.ametys.cms.workflow.LockCondition</arg>     
                  </condition>     
                  <condition type="avalon">     
                      <arg name="role">org.ametys.plugins.contentio.synchronize.workflow.ValidateMetadataSynchronizeCondition</arg>     
                      <arg name="validation-step">3</arg>     
                  </condition>     
              </conditions>     
          </restrict-to>     
          <results>     
              <result old-status=" " status=" " step="1">     
                  <conditions type="AND">     
                      <condition type="avalon">     
                          <arg name="role">org.ametys.cms.workflow.ContentCurrentStepCondition</arg>     
                          <arg name="step">1</arg>     
                      </condition>     
                  </conditions>     
                  <post-functions>     
                      <function type="avalon">     
                          <arg name="role">org.ametys.cms.workflow.SetCurrentStepIdAndNotifyFunction</arg>     
                      </function>     
                  </post-functions>     
              </result>     
              <result old-status=" " status=" " step="2">     
                  <conditions type="AND">     
                      <condition type="avalon">     
                          <arg name="role">org.ametys.cms.workflow.ContentCurrentStepCondition</arg>     
                          <arg name="step">2</arg>     
                      </condition>     
                  </conditions>     
                  <post-functions>     
                      <function type="avalon">     
                          <arg name="role">org.ametys.cms.workflow.SetCurrentStepIdAndNotifyFunction</arg>     
                      </function>     
                  </post-functions>     
              </result>     
              <result old-status=" " status=" " step="3">     
                  <conditions type="AND">     
                      <condition type="avalon">     
                          <arg name="role">org.ametys.cms.workflow.ContentCurrentStepCondition</arg>     
                          <arg name="step">3</arg>     
                      </condition>     
                  </conditions>     
                  <post-functions>     
                      <function type="avalon">     
                          <arg name="role">org.ametys.plugins.contentio.synchronize.workflow.ValidateSynchronizedContentFunction</arg>     
                      </function>     
                      <function type="avalon">     
                          <arg name="role">org.ametys.cms.workflow.ValidationStepFunction</arg>     
                      </function>     
                  </post-functions>     
              </result>     
              <unconditional-result old-status=" " status=" " step="1"/>     
          </results>     
          <post-functions>     
              <function type="avalon">     
                  <arg name="role">org.ametys.cms.workflow.ExtractOutgoingReferencesFunction</arg>     
              </function>     
          </post-functions>     
      </action>     

      puis ajoutez sa référence pour chaque état  (step) du workflow :

      <step id="X" name="....">
          <actions>
              <!-- Edit Action -->
              <common-action id="2" />
              // ...  
              <!-- Edit references -->
              <common-action id="200" />
              <!-- Synchronize Action -->
              <common-action id="800" />
          <actions>
      </step>
Retour en haut