Migration technique et graphique 4.0 vers 4.1


  1. Tableau de compatibilité des plugins
  2. Base de données
  3. Nouveaux paramètres de configuration
  4. Migration technique
    1. Mise à jour des fichiers runtime.xml
    2. Mise à jour des ficheirs de plugins (plugin.xml)
    3. Mise à jour des fichiers workflow
      1. Modification Front-office
      2. Table de référence
      3. Workflow de dépublication
      4. Synchronisation des contenus
    4. Dépendances ivy
    5. Widget "edition.select-page"
    6. Changement d'API (java)
      1. Changement d'API sur ContentHelper
    7. Table de référence
    8. Renderers et converters JS (pour les moteurs de recherche)
    9. Nouvelles icônes et décorateurs
    10. Token d'authentification
  5. Migration graphique
    1. Images redimensionnées
    2. Page de login du CMS
    3. Player HTML5 pour les galerie vidéo et audio
    4. Plugins Zimbra 1.1.0, Exchange 1.1.0, Bluemind 2.1.0
  6. Serveur Solr
  7. Migration des données
    1. Plugin Annuaire de liens 2.2.x

 

Tableau de compatibilité des plugins

Reportez-vous au tableau de compatibilité des plugins et incrémenter les versions de vos plugins (prendre pour chaque plugin la version la plus récente compatible 4.1) : Plugins

Base de données

La table SQL Authentication_Token a changé de structure. Supprimez-la pour qu'elle soit recréée correctement, ou alors modifiez la table pour ajouter la colonne Creation_Date (DATETIME)

MySQL

ALTER TABLE Authentication_Token ADD creation_date datetime;  
ALTER TABLE Authentication_Token ADD last_update_date datetime;  

L'identifiant des droits liés aux tables de référence a été modifié. Passez le script suivant sur la BDD des droits :

Mise à jour de l'identifiant des droits

#Si besoin il faut passer en safe updates  
#SET SQL_SAFE_UPDATES = 0;  
update Rights_ProfileRights set Right_Id='CMS_Rights_ReferenceTables' Where Right_Id='CMS_Rights_SimpleContents';  
update Rights_ProfileRights set Right_Id='CMS_Rights_ReferenceTables_Create' Where Right_Id='CMS_Rights_SimpleContents_Create';  
update Rights_ProfileRights set Right_Id='CMS_Rights_ReferenceTables_Delete' Where Right_Id='CMS_Rights_SimpleContents_Delete';  
update Rights_ProfileRights set Right_Id='CMS_Rights_ReferenceTables_Import' Where Right_Id='CMS_Rights_SimpleContents_Import';  
#SET SQL_SAFE_UPDATES = 1;  

L'affectation des droits sur les tables de référence sont stockés en base de données sous le contexte "/reference-tables", anciennement "/simple-contents".

Vous devez soit réaffecter manuellement vos droits sur ces types de contenus, soit mettre à jour la base de données en utilisant les scripts suivants:

MySQL

#Si besoin il faut passer en safe updates  
#SET SQL_SAFE_UPDATES = 0;  
update Rights_AllowedGroups set Context = CONCAT('/reference-tables', SUBSTR(context, 17, LENGTH(context))) Where Context like '/simple-contents%';  
update Rights_AllowedUsers set Context = CONCAT('/reference-tables', SUBSTR(context, 17, LENGTH(context))) Where Context like '/simple-contents%';  
update Rights_AllowedProfilesAnonym set Context = CONCAT('/reference-tables', SUBSTR(context, 17, LENGTH(context))) Where Context like '/simple-contents%';  
update Rights_AllowedProfilesAnyCon set Context = CONCAT('/reference-tables', SUBSTR(context, 17, LENGTH(context))) Where Context like '/simple-contents%';  
update Rights_DeniedGroups set Context = CONCAT('/reference-tables', SUBSTR(context, 17, LENGTH(context))) Where Context like '/simple-contents%';  
update Rights_DeniedUsers set Context = CONCAT('/reference-tables', SUBSTR(context, 17, LENGTH(context))) Where Context like '/simple-contents%';  
update Rights_DeniedProfilesAnonym set Context = CONCAT('/reference-tables', SUBSTR(context, 17, LENGTH(context))) Where Context like '/simple-contents%';  
update Rights_DeniedProfilesAnyCon set Context = CONCAT('/reference-tables', SUBSTR(context, 17, LENGTH(context))) Where Context like '/simple-contents%';  
#SET SQL_SAFE_UPDATES = 1;  

Derby

update rights_allowedusers set Context = '/reference-tables' || SUBSTR(context, 17, LENGTH(context)) Where Context like '/simple-contents%';  
update rights_allowedgroups set Context = '/reference-tables' || SUBSTR(context, 17, LENGTH(context)) Where Context like '/simple-contents%';  
update rights_allowedprofilesanonym set Context = '/reference-tables' || SUBSTR(context, 17, LENGTH(context)) Where Context like '/simple-contents%';  
update rights_allowedprofilesanycon set Context = '/reference-tables' || SUBSTR(context, 17, LENGTH(context)) Where Context like '/simple-contents%';  
update rights_deniedgroups set Context = '/reference-tables' || SUBSTR(context, 17, LENGTH(context)) Where Context like '/simple-contents%';  
update rights_deniedusers set Context = '/reference-tables' || SUBSTR(context, 17, LENGTH(context)) Where Context like '/simple-contents%';  
update rights_deniedprofilesanonym set Context = '/reference-tables' || SUBSTR(context, 17, LENGTH(context)) Where Context like '/simple-contents%';  
update rights_deniedprofilesanycon set Context = '/reference-tables' || SUBSTR(context, 17, LENGTH(context)) Where Context like '/simple-contents%';  

Nouveaux paramètres de configuration

Au redémarrage de l'application, deux nouveaux paramètres de configuration vous seront demandés :

  • Recherche et indexation > Serveur Solr > Adresse IP de Solr (cms.solr.core.allowedips)
    Entrez l'adresse IP du serveur Solr ou laissez vide pour ne pas protéger les requêtes Solr -> CMS

  • Sites web > Front-offices > Vider le cache complet au démarrage (web.invalidate.focache.scheduler.enabled)
    Permet de vider le cache du site à chaque redémarrage du CMS.
    Si les applications CMS et site sont sur le même serveur, il n'est pas nécessaire de cocher cette case.

Migration technique

Mise à jour des fichiers runtime.xml

Dans le fichier WEB-INF/param/runtime.xml des applications CMS et site, remplacez :

http://www.ametys.org/schema/runtime/runtime-4.0.xsd  

par

http://www.ametys.org/schema/runtime/runtime-4.1.xsd  

Dans le fichier WEB-INF/param/runtime.xml de l'application site uniquement, remplacez :

<workspaces default="site"/>  

par

<workspaces default="site">  
     <theme>  
         <workspace name="admin">ametys-admin-site</workspace>  
     </theme>  
</workspaces>  

Dans le fichier WEB-INF/param/runtime.xml de l'application CMS, vous pouvez supprimer les lignes suivantes de la section <exclude>

<feature>explorer/explorer.other.rights</feature>  
<feature>explorer/explorer.calendar.rights</feature>  
<feature>explorer/explorer.threads.rights</feature>  
<feature>explorer/explorer.calendars</feature>  

 

Enfin, supprimez la ligne qui contient:

<org.ametys.plugins.repository.provider.WorkspaceSelector>...</org.ametys.plugins.repository.provider.WorkspaceSelector>   

 

Mise à jour des ficheirs de plugins (plugin.xml)

Dans l'en-tête

http://www.ametys.org/schema/plugin-2.0.xsd

par

http://www.ametys.org/schema/plugin-4.0.xsd

Mise à jour des fichiers workflow

Modification Front-office

Cette section vous concerne si vous utilisez le plugin de modification front-office (front-edition)

Pour autoriser l'insertion des pièces jointes à un contenu coté front-office, il faut ajouter une action de workflow dans le fichier WEB-INF/param/workflow-edition-fo.xml

Dans l'état (step) 1, rajoutez:

<!--  Edit attachments -->  
<action id="12" name="plugin.default-workflow:WORKFLOW_ACTION_ATTACH">  
    <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.cms.workflow.ContentCheckRightsCondition</arg>  
                <arg name="right">Front_Edition_Access_Right</arg>  
            </condition>  
        </conditions>  
    </restrict-to>  
    <results>  
        <unconditional-result old-status=" " status=" " step="1" />  
    </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>  

Par ailleurs, aucun droit n'était vérifié sur l'édition. Dans l'action n°2, remplacez la condition existante par :

<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.cms.workflow.ContentCheckRightsCondition</arg>  
            <arg name="right">Front_Edition_Access_Right</arg>  
        </condition>  
    </conditions>  
</restrict-to>  

Reportez-vous au fichier workflow-editionfo.xml du template de démo en cas de doute.
https://code.ametys.org/projects/WEB/repos/template-web/browse/webapp/cms/WEB-INF/param/workflow-editionfo.xml?at=refs%2Fheads%2F4.1.x

Table de référence

  • renommer le fichier workflow-simple-content.xml en workflow-reference-table.xml
  • dans ce même fichier, remplacer :
    org.ametys.cms.workflow.CreateSimpleContentFunction
    par
    org.ametys.cms.workflow.CreateReferenceTableContentFunction
  • Dans le fichier workflows.xml, remplacer :
    <workflow name="simple-content" type="file" location="workflow-simple-content.xml"/>
    par
    <workflow name="reference-table" type="file" location="workflow-reference-table.xml"/>

Workflow de dépublication

Dans vos fichiers de workflow, cherchez l'action de dépublication (normalement n°10) et ajoutez la post-fonction org.ametys.cms.workflow.SetCurrentStepIdAndNotifyFunction
L'absence de cette post-fonction était responsable de cette issue https://issues.ametys.org/browse/CMS-8648

<action id="10" name="plugin.default-workflow:WORKFLOW_ACTION_UNPUBLISH">  
    <restrict-to>  
        <conditions type="AND">  
            <condition type="avalon">  
                <arg name="role">org.ametys.cms.workflow.ContentCheckRightsCondition</arg>  
                <arg name="right">Workflow_Rights_Unpublish</arg>  
            </condition>  
            <condition type="avalon">  
                <arg name="role">org.ametys.cms.workflow.LockCondition</arg>  
            </condition>  
            <condition type="avalon">  
                <arg name="role">org.ametys.web.workflow.ContentPublishedCondition</arg>  
            </condition>  
        </conditions>  
    </restrict-to>  
    <pre-functions>  
        <function type="avalon">  
            <arg name="role">org.ametys.web.workflow.UnpublishContentFunction</arg>  
        </function>  
    </pre-functions>  
    <results>  
        <unconditional-result old-status=" " status=" " step="1" />  
    </results>  
    <post-functions>  
        <function type="avalon">  
            <arg name="role">org.ametys.cms.workflow.SetCurrentStepIdAndNotifyFunction</arg>  
        </function>  
    </post-functions>  
</action>  

Synchronisation des contenus

Si vous utilisez le plugin ContentIO et son fichier de workflow workflow-contentio.xml, les actions de synchronisation 810, 820 et 830 ont été rassemblées dans une seule action 800 avec des résultats conditionnels.

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

<!-- Synchronize -->  
<action id="800" name="plugin.contentio:WORKFLOW_ACTION_SYNCHRONIZE">  
 <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>  
</action>  

Puis supprimez les actions 810, 820, et 830 et les remplacer par la référence à l'action 800 : <common-action id="800" />. Attention, veiller à bien ordonner les action et common-action : d'abord lister les common-action ensuite les actions.

Vous pouvez aussi récupérer le fichier workflow-contentio.xml du template de démo si vous n'avez pas apporté de personnalisation à ce fichier.

Cette modification simplifie nos fichiers de workflow, le revers de la médaille c'est que dans l'historique des contenus synchronisés anciennement avec les actions 810, 820 ou 830 vous aurez "Action inconnue" sur les quelques transitions.

Dépendances ivy

Si vous utilisez les espaces projets (plugin workspaces), ajoutez cette ligne dans l'ivy.xml de votre application site uniquement :

<dependency org="org.ametys.plugins" name="workspaces-site" branch="1.0.x" rev="latest.release" conf="site_compile,site->default"/>  

Widget "edition.select-page"

Un paramètre du widget a été renommé, et un nouveau paramètre a fait son apparition.

Cherchez dans tous vos fichiers plugin.xml :

<param name="foSearchModeField">  

et remplacez par :

<param name="enableWithFieldName">ancienne valeur de foSearchModeField</param>  
<param name="enableOnFieldValues">criteria-only</param>  

 

Changement d'API (java)

Changement d'API sur ContentHelper

L'API java de la classe org.ametys.cms.content.ContentHelper a été modifié:

Les méthodes suivantes :

  • getMetadataValue(Content content, String metadataPath, boolean resolveReferences)
  • getMetadataValue(Content content, String metadataPath, boolean resolveReferences, boolean returnNullValues)
  • getMetadataValue(CompositeMetadata metadataHolder, MetadataDefinition definition, String metadataPath, boolean resolveReferences, boolean returnNullValues)
  • getMetadataValues(Content content, String metadataPath, boolean resolveReferences, boolean returnNullValues)

deviennent:

  • getMetadataValue(Content content, String metadataPath, Locale defaultLocale, boolean resolveReferences)
  • getMetadataValue(Content content, String metadataPath, Locale defaultLocale, boolean resolveReferences, boolean returnNullValues)
  • getMetadataValue(CompositeMetadata metadataHolder, MetadataDefinition definition, String metadataPath, Locale locale, boolean resolveReferences, boolean returnNullValues)
  • getMetadataValues(Content content, String metadataPath, Locale defaultLocale, boolean resolveReferences, boolean returnNullValues)

L'argument supplémentaire "defaultLocale" permet de résoudre les métadonnées de type multilingue avec la bonne locale.
Si votre contenu n'est pas un contenu multilingue ou si vous n'utilisez pas de métadonnées de type multilingue, vous pouvez mettre null pour cet argument.

Si vous utilisez cet helper dans les classes java de votre application, faites les modifications nécessaires.

Table de référence

Les types de contenus appelés "simple" deviennent des types de contenus de type "table de référence".
Tous les types de contenus "table de référence" possèdent leur propre outil de recherche accessible depuis le menu "Table de référence".
La notion de contenu simple existe toujours, il s'agit des types de contenus ne possédant que les métadonnées de types simple, sans composite, ni repeater. Une table de référence n'est pas forcément un type de contenu simple.

 

Dans l'ensemble de vos définitions de type de contenus :

1) Recherchez le widget edition.select-simple-content et remplacez-le par edition.select-referencetable-content

2) Remplacez le tag <cms:tag>simple</cms:tag> par <cms:tag>reference-table</cms:tag>

Renderers et converters JS (pour les moteurs de recherche)

Ces fonctions JS ont été déplacées. Si vous définissez des modèles de recherche, alors vous en référencez probablement certaines.

Rechercher dans les fichiers XML Ametys.cms.content.EditContentsGrid.render et remplacer par Ametys.plugins.cms.search.SearchGridHelper.render

Rechercher dans les fichiers XML Ametys.cms.content.EditContentsGrid.convert et remplacer par Ametys.plugins.cms.search.SearchGridHelper.convert

Nouvelles icônes et décorateurs

Dans le template, le fichier default-workflow/plugin.xml a été modifié par l'ajout de <icon-decorator-type> suivant les balises <icon-decorator>. Faire un diff avec le template par exemple pour ajouter ces nouvelles balises. 
 

Token d'authentification

Les token sont maintenant encodés en base 64, les anciens ne sont plus valides.

Il n'y a pas de migration prévue pour les token existants, il faut les révoquer et les recréer.

Migration graphique

Images redimensionnées

Dans tous vos fichier XSL, rechercher l'utilisation de la méthode resolveBoundedImage à 4 arguments resolveBoundedImage(String type, String uri, int maxHeight, int maxWidth)

Dans cette méthode, la hauteur et la largeur étaient inversées par erreur; maintenant c'est maxHeight puis maxWidth. Vérifier vos appels à cette méthode : assurez-vous que la hauteur demandée est bien le 3e argument, et la largeur est le 4e argument.

Vous pouvez faire un rechercher/remplacer dans Eclipse avec :

  • rechercher : resolveBoundedImage\s*\(([^(,)]+|[^,)]+\([^)]+\)[^,)]+),([^(,)]+|[^(,)]*\([^()]*\)[^(,)]*),([^(,)]+|[^(,)]*\([^()]*\)[^(,)]*),([^(,)]+|[^(,)]*\([^()]*\)[^(,)]*)\)
  • remplacer par  : resolveBoundedImage($1,$2,$4,$3)

Pensez à cocher "Regular expression" !

Page de login du CMS

Le fichier WEB-INF/param/login.xsl a été refait.
Ce fichier est facultatif mais si vous l'avez personnalisez dans votre application, repartez de celui du template web https://code.ametys.org/projects/WEB/repos/template-web/browse/webapp/cms/WEB-INF/param/login.xsl?at=4.1.x

En plus il faut modifier les clefs i18n suivantes (catalogue WEB-INF/i18n/application*.xml)

<!-- login.xsl -->  
<message key="LOGIN_SCREEN_INTRO_AMETYS_TITLE">Essayez Ametys</message>  
<message key="LOGIN_SCREEN_INTRO_AMETYS_DESCRIPTION"></message>  
<message key="LOGIN_SCREEN_INTRO_AMETYS_AVAILABLE_IDENTIFIERS">Les identifiants suivants sont disponibles :</message>  
<message key="LOGIN_SCREEN_INTRO_RESOURCES_TITLE">Rejoignez la communauté Ametys</message>  
<message key="LOGIN_SCREEN_INTRO_RESOURCES_DESCRIPTION">Les ressources suivantes vous permettront de trouver la documentation et le support dont vous pourriez avoir besoin.</message>  
<message key="LOGIN_SCREEN_INTRO_RESOURCES_WEBSITE">Site web www.ametys.org</message>  
<message key="LOGIN_SCREEN_INTRO_RESOURCES_DOC">Documentation Wiki Ametys</message>  
<message key="LOGIN_SCREEN_INTRO_RESOURCES_FORUM">Forum de la communauté</message>  
<message key="LOGIN_SCREEN_INTRO_RESOURCES_ISSUES">Signalisation de bugs et demandes d'évolutions</message>  
<message key="LOGIN_SCREEN_INTRO_NETWORKS_TITLE">Suivez-nous sur les réseaux :</message>  
<message key="LOGIN_SCREEN_INTRO_NETWORKS_FACEBOOK">Suivez-nous sur Facebook</message>  
<message key="LOGIN_SCREEN_INTRO_NETWORKS_TWITTER">Suivez-nous sur Twitter</message>  
<message key="LOGIN_SCREEN_INTRO_NETWORKS_GOOGLE_PLUS">Suivez-nous sur Google+</message>  
  
<!-- login.xsl -->  
<message key="LOGIN_SCREEN_INTRO_AMETYS_TITLE">Try Ametys</message>  
<message key="LOGIN_SCREEN_INTRO_AMETYS_DESCRIPTION"></message>  
<message key="LOGIN_SCREEN_INTRO_AMETYS_AVAILABLE_IDENTIFIERS">The following identifiers are available:</message>  
<message key="LOGIN_SCREEN_INTRO_RESOURCES_TITLE">Join the Ametys community</message>  
<message key="LOGIN_SCREEN_INTRO_RESOURCES_DESCRIPTION">The following resources will allow you to find the documentation and support you need:</message>  
<message key="LOGIN_SCREEN_INTRO_RESOURCES_WEBSITE">www.ametys.org website</message>  
<message key="LOGIN_SCREEN_INTRO_RESOURCES_DOC">Ametys wiki documentation</message>  
<message key="LOGIN_SCREEN_INTRO_RESOURCES_FORUM">Community forum</message>  
<message key="LOGIN_SCREEN_INTRO_RESOURCES_ISSUES">Features and issues tracking</message>  
<message key="LOGIN_SCREEN_INTRO_NETWORKS_TITLE">Follow us on social media</message>  
<message key="LOGIN_SCREEN_INTRO_NETWORKS_FACEBOOK">Follow us on Facebook</message>  
<message key="LOGIN_SCREEN_INTRO_NETWORKS_TWITTER">Follow us on Twitter</message>  
<message key="LOGIN_SCREEN_INTRO_NETWORKS_GOOGLE_PLUS">Follow us on Google+</message  

Player HTML5 pour les galerie vidéo et audio

Le plugin multimedia dans sa version 2.1.0 remplace le lecteur Flash par un lecteur HTML5 : Plugin Multimedia v2.1.0 - Nouveautés
Par conséquent, le format FLV n'est plus supporté au profit des formats mp4, ogv, ogg et webm.

Si vous avez des galerie video qui utilise des fichiers FLV, ils faut les migrer vers les formats supportés.
Si vous avez surchargé le rendu de la galerie, il faudra certainement reprendre votre surcharge : Plugin Multimedia - Manuel de migration graphique 2.0.0 vers 2.1.0

Par ailleurs, pour pouvoir visualiser les vidéos ou fichiers audio insérés dans vos contenus en mode "wrappé" (=contenu hors page), vous devez ajouter les CSS et JS apportées par le plugin "mediaelement" dans la XSL du rendu des contenus "wrappés".
Pour cela, pour l'ensemble de vos chartes graphiques, modifiez le fichier skins/[SKIN_NAME]/stylesheets/content/_wrapper/content.xsl, pour y ajouter l'appel aux templates XSL "head-js-mediaelement" et "head-css-mediaelement"

 

<xsl:call-template name="head-js-jquery"/>                       
<xsl:call-template name="head-js-pirobox"/>    
<xsl:call-template name="head-js-mediaelement"/>                      
                 
<xsl:call-template name="head-css-jquery"/>                      
<xsl:call-template name="head-css-pirobox"/>  
<xsl:call-template name="head-css-mediaelement"/>  

Plugins Zimbra 1.1.0, Exchange 1.1.0, Bluemind 2.1.0

Les plugins Zimbra, Exchange et Bluemind dépendent maintenant d'un plugin commun Messaging Connector.

Il vous faudra redéfinir les paramètres du cache dans les paramètres de configuration.

L'intégration graphique est identique pour ces 3 plugins: Plugin Bluemind 2.1.0 - Exchange 1.1.0 - Zimbra 1.1.0

Pour Bluemind

L'input data utilisé est remplacé par du JS. Il faut remplacer l'existant, et recommencer l'intégration en suivant la documentation commune aux 3 plugins.

Pour Exchange et Zimbra

Il faut remplacer l'import des XSL spécifique exchange et zimbra par celle de Messaging connector (voir documentation commune) :

  • <xsl:import href="plugin:exchange://stylesheets/exchange.xsl" /> => <xsl:import href="plugin:messaging-connector://stylesheets/messaging-connector.xsl" />
  • <xsl:import href="plugin:exchange://stylesheets/zimbra.xsl" /> => <xsl:import href="plugin:messaging-connector://stylesheets/messaging-connector.xsl" />

Le nom des templates XSL a été modifié mais les paramètres et le HTML produit par défaut sont identiques :

  • script-js-zimbra => script-js-messaging-connector
  • script-js-exchange=> script-js-messaging-connector
  • zimbra-card => messaging-connector-card
  • exchange => messaging-connector-card

Si vous avez fait des surcharges, remplacez dans les xsl

  • <xsl:call-template name="exchange-event-date"/> par <xsl:call-template name="messaging-event-date"/>

  • <xsl:call-template name="exchange-event-subject"/> par  <xsl:call-template name="messaging-event-subject"/>

  • <xsl:call-template name="exchange-event-location"/> par <xsl:call-template name="messaging-event-location"/>

  • <i18n:texti18n:key="PLUGINS_EXCHANGE_CARD_INFOUSER_EXCHANGE_RDV_WAITING" i18n:catalogue="plugin.exchange"/> par <i18n:texti18n:key="PLUGINS_MESSAGINGCONNECTOR_CARD_INFOUSER_MESSAGINGCONNECTOR_RDV_WAITING" i18n:catalogue="plugin.messaging-connector"/>

  • <i18n:texti18n:key="PLUGINS_EXCHANGE_CARD_INFOUSER_EXCHANGE_RDV_ERROR" i18n:catalogue="plugin.exchange"/> par <i18n:texti18n:key="PLUGINS_MESSAGINGCONNECTOR_CARD_INFOUSER_MESSAGINGCONNECTOR_RDV_ERROR" i18n:catalogue="plugin.messaging-connector"/>

  • <i18n:texti18n:key="PLUGINS_EXCHANGE_CARD_INFOUSER_EXCHANGE_RDV_NONE_PART1" i18n:catalogue="plugin.exchange"/> par <i18n:texti18n:key="PLUGINS_MESSAGINGCONNECTOR_CARD_INFOUSER_MESSAGINGCONNECTOR_RDV_NONE_PART1" i18n:catalogue="plugin.messaging-connector"/>

  • <i18n:texti18n:key="PLUGINS_EXCHANGE_CARD_INFOUSER_EXCHANGE_RDV_NONE_PART2" i18n:catalogue="plugin.exchange"/> par <i18n:texti18n:key="PLUGINS_MESSAGINGCONNECTOR_CARD_INFOUSER_MESSAGINGCONNECTOR_RDV_NONE_PART2" i18n:catalogue="plugin.messaging-connector"/>

  • <i18n:text i18n:key="PLUGINS_EXCHANGE_CARD_INFOUSER_EXCHANGE_RDV_NONE_PART3" i18n:catalogue="plugin.exchange"/> par <i18n:text i18n:key="PLUGINS_MESSAGINGCONNECTOR_CARD_INFOUSER_MESSAGINGCONNECTOR_RDV_NONE_PART3" i18n:catalogue="plugin.messaging-connector"/>

Si vous utilisez des clés i18 de l'ancien plugin, vous pouvez remplacer : <category i18n="true">plugin.exchange:PLUGINS_EXCHANGE_LOGIN_CATEGORY</category> par <category i18n="true">plugin.messaging-connector:PLUGINS_MESSAGINGCONNECTOR_CONFIG_CATEGORY</category>

Si vous avez surchargé messages.xml du plugin (WEB-INF\i18n\plugins\exchange), renommez le répertoire puis renommez les clés i18 contenus dans les fichiers messages*.xml

Les classes CSS sont préfixées par défaut par "messaging". Pour garder le prefix "exchange" ou "zimbra", faites appel aux templates script-js-messaging-connector et messaging-connector-card en rajoutant le paramètres "css-class-prefix":

Serveur Solr

Le serveur Solr doit être réinstallé.
Télécharger la version 4.1 http://releases.ametys.org/release/org.ametys/solr-app/4.1.x/4.1.0/zips/

Ne conservez pas les anciennes données indéxées.

Après redémarrage du serveur, lancez une indexation totale.

Migration des données

Supprimez le fichier custom_nodetypes.xml de votre repository (${AMETYS_HOME}/data/repository/repository/nodetypes/custom_nodetypes.xml) puis redémarrer le serveur avant d’exécuter les scripts suivant :

Migration du service Plan du site

var qm = session.getWorkspace().getQueryManager();  
var query = qm.createQuery("//element(*, ametys:zoneItem)[@ametys-internal:type='SERVICE' and @ametys-internal:service='org.ametys.web.service.SitemapService']/ametys:service_parameters[@ametys:all='criteria-only']", javax.jcr.query.Query.XPATH);  
it = query.execute().getNodes();  
var count = 0;  
while (it.hasNext())  
{  
  var node = it.nextNode();  
  node.setProperty("ametys:all", "select-root");  
  node.save();  
    
  count++  
}  
     
print(count + " services have been updated");  

Migration des services remontée de contenus et de pages

var ConsoleHelper = Java.type('org.ametys.workspaces.repository.ConsoleHelper');  
    
var qm = session.getWorkspace().getQueryManager();  
var query = qm.createQuery("//element(*, ametys:zoneItem)[@ametys-internal:type='SERVICE' and @ametys-internal:service='org.ametys.web.service.FilteredContentsService']", javax.jcr.query.Query.XPATH);  
var nodes = query.execute().getNodes();  
    
var count = 0;  
while (nodes.hasNext())  
{  
    var needSave = false;  
    var node = nodes.next();  
    var paramsNode = node.getNode('ametys:service_parameters');  
            
    if (paramsNode.hasNode('ametys:search'))  
    {  
        var entryNodes = paramsNode.getNode('ametys:search').getNodes();  
          
        while (entryNodes.hasNext())  
        {  
            var entryNode = entryNodes.next();  
              
            if (entryNode.hasProperty('ametys:search-context'))  
            {  
                var searchCtx = entryNode.getProperty('ametys:search-context').getString();  
                if (searchCtx == 'CURRENT_SITE' || searchCtx == 'CHILD_PAGES' || searchCtx == 'DIRECT_CHILD_PAGES')  
                {  
                    var s = '{"context":"' + searchCtx + '","page":null}';  
                    entryNode.setProperty('ametys:search-context', new java.lang.String(s));  
                    print('Migrate search context value ' + searchCtx + ' to : ' + s);  
                    paramsNode.save();  
                    count++  
                }  
            }  
         }  
    }  
}  
      
print(count + " content aggregation services have been migrated");  
  
query = qm.createQuery("//element(*, ametys:zoneItem)[@ametys-internal:type='SERVICE' and @ametys-internal:service='org.ametys.web.service.FilteredPagesService']", javax.jcr.query.Query.XPATH);  
nodes = query.execute().getNodes();  
    
count = 0;  
while (nodes.hasNext())  
{  
    var needSave = false;  
    var node = nodes.next();  
    var paramsNode = node.getNode('ametys:service_parameters');  
  
    if (paramsNode.hasProperty('ametys:search-context'))  
    {  
        var searchCtx =  paramsNode.getProperty('ametys:search-context').getString();  
        if (searchCtx == 'CURRENT_SITE' || searchCtx == 'CHILD_PAGES' || searchCtx == 'DIRECT_CHILD_PAGES')  
        {  
            var s = '{"context":"' + searchCtx + '","page":null}';  
            paramsNode.setProperty('ametys:search-context', new java.lang.String(s));  
            print('Migrate search context value ' + searchCtx + ' to : ' + s);  
            paramsNode.save();  
            count++  
        }   
    }  
}  
print(count + " page aggregation services have been migrated");  

Migration des services remontée de contenus (paramètre sortby avec les valeurs les plus courantes)

var ConsoleHelper = Java.type('org.ametys.workspaces.repository.ConsoleHelper');  

var qm = session.getWorkspace().getQueryManager();  
var query = qm.createQuery("//element(*, ametys:zoneItem)[@ametys-internal:type='SERVICE' and @ametys-internal:service='org.ametys.web.service.FilteredContentsService']", javax.jcr.query.Query.XPATH);  
var nodes = query.execute().getNodes();  

var count = 0;  
while (nodes.hasNext())  
{  
    var needSave = false;  
    var node = nodes.next();  
    var paramsNode = node.getNode('ametys:service_parameters');  

    if (paramsNode.hasProperty("ametys:sortBy"))
    {
      if (paramsNode.getProperty("ametys:sortBy").getString() == "start-date#asc")
      {
          paramsNode.setProperty("ametys:sortBy", "[{\"name\":\"start-date\",\"sort\":\"ASC\"}]");
          session.save();
       count++;
      }
      else if (paramsNode.getProperty("ametys:sortBy").getString() == "start-date#desc")
      {
          paramsNode.setProperty("ametys:sortBy", "[{\"name\":\"start-date\",\"sort\":\"DESC\"}]");
          session.save();
       count++;
      }
      else if (paramsNode.getProperty("ametys:sortBy").getString() == "end-date#desc,start-date#desc")
      {
          paramsNode.setProperty("ametys:sortBy", "[{\"name\":\"end-date\",\"sort\":\"DESC\"},{\"name\":\"start-date\",\"sort\":\"DESC\"}]");
          session.save();
       count++;
      }
      else if (paramsNode.getProperty("ametys:sortBy").getString() == "start-date#desc,end-date#desc"
   || paramsNode.getProperty("ametys:sortBy").getString() == "start-date#desc,end-date#asc")
      {
          paramsNode.setProperty("ametys:sortBy", "[{\"name\":\"start-date\",\"sort\":\"DESC\"},{\"name\":\"end-date\",\"sort\":\"DESC\"}]");
          session.save();
       count++;
      }
      else if (paramsNode.getProperty("ametys:sortBy").getString() == "lastValidationDate#desc")
      {
          paramsNode.setProperty("ametys:sortBy", "[{\"name\":\"lastValidationDate\",\"sort\":\"DESC\"}]");
          session.save();
       count++;
      }
      else if (paramsNode.getProperty("ametys:sortBy").getString().indexOf("#") != -1)
      {
         print(paramsNode.getId() + " - " + paramsNode.getProperty("ametys:sortBy").getString())
      }
    }
}  

print(count + " content aggregation services have been migrated"); 

Migration des thèmes de couleur

var mapping = {  
'804080': '4',  
'0178D6': '8',  
'01BFF3': '9',  
'4FC7D8': '11',  
'81BC26': '15',  
'579741': '16',  
'107C0C': '14',  
'FAD115': '17',  
'FF8800': '18',  
'FD002F': '22',  
'C91717': '24',  
'060606': '28'  
};  
  
jcrXPathQuery("//element(*, ametys:site)").forEach(function(site) {  
 var color = site.getColor();  
 var colorIndex = mapping[color];  
 if (colorIndex)  
 {  
 print("Changing " + site.getTitle() + " -> " + site.getColor() + "\n");  
 site.getNode().setProperty("ametys:color", colorIndex);  
 }  
});  
  
session.save();  

Suppression des références JCR

function migrate()  
{  
    var count = {  
        existing: 0,  
        done: 0  
    };  
    jcrXPathQuery("//element(*, ametys:content)").forEach(function(content) {  
        count.existing++;  
        migrateContent(content,  
                        functionsToApply,  
                        true            /* old versions have to be marked incompatible */,  
                        null            /* tag new versions */,  
                        false           /* not verbose */);  
        count.done++;  
    });  
    print(count.done + " contents migrated on " + count.existing + " existing contents");  
}  
  
function _removeRefs(content)  
{  
    _removeRefsRecursively(content.getNode());  
}  
   
function _removeRefsRecursively(node)  
{  
    // Explore nodes recursively  
    var subNodes = node.getNodes();  
    while (subNodes.hasNext())  
    {  
        var subNode = subNodes.nextNode();  
        if (!subNode.getName().startsWith(internalPrefix))  
        {  
            _removeRefsRecursively(subNode);  
        }  
    }  
       
    // Remove reference properties  
    var properties = node.getProperties(jcrRefPattern);  
    while (properties.hasNext())  
    {  
        var prop = properties.nextProperty();  
        prop.remove();  
    }  
}  
  
var _extractOutgoingReferences = (function()  
{  
    var proxy = serviceManager.lookup("org.ametys.cms.workflow.EditContentFunction");  
    var method = org.ametys.cms.workflow.EditContentFunction.class.getDeclaredMethod("_extractOutgoingReferences", org.ametys.cms.repository.ModifiableContent.class);  
    method.setAccessible(true);  
    return function(content)  
    {  
        if (!(content instanceof org.ametys.cms.repository.ModifiableContent))  
        {  
          print("passed arg content (" + (content == null ? "null" : content.getId()) + ") is not modifiable");  
          return;  
        }  
        var args = [content];  
        return java.lang.reflect.Proxy.getInvocationHandler(proxy).invoke(proxy, method, args);  
    }  
})();  
    
var internalPrefix = "ametys-internal:";  
var jcrRefPattern = internalPrefix + "ref-*";  
  
var functionsToApply = [];  
functionsToApply.push(_removeRefs);  
functionsToApply.push(_extractOutgoingReferences);  
  
migrate();  
print("Switching to archives");  
var credentials = new javax.jcr.SimpleCredentials('ametys', []);  
session = repository.login(credentials, 'archives');  
migrate();  

Migration des tables de référence

var qm = session.getWorkspace().getQueryManager();  
var query = qm.createQuery("//element(*)[@oswf:workflowName='simple-content']", javax.jcr.query.Query.XPATH);  
var nodes = query.execute().getNodes();  
var nodeCount = 0;  
while (nodes.hasNext())  
{  
    var node = nodes.next();         
    nodeCount++;  
    node.setProperty('oswf:workflowName','reference-table')  
}  
session.save();  
print("* "+nodeCount+" simple-content modified to reference-table\n");  

 

Plugin Annuaire de liens 2.2.x

Si vous utilisez le plugin Annuaire de lien (link-directory), vous devrez passer à la version 2.2.x ou supérieure.
Suivez le guide de migration technique et graphique:  Plugin Annuaire de liens - Manuel de migration technique et graphique 2.1.0 vers 2.2.0

Attention, si votre ancienne version était la version 2.0.x, suivez également le guide de migration de la version 2.0.0 vers 2.1.0 : Plugin Annuaire de liens - Manuel de migration technique et graphique 2.0.0 vers 2.1.0

 

Retour en haut