Ces 4 types de contenus héritent du même type abstrait Media (org.ametys.plugins.multimedia.Content.abstractMedia)
Chaque type de contenu est lié à un nouveau droit de création: créer un document audio, créer un document vidéo, créer un document photo et créer un document.
Le plugin propose un rendu par défaut pour chacun de ces contenus, avec un player multimedia basé sur la librairie mediaelement.js pour les documents audio et vidéo.
Si vous avez des types de contenus similaires dans votre application
Vous pouvez choisir d'exclure ces nouveaux types au niveau de votre charte (fichiers content-types-default.xml) afin d'éviter les doublons et une nouvelle intégration graphique.
Ou vous pouvez choisir de migrer vos types de contenus existants vers les nouveaux (cf. migration de données ci-après) et reprendre l'intégration graphique existante pour les nouveaux types (cf. Migration graphique ci après)
Migration des données
Exécutez le script suivant. Le script migre les types de contenus et les éventuels services de recherche paramétrés sur les anciens types. Attention, ce script est un exemple avec des types de contenus à migrer dont les identifiants seraient "plugin.single-media-contents.**". Adaptez ce script si vos identifiants divergent.
Oups !
La copie dans le presse papier a échouée. Ouvrez le code et copier-le manuellement.
let logger = Ametys.getLogger("org.ametys.plugins.multimedia.migration.logger", {"filename": "migration-multimedia", "level": "info"});
logger.info("[BEGIN] Migration of single media");
convertContentType("plugin.single-media-contents.video", "org.ametys.plugins.multimedia.Content.video");
convertContentType("plugin.single-media-contents.audio", "org.ametys.plugins.multimedia.Content.audio");
convertContentType("plugin.single-media-contents.document", "org.ametys.plugins.multimedia.Content.document");
convertSearchService("plugin.single-media-contents.item-content", "org.ametys.plugins.multimedia.Content.abstractMedia");
convertSearchService("plugin.single-media-contents.video", "org.ametys.plugins.multimedia.Content.video");
convertSearchService("plugin.single-media-contents.audio", "org.ametys.plugins.multimedia.Content.audio");
convertSearchService("plugin.single-media-contents.document", "org.ametys.plugins.multimedia.Content.document");
logger.info("[END] Migration of single media");
function convertContentType(oldType, newType)
{
let count = 0;
let contents = Repository.query("//element(*, ametys:content)[@ametys-internal:contentType = '" + oldType + "']");
contents.forEach(
content =>
{
Content.migrate(
content,
_migrateContent.bind(null, newType),
true,
false,
false,
true
);
count++;
}
);
logger.info(`${count} contents of type '${oldType}' have been migrated to content type '${newType}'`);
}
function convertSearchService(oldType, newType)
{
_convertSearchServiceInWorkspace(oldType, newType, Repository.session);
_convertSearchServiceInWorkspace(oldType, newType, Repository.liveSession);
}
function _convertSearchServiceInWorkspace(oldType, newType, currentSession)
{
let count = 0;
const paramsNodes = Repository.query("//element(*, ametys:zoneItem)[@ametys-internal:service='org.ametys.web.service.SearchService']/ametys:service_parameters[@ametys:contentTypes='" + oldType + "']", false, currentSession);
while (paramsNodes.hasNext())
{
let paramsNode = paramsNodes.next();
_migrateService(paramsNode, oldType, newType);
count++;
}
if (count > 0)
{
currentSession.save();
}
let sessionName = currentSession.getWorkspace().getName();
logger.info(`[${sessionName}] ${count} search services have been migrated for type '${oldType}'`);
}
function _migrateContent(newType, content)
{
content.setTypes([newType]);
let node = content.getNode();
// Migrate attachment (attached to the content)
if (node.hasNode("ametys:attachment"))
{
node.getSession().move(node.getNode('ametys:attachment').getPath(), node.getPath() + "/ametys:file");
}
// Migrate attachment (from resource explorer)
if (node.hasProperty("ametys:attachment"))
{
let oldProperty = node.getProperty("ametys:attachment");
node.setProperty("ametys:file", oldProperty.getValue());
oldProperty.remove();
}
}
function _migrateService(paramsNode, oldType, newType, service)
{
let newCTypes = [];
let ctypes = paramsNode.getProperty("ametys:contentTypes").getValues();
for (let i=0; i < ctypes.length; i++)
{
let currentCType = ctypes[i].getString();
newCTypes.push(currentCType == oldType ? newType : currentCType);
}
Repository.helper.setProperty(paramsNode, "ametys:contentTypes", newCTypes);
}
let logger = Ametys.getLogger("org.ametys.plugins.multimedia.migration.logger", {"filename": "migration-multimedia", "level": "info"});
logger.info("[BEGIN] Migration of single media");
convertContentType("plugin.single-media-contents.video", "org.ametys.plugins.multimedia.Content.video");
convertContentType("plugin.single-media-contents.audio", "org.ametys.plugins.multimedia.Content.audio");
convertContentType("plugin.single-media-contents.document", "org.ametys.plugins.multimedia.Content.document");
convertSearchService("plugin.single-media-contents.item-content", "org.ametys.plugins.multimedia.Content.abstractMedia");
convertSearchService("plugin.single-media-contents.video", "org.ametys.plugins.multimedia.Content.video");
convertSearchService("plugin.single-media-contents.audio", "org.ametys.plugins.multimedia.Content.audio");
convertSearchService("plugin.single-media-contents.document", "org.ametys.plugins.multimedia.Content.document");
logger.info("[END] Migration of single media");
function convertContentType(oldType, newType)
{
let count = 0;
let contents = Repository.query("//element(*, ametys:content)[@ametys-internal:contentType = '" + oldType + "']");
contents.forEach(
content =>
{
Content.migrate(
content,
_migrateContent.bind(null, newType),
true,
false,
false,
true
);
count++;
}
);
logger.info(`${count} contents of type '${oldType}' have been migrated to content type '${newType}'`);
}
function convertSearchService(oldType, newType)
{
_convertSearchServiceInWorkspace(oldType, newType, Repository.session);
_convertSearchServiceInWorkspace(oldType, newType, Repository.liveSession);
}
function _convertSearchServiceInWorkspace(oldType, newType, currentSession)
{
let count = 0;
const paramsNodes = Repository.query("//element(*, ametys:zoneItem)[@ametys-internal:service='org.ametys.web.service.SearchService']/ametys:service_parameters[@ametys:contentTypes='" + oldType + "']", false, currentSession);
while (paramsNodes.hasNext())
{
let paramsNode = paramsNodes.next();
_migrateService(paramsNode, oldType, newType);
count++;
}
if (count > 0)
{
currentSession.save();
}
let sessionName = currentSession.getWorkspace().getName();
logger.info(`[${sessionName}] ${count} search services have been migrated for type '${oldType}'`);
}
function _migrateContent(newType, content)
{
content.setTypes([newType]);
let node = content.getNode();
// Migrate attachment (attached to the content)
if (node.hasNode("ametys:attachment"))
{
node.getSession().move(node.getNode('ametys:attachment').getPath(), node.getPath() + "/ametys:file");
}
// Migrate attachment (from resource explorer)
if (node.hasProperty("ametys:attachment"))
{
let oldProperty = node.getProperty("ametys:attachment");
node.setProperty("ametys:file", oldProperty.getValue());
oldProperty.remove();
}
}
function _migrateService(paramsNode, oldType, newType, service)
{
let newCTypes = [];
let ctypes = paramsNode.getProperty("ametys:contentTypes").getValues();
for (let i=0; i < ctypes.length; i++)
{
let currentCType = ctypes[i].getString();
newCTypes.push(currentCType == oldType ? newType : currentCType);
}
Repository.helper.setProperty(paramsNode, "ametys:contentTypes", newCTypes);
}
let logger = Ametys.getLogger("org.ametys.plugins.multimedia.migration.logger", {"filename": "migration-multimedia", "level": "info"});
logger.info("[BEGIN] Migration of single media");
convertContentType("plugin.single-media-contents.video", "org.ametys.plugins.multimedia.Content.video");
convertContentType("plugin.single-media-contents.audio", "org.ametys.plugins.multimedia.Content.audio");
convertContentType("plugin.single-media-contents.document", "org.ametys.plugins.multimedia.Content.document");
convertSearchService("plugin.single-media-contents.item-content", "org.ametys.plugins.multimedia.Content.abstractMedia");
convertSearchService("plugin.single-media-contents.video", "org.ametys.plugins.multimedia.Content.video");
convertSearchService("plugin.single-media-contents.audio", "org.ametys.plugins.multimedia.Content.audio");
convertSearchService("plugin.single-media-contents.document", "org.ametys.plugins.multimedia.Content.document");
logger.info("[END] Migration of single media");
function convertContentType(oldType, newType)
{
let count = 0;
let contents = Repository.query("//element(*, ametys:content)[@ametys-internal:contentType = '" + oldType + "']");
contents.forEach(
content =>
{
Content.migrate(
content,
_migrateContent.bind(null, newType),
true,
false,
false,
true
);
count++;
}
);
logger.info(`${count} contents of type '${oldType}' have been migrated to content type '${newType}'`);
}
function convertSearchService(oldType, newType)
{
_convertSearchServiceInWorkspace(oldType, newType, Repository.session);
_convertSearchServiceInWorkspace(oldType, newType, Repository.liveSession);
}
function _convertSearchServiceInWorkspace(oldType, newType, currentSession)
{
let count = 0;
const paramsNodes = Repository.query("//element(*, ametys:zoneItem)[@ametys-internal:service='org.ametys.web.service.SearchService']/ametys:service_parameters[@ametys:contentTypes='" + oldType + "']", false, currentSession);
while (paramsNodes.hasNext())
{
let paramsNode = paramsNodes.next();
_migrateService(paramsNode, oldType, newType);
count++;
}
if (count > 0)
{
currentSession.save();
}
let sessionName = currentSession.getWorkspace().getName();
logger.info(`[${sessionName}] ${count} search services have been migrated for type '${oldType}'`);
}
function _migrateContent(newType, content)
{
content.setTypes([newType]);
let node = content.getNode();
// Migrate attachment (attached to the content)
if (node.hasNode("ametys:attachment"))
{
node.getSession().move(node.getNode('ametys:attachment').getPath(), node.getPath() + "/ametys:file");
}
// Migrate attachment (from resource explorer)
if (node.hasProperty("ametys:attachment"))
{
let oldProperty = node.getProperty("ametys:attachment");
node.setProperty("ametys:file", oldProperty.getValue());
oldProperty.remove();
}
}
function _migrateService(paramsNode, oldType, newType, service)
{
let newCTypes = [];
let ctypes = paramsNode.getProperty("ametys:contentTypes").getValues();
for (let i=0; i < ctypes.length; i++)
{
let currentCType = ctypes[i].getString();
newCTypes.push(currentCType == oldType ? newType : currentCType);
}
Repository.helper.setProperty(paramsNode, "ametys:contentTypes", newCTypes);
}
Migration graphique
Déplacez les XSL de rendus de vos anciens types de contenus dans :
Le champ portant le fichier (document, audio ou video) est nommé "file". Si dans votre ancien modèle, le champ porte un nom différent (ex: attachment), rechercher ce nom dans vos XSL de rendus et remplacez-le par "file"
Si vous n'avez pas de types de contenus similaires dans votre application
Vous pouvez choisir d'exclure ces nouveaux types au niveau de votre charte (fichiers content-types-default.xml) si ce n'est pas souhaitable ou pour éviter une nouvelle intégration graphique.
Ou vous pouvez choisir de proposer ces nouveaux types. Si le rendu par défaut proposé ne convient pas, il faudra prévoir une intégration graphique de ces 4 nouveaux types.