• Workflow action for creating a user record via the registration service

      Workflow action for creating a user record via the registration service

      To enable the creation of a user file from the registration service, workflow action 1111 must be added to the user workflow (file 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

      Relationship between entities and directory users

      Before starting the migration, please make sure that you have done the following migration: plugin-contentIO

      User synchronization action :

      We've added a new parameter for entity synchronization (Source SQL entities).

      This parameter is: 'User synchronization action'.
      The default setting is 800. In most cases, leave 800.

      For each synchronization of content of type "Source SQL of entities", click on "Modify" and then on "Save and close" to take this new parameter into account.

      New user lifecycle :

      A new user lifecycle has been added here

      We recommend that you run all your user content through this lifecycle. View documentation

      Next, define the associated i18n key and give it a name in WEB-INF/i18n/applications.xml :

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

      Then go to script to migrate:

      Warning: if you have already defined a different lifecycle for users (other than the 'contentio' lifecycle), you must adapt this script and change the worfklow name (defaultWorkflowName variable).

                   
       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)");                        

      All that's left is to modify the synchronization of your users' content by defining the right associated life cycle:

       

      Lifecycle for entities : 

      You can delete action 22 from your workflow file (WEB-INF/param/workflows/udorgunit.xml). 

      New fields for 'user' content:

      We now have a bi-directional link between entities and users. To achieve this, we have added an "orgunits" data item to the content type 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>          

      In your project, your 'user' content type extends this one. You'll need to add this data to all your content type's metadataSets.

    • CMS user relations and user content

      User content type

      The "User" abstract type has changed.
      It now provides the "user" data, which is of type "user".

      For projects that have defined their own "user" content type that extends "org.ametys.plugins.userdirectory.Content.user", it will be necessary to change the content metadataset to take the "user" data into account:

      • Above all, you need to position it on the "creation" metadataset in editing.
      • And avoid positioning it on other metadatasets in editing.

      SCC

      If your directory users are linked to CMS users:

      • Change the definition of your SCC in the administration :

        • If it's a "Data source SQL", select instead "User directory: entities from a data source SQL" and fill in the fields.
        • If it's a "Data source LDAP", select instead "User directory: entities from a data source LDAP" and fill in the fields.
        • If it's a "User directory: users from a population Ametys", just edit and save.

      When you change the type of SCC, some settings will be reset. To see the old settings, you can look at the "synchronizable-collection.xml" file in the /data/config folder.
      This file will be overwritten when you save.

      • Go to script and set the following parameters:
        • The type of content to be migrated
        • SCC identifier
        • The content data which carries the content's unique field (most of the time this is 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)");                                
      • Relaunch content synchronization to finalize migration.

       

      The UserXSLTHelper

      Chances are that in your projects you have created your own helper XSLT to override the getCurrentUserContent method.
      You can now remove this override and use the getCurrentUserContent core method of the helper org.ametys.plugins.userdirectory.transformation.xslt.UserXSLTHelper.

      You should also remember to put this kernel helper back in your XSL in place of the project helper.

      What's more, there's probably a workflow condition that's been created in your project to call up your custom Helper (this condition is often called CheckCurrentUserContentCondition)
      It's no longer useful either, so you can delete it (along with its declaration in plugin.xml)

      And you can call up the kernel condition again org.ametys.plugins.userdirectory.workflow.CheckCurrentUserContentCondition.

    • Remove relationships between users and entities

      Remove relationships between users and entities

      A new lifecycle action must be added to your "users" and "entities" lifecycle files. This action is called up when relationships are deleted from the directory.

      You therefore need to add the common action 200 below to your lifecycle files:

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

      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>     

      then add its reference for each workflow state (step):

      <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>
Back to top