Refer to the plugins compatibility table and increment the versions of your plugins (take the most recent 4.2-compatible version for each plugin ).
In the runtime.xml, delete the following lines:
<org.ametys.cms.source.ContentView>org.ametys.web.source.WebContentView</org.ametys.cms.source.ContentView> <org.ametys.cms.source.ViewSelector>org.ametys.web.source.WebViewSelector</org.ametys.cms.source.ViewSelector>
In your search templates (the XML files under WEB-INF/param/search), replace occurrences of IndexingStringFieldAggregatorSearchUICriterion by IndexingFieldAggregatorSearchUICriterion
The FormsCredentialProvider configuration options have been modified:
The file $AMETYS _HOME/config/user-population .xml must be modified manually.
Replace :
<runtime.authentication.form.security.level>low</runtime.authentication.form.security.level>
by
<runtime.authentication.form.cookies>true</runtime.authentication.form.cookies> <runtime.authentication.form.captcha>false</runtime.authentication.form.captcha> <runtime.authentication.form.login-by-email>false</runtime.authentication.form.login-by-email>
Replace :
<runtime.authentication.form.security.level>high</runtime.authentication.form.security.level>
by
<runtime.authentication.form.cookies>false</runtime.authentication.form.cookies> <runtime.authentication.form.captcha>true</runtime.authentication.form.captcha> <runtime.authentication.form.login-by-email>false</runtime.authentication.form.login-by-email>
The "results sorting" parameter has been brought up from the "Directory LDAP" type populations directly in the data source, in particular so that it can also be used by group directories.
In your files $AMETYS_HOME/config/user-populations .xml, delete all occurrences of the following parameter, if present:
<runtime.users.ldap.serverSideSorting>true</runtime.users.ldap.serverSideSorting>
And in your files $AMETYS_HOME/config/datasources- ldap.xml, add the following parameter to each data source:
<serverSideSorting>true</serverSideSorting>
The default value is "true". However, if you had unchecked "Sort results", i.e. you had set "runtime.users.ldap.serverSideSorting" to false in your directory population(s) LDAP for performance reasons, then set the value to "false" instead of "true" in the $AMETYS _HOME/config/datasources- ldap.xml to the corresponding data sources.
The WEB-INF/param/workflows.xml file is now optional. Available workflows are automatically read from the WEB-INF/param/workflows folder.
In general, all you need to do is remove the "workflow-" prefix in front of the file name, but beware of a few pitfalls... for example, "worfklow.xml" becomes "content.xml"; or "workflow-coursepart.xml" becomes "course-part.xml". Pay particular attention to the "name" attribute in the workflows file.xml
Dans le fichier workflows/reference-table.xml pour les tables de référence, rajoutez l'action suivante dans les <common-actions> :
<action id="220" name="plugin.default-workflow:WORKFLOW_ACTION_ADD_CONTENTTYPE"> <restrict-to> <conditions type="AND"> <condition type="avalon"> <arg name="role">org.ametys.cms.workflow.LockCondition</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> </post-functions> </action>
and add the reference to this new action in reports (step) 1 and 3
<actions> <common-action id="2" /> <common-action id="220" /> <common-action id="222" /> </actions>
On all workflows used in synchronization (i.e. using action 800), add to synchronization action 800 the post-function org.ametys.cms.workflow.ExtractOutgoingReferencesFunction :
<action id="800" name="plugin.contentio:WORKFLOW_ACTION_SYNCHRONIZE"> <restrict-to> [...] </restrict-to> <results> [...] </results> <post-functions> <function type="avalon"> <arg name="role">org.ametys.cms.workflow.ExtractOutgoingReferencesFunction</arg> </function> </post-functions> </action>
To simplify the installation of certain plugins functions, there is now an extension point for the 'after registration' and 'after validation' functions.
Places where you used to have the workflow functions of plugin forms or plugin translation-flagging will be replaced by generic functions.
For example, the function: org.ametys.plugins.forms.workflow.FormEditionFunction becomes
<function type="avalon"> <arg name="role">org.ametys.cms.workflow.extensions.ExtensibleFunction</arg> <arg name="extension-point">org.ametys.cms.workflow.extensions.PostContentEditionFunctionsExtensionPoint</arg> </function>
and the org.ametys.plugins.translationflagging.TranslationAlertFunction becomes :
<function type="avalon"> <arg name="role">org.ametys.cms.workflow.extensions.ExtensibleFunction</arg> <arg name="extension-point">org.ametys.cms.workflow.extensions.PostContentValidationFunctionsExtensionPoint</arg> </function>
Tokens used to be for infinite or single use.
Now they can have a limited number of uses, be renewable and have a context of use.
Migration scripts SQL need to be run to update table formats (depending on your database type).
#Derby ALTER TABLE APP.Authentication_Token ADD nb_uses_left int; ALTER TABLE APP.Authentication_Token ADD auto_renew_duration bigint; ALTER TABLE APP.Authentication_Token ADD context VARCHAR(200); UPDATE APP.Authentication_Token SET nb_uses_left = 1 WHERE end_date IS NOT NULL; RENAME COLUMN APP.Authentication_Token.comment TO token_comment; #HsqlDb ALTER TABLE Authentication_Token ADD nb_uses_left INTEGER NULL BEFORE context; ALTER TABLE Authentication_Token ADD auto_renew_duration NUMERIC(13) NULL BEFORE context; ALTER TABLE Authentication_Token ADD context VARCHAR(200) NULL BEFORE context; UPDATE Authentication_Token SET nb_uses_left = 1 WHERE end_date IS NOT NULL; ALTER TABLE Authentication_Token ALTER COLUMN comment RENAME TO token_comment; #MySQL ALTER TABLE Authentication_Token ADD nb_uses_left INT NULL AFTER last_update_date, ADD auto_renew_duration BIGINT NULL AFTER nb_uses_left, ADD context VARCHAR(200) NULL AFTER auto_renew_duration; UPDATE Authentication_Token SET nb_uses_left = 1 WHERE end_date IS NOT NULL; ALTER TABLE Authentication_Token CHANGE comment token_comment LONGBLOB; #Oracle ALTER TABLE Authentication_Token ADD ( nb_uses_left NUMBER, auto_renew_duration NUMBER(13), context VARCHAR(200) ); UPDATE Authentication_Token SET nb_uses_left = 1 WHERE end_date IS NOT NULL; ALTER TABLE Authentication_Token RENAME COLUMN comment TO token_comment; #PostgreSql ALTER TABLE Authentication_Token ADD nb_uses_left INTEGER NULL, ADD auto_renew_duration BIGINT NULL, ADD context VARCHAR(200) NULL; UPDATE Authentication_Token SET nb_uses_left = 1 WHERE end_date IS NOT NULL; ALTER TABLE Authentication_Token RENAME COLUMN comment TO token_comment;
The account creation request no longer asks for first and last names (which will be requested later).
Run the following scripts on your database:
alter table Users_Temp drop lastname; alter table Users_Temp drop firstname;
In your files java and plugin.xml, find and replace the occurrences in the 1st column of the table by their equivalent in the 2nd column:
|
Replace |
By |
|---|---|
|
org.ametys.cms.clientsideelement.SmartContentClientSideElement |
org.ametys.core.ui.StaticClientSideElement |
|
org.ametys.cms.clientsideelement.SmartContentTypesGallery |
org.ametys.cms.clientsideelement.ContentTypesGallery |
|
org.ametys.cms.clientsideelement.DeleteContentClientSideElement |
org.ametys.core.ui.StaticClientSideElement |
|
org.ametys.cms.clientsideelement.ArchiveMenuClientSideElement |
org.ametys.cms.clientsideelement.SmartContentMenu |
|
org.ametys.web.clientsideelement.DeleteContentClientSideElement |
org.ametys.core.ui.StaticClientSideElement |
|
org.ametys.web.clientsideelement.TagClientSideElement |
org.ametys.core.ui.StaticClientSideElement |
|
org.ametys.web.clientsideelement.PageVisibilityClientSideElement |
org.ametys.core.ui.StaticClientSideElement |
|
org.ametys.web.clientsideelement.PreviewPageClientSideElement |
org.ametys.core.ui.StaticClientSideElement |
|
org.ametys.web.clientsideelement.LivePageClientSideElement |
org.ametys.core.ui.StaticClientSideElement |
|
org.ametys.web.clientsideelement.BlankPageClientSideElement |
org.ametys.core.ui.StaticClientSideElement |
|
org.ametys.web.clientsideelement.LinkPageClientSideElement |
org.ametys.core.ui.SimpleMenu |
The management of service parameters has been completely modified. When migrating a project to 4.2, if this project contains specific services or overloads kernel services (unless it only overloads rendering), this migration may require code modifications.
Dans certains projets (principalement ODF) les pipelines faisant appel à des PDF ont été modifiés pour intégrer des fonts personnalisées. Les pipelines personnalisés dans ce but ne sont donc plus utiles, il faut supprimer leurs appels et leurs déclarations. Vous pouvez les détecter en cherchant les serializers (sitemap.xmap) org.ametys.core.cocoon.FOPNGSerializer ayant une balise <user-config>. Les pipelines noyaux font désormais correctement l'appel à la configuration personnalisée.
Vérifier qu'il n'existe pas d'autres serializers spécifique au projet en cherchant <map:serialize type="fo2pdf"/>.
However, you may need to modify your project if the file is not positioned correctly. Please refer to the page Putting a custom font in a PDF for further information.
In the general configuration parameters, CMS 'surl can no longer end with / or /index.html.
If this is the case, you need to change this parameter.
With the server off, start by deleting the file $AMETYS_HOME/data/repository/repository/custom_nodetypes.xml then restart.
From the management console, run the following scripts:
function copyTagNode(originalNode, newNode)
{
setPropertyFromNode(originalNode, newNode, "ametys-internal:target");
setPropertyFromNode(originalNode, newNode, "ametys-internal:description");
setPropertyFromNode(originalNode, newNode, "ametys-internal:visibility");
setPropertyFromNode(originalNode, newNode, "ametys-internal:title");
}
function setPropertyFromNode(originalNode, newNode, propertyName)
{
if (originalNode.hasProperty(propertyName))
{
newNode.setProperty(propertyName, originalNode.getProperty(propertyName).getString());
}
}
function createNodesFromNode(rootNode, sourceNode)
{
var nbTag = 0;
var childNodes = sourceNode.getNodes();
while (childNodes.hasNext())
{
var childNode = childNodes.next();
var createdNode = rootNode.addNode(childNode.getName(), "ametys:cmstag");
copyTagNode(childNode, createdNode);
nbTag++;
nbTag += createNodesFromNode(createdNode, childNode);
}
return nbTag;
}
var totalNbTag = 0;
var qm = session.getWorkspace().getQueryManager();
var query = qm.createQuery("//element(*, ametys:tags)", javax.jcr.query.Query.XPATH);
var nodes = query.execute().getNodes();
while (nodes.hasNext())
{
var tagsNode = nodes.next();
if (!tagsNode.getParent().hasNode("cmstags"))
{
tagsNode.getParent().addNode("cmstags", "ametys:cmstags");
}
var newTagsNode = tagsNode.getParent().getNode("cmstags");
totalNbTag += createNodesFromNode(newTagsNode, tagsNode);
tagsNode.remove();
}
session.save();
print(totalNbTag + " tag(s) have been migrated"); The service parameters have been modified:
Run the following script JCR to modify existing services:
var count = 0;
var qm = session.getWorkspace().getQueryManager();
var query = qm.createQuery("//element(*, ametys:zoneItem)[@ametys-internal:service = 'org.ametys.web.service.UserSignup']", javax.jcr.query.Query.XPATH);
var nodes = query.execute().getNodes();
while (nodes.hasNext())
{
var node = nodes.next();
var page = node.getParent().getParent().getParent().getParent();
var sitemap = page.getProperty("ametys:sitemap").getString();
print("Found a signup service for language " + sitemap + " at path " + page.getPath());
count++;
var params = node.getNode("ametys:service_parameters");
if (params.hasProperty("ametys:terms-of-service-page"))
{
var pageId = params.getProperty("ametys:terms-of-service-page").getString();
if (pageId != '')
{
params.setProperty("ametys:terms-of-service-mode", "PAGE");
}
else
{
params.setProperty("ametys:terms-of-service-mode", "NONE");
}
}
else
{
params.setProperty("ametys:terms-of-service-mode", "NONE");
}
query = qm.createQuery("//element(*, ametys:page)[@ametys-internal:tags = 'USER_PREFS_MAIN' and @ametys:sitemap= " + sitemap + "]", javax.jcr.query.Query.XPATH);
var pages = query.execute().getNodes();
if (pages.hasNext())
{
var successPage = pages.next();
params.setProperty("ametys:success-page", "page://" + successPage.getUUID());
params.setProperty("ametys:success-mode", "PAGE");
}
// TO UNCOMMENT ONLY IF YOU USE USER-DIRECTORY PLUGIN
// params.setProperty("ametys:xslt", pages/services/user-signup/signup.xsl);
}
session.save();
print(count + " signup services have been migrated"); var fieldsByContent = new java.util.HashMap();
fillFieldsToMigrateMap();
var migratedFields = 0;
var migratedContents = 0;
// Migrate the multilingual nodes content by content
fieldsByContent.forEach(
function(contentId)
{
var content = ametysResolver.resolveById("content://" + contentId);
migrateContent(content,
[renameMultilingualString],
true /* old versions have to be marked incompatible */,
null /* tag new versions */,
false /* not verbose - DO NOT ACTIVATE IN THIS CASE !! */
);
}
);
print(migratedFields + " multilingual fields have been migrated in " + migratedContents + " contents.");
// Get all the multilingual nodes
function fillFieldsToMigrateMap()
{
var fieldsToMigrate = 0;
var qm = session.getWorkspace().getQueryManager();
var query = qm.createQuery("//element(*, ametys:multilingualString)", javax.jcr.query.Query.XPATH);
var nodes = query.execute().getNodes();
while (nodes.hasNext())
{
var node = nodes.next();
// Get the path of the multilingual metadata to migrate
var metadataPath = "";
var contentNode = node;
while (!contentNode.getPrimaryNodeType().isNodeType("ametys:content"))
{
metadataPath += node.getName() + "/";
contentNode = node.getParent();
}
metadataPath = metadataPath.slice(0, -1);
// Store the metadataPath to migrate by content ID
var contentId = contentNode.getIdentifier();
var fields = fieldsByContent.getOrDefault(contentId, new java.util.HashSet());
fields.add(metadataPath);
fieldsByContent.put(contentId, fields);
fieldsToMigrate++;
}
print(fieldsToMigrate + " multilingual fields to migrate potentially in " + fieldsByContent.keySet().size() + " contents.");
}
// Migrate the multilingual strings of the content and increment the global counter
function renameMultilingualString(content)
{
var migratedContent = false;
var contentId = content.getNode().getIdentifier();
// Get all metadata to migrate for the current content
var fields = fieldsByContent.get(contentId);
fields.forEach(
function(fieldName)
{
var migratedField = false;
var fieldNode = content.getNode().getNode(fieldName);
var properties = fieldNode.getProperties();
while (properties.hasNext())
{
var property = properties.nextProperty();
// If the current property name doesn't starts with "ametys:" ...
var propertyName = property.getName();
if (propertyName.indexOf(":") == -1)
{
// ... move it to "ametys:[propertyName]"
fieldNode.setProperty("ametys:" + propertyName, property.getValue());
property.remove();
migratedField = true;
}
}
if (migratedField)
{
migratedFields++;
migratedContent = true;
}
}
);
if (migratedContent)
{
migratedContents++;
}
} The main search engine service has been renamed "Page Search".
The associatedurl service has been changed from "service/search.html" to "service/search-pages.html". Check your XSL to make sure you didn't have this url .
The service class has changed. If the search engine has been duplicated, search your project's xml files and replace "org.ametys.web.frontoffice.SearchService" with "org.ametys.web.frontoffice.SearchPagesService".
The location of the service's XSL has changed(see graphic migration), so you need to run the following script (and rebuild live if there are any changes):
var count = 0;
var done = 0;
jcrXPathQuery("//element(*, ametys:zoneItem)[@ametys-internal:service='org.ametys.web.service.FrontSearchService']").forEach(function(zi) {
print("Found " + zi.getPath());
var parameters = zi.getServiceParameters();
var xsltParam = parameters.getValue("xslt");
print(" " + xsltParam);
count++;
var toReplace = "pages/services/search/";
if (xsltParam.startsWith(toReplace))
{
var newValue = "pages/services/search-pages/" + xsltParam.substring(toReplace.length);
print(" => " + newValue)
parameters.setValue("xslt", newValue);
zi.saveChanges();
done++;
}
else
{
print(" => ok")
}
})
print("...");
print(done + " services modifiés sur " + count)
if (done > 0)
{
print("PENSEZ A RECONSTRUIRE LE LIVE")
} Following changes toAPI and data storage, existing services need to be migrated.
Go to script on the page dedicated to service migration.
If your application is a Ametys ODF application, follow the technical and graphical migration guide from version 4.0 to version 4.1 of theODF
Depending on the plugins Ametys you use, you must follow the technical and/or graphic migrations specific to each plugin :
The "Modify search Solr" right has been removed in favor of the already existing "Search tool Solr" right.
The Solr server must be reinstalled.
Download version 4.2 http://releases.ametys.org/release/org.ametys / solr-app/4 .2.x/4.2.0/zips/
Do not keep the old indexed data (delete all the contents of "solr home" (except the logs folder, if any), by default it is located in solr/server/solr, then copy and paste the default data from the delivery of ametys-solr-config-*.zip).
After restarting the server Solr then Ametys, run a full indexing operation.