/*
* Copyright 2010 Anyware Services
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @private
* Archive content
*/
Ext.define('Ametys.plugins.cms.content.actions.ArchiveContentAction', {
singleton: true,
/**
* @private
* @property {String} archivePluginName The plugin to call when archiving
*/
archivePluginName: 'cms',
/**
* @private
* @property {String} unarchivePluginName The plugin to call when unarchiving
*/
unarchivePluginName: 'cms',
/**
* @property {Number} _count Counter for processed contents.
* @private
*/
_count: 0,
/**
* @property {String[]} _cumulatedContentsIds Array of processed contents' ids.
* @private
*/
_cumulatedContentsIds: [],
/**
* @property {String[]} _cumulatedContentsTargets Array of processed contents' targets.
* @private
*/
_cumulatedContentsTargets: [],
/**
* Action which archives the selected content(s).
* @param {Ametys.ribbon.element.ui.ButtonController} controller The button controller.
*/
archive: function(controller)
{
var contentIds = controller.getContentIds();
if (contentIds.length > 0)
{
var actionId = controller.getInitialConfig()['workflow-action-id'];
var callback = Ext.bind(this._canArchiveCb, this);
controller.serverCall('canArchive', [contentIds], callback, { arguments: {contentIds: contentIds, targets: controller.getMatchingTargets(), actionId: actionId, controller: controller} });
}
},
/**
* Process the "canArchive" test results.
* @param {Object[]} params The JSON result.
* @param {String[]} params.referenced-contents the referenced contents
* @param {Object[]} args The callback arguments.
* @param {String} args.targets the candidates for the archiving
* @param {String} args.actionId the id of the action to be performed
* @private
*/
_canArchiveCb: function(params, args)
{
var noRightsContents = params['no-right-contents'];
var referencedContents = params['referenced-contents'];
if (noRightsContents.length > 0 || referencedContents.length > 0)
{
var message = "";
if (noRightsContents.length > 0)
{
message += "{{i18n plugin.cms:CONTENT_ARCHIVE_NO_RIGHT}}";
for (var i=0; i < noRightsContents.length; i++)
{
message += (i > 0 ? ', ' : '') + noRightsContents[i].title;
}
message += ".";
}
if (referencedContents.length > 0)
{
if (message != '')
{
message += ".<br/><br/>";
}
message += "{{i18n plugin.cms:CONTENT_ARCHIVE_REFERENCED_CONTENTS}}";
for (var i=0; i < referencedContents.length; i++)
{
message += (i > 0 ? ', ' : '') + referencedContents[i].title;
}
message += ".<br/>{{i18n plugin.cms:CONTENT_ARCHIVE_REFERENCED_CONTENTS_END}}";
}
Ametys.Msg.show({
title: "{{i18n plugin.cms:CONTENT_ARCHIVE_LABEL}}",
msg: message,
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.ERROR
});
}
else
{
Ametys.Msg.confirm(
"{{i18n plugin.cms:CONTENT_ARCHIVE_LABEL}}",
"{{i18n plugin.cms:CONTENT_ARCHIVE_CONFIRM}}",
function(answer)
{
if (answer == 'yes')
{
this.doArchive(args.contentIds, args.targets, args.actionId, args.controller);
}
},
this
);
}
},
/**
* Effectively archives the selected content(s).
* @param {String[]} contentIds The content ids.
* @param {Object[]} contentTargets The content targets.
* @param {String} actionId The archive action ID.
* @param {Object} controller The controller
*/
doArchive: function(contentIds, contentTargets, actionId, controller)
{
var url = 'archives/archive/' + actionId;
var viewport = Ext.ComponentQuery.query('viewport')[0];
this._count = 0;
this._cumulatedContentsTargets = [];
var archivedContentTargets = [];
Ametys.data.ServerComm.suspend();
for (var i=0; i < contentIds.length; i++)
{
var contentId = contentIds[i];
var archivedContentTarget;
for (var j=0; j < contentTargets.length; j++)
{
if (contentTargets[j].getParameters().id == contentId)
{
archivedContentTarget = contentTargets[j];
archivedContentTargets.push(archivedContentTarget);
break;
}
}
Ametys.data.ServerComm.send({
plugin: this.archivePluginName,
url: url,
parameters: {
contentId: contentId
},
waitMessage: "{{i18n plugin.cms:CONTENT_ARCHIVE_WAITING_MESSAGE}}",
callback: {
handler: this.doArchiveCallback,
scope: this,
arguments: {
id: contentId,
target: archivedContentTarget,
total: contentIds.length,
controller: controller
}
}
});
}
Ametys.data.ServerComm.restart();
},
/**
* Callback function called when the content is archived.
* Fires 'archived' message for concerned contents.
* @param {Object} response The XML response provided by the {@link Ametys.data.ServerComm}
* @param {Object} args The callback parameters passed to the {@link Ametys.data.ServerComm#send} method
* @private
*/
doArchiveCallback: function(response, args)
{
this._cumulatedContentsTargets.push(args.target);
this._count++;
if (Ametys.data.ServerComm.handleBadResponse("{{i18n plugin.cms:CONTENT_ARCHIVE_ERROR}}", response, 'Ametys.plugins.cms.content.actions.ArchiveContentAction.archive'))
{
return;
}
var total = args.total;
if (this._count == total)
{
Ext.create('Ametys.message.Message', {
type: Ametys.message.Message.ARCHIVED,
targets: this._cumulatedContentsTargets
});
}
// Force stop refreshing
args.controller.stopRefreshing(true);
},
/**
* Action which retrieves one or several content(s) from the archives.
* @param {Ametys.ribbon.element.ui.ButtonController} controller The button controller.
*/
unarchive: function(controller)
{
var contentTargets = controller.getMatchingTargets();
if (contentTargets.length > 0)
{
Ametys.Msg.confirm(
"{{i18n plugin.cms:CONTENT_UNARCHIVE_LABEL}}",
"{{i18n plugin.cms:CONTENT_UNARCHIVE_CONFIRM}}",
function(answer)
{
if (answer == 'yes')
{
var actionId = controller.getInitialConfig()['workflow-action-id'];
this.doUnarchive(contentTargets, actionId);
}
},
this
);
}
},
/**
* Effectively unarchives the selected content(s).
* @param {Object[]} contentTargets The content targets.
* @param {String} actionId The archive action ID.
*/
doUnarchive: function(contentTargets, actionId)
{
var url = 'archives/unarchive/' + actionId;
var viewport = Ext.ComponentQuery.query('viewport')[0];
var contentIds = [];
this._count = 0;
this._cumulatedContentsIds = [];
Ametys.data.ServerComm.suspend();
for (var i=0; i < contentTargets.length; i++)
{
var contentId = contentTargets[i].getParameters().id;
contentIds.push(contentId);
Ametys.data.ServerComm.send({
plugin: this.unarchivePluginName,
url: url,
parameters: {
contentId: contentId
},
waitMessage: "{{i18n plugin.cms:CONTENT_UNARCHIVE_WAITING_MESSAGE}}",
callback: {
handler: this.doUnarchiveCallback,
scope: this,
arguments: {
id: contentId,
target: contentTargets[i],
total: contentTargets.length
}
}
});
}
Ametys.data.ServerComm.restart();
},
/**
* Callback function called when the content is unarchived.
* Fires 'unarchived' message for concerned contents.
* @param {Object} response The XML response provided by the {@link Ametys.data.ServerComm}
* @param {Object} args The callback parameters passed to the {@link Ametys.data.ServerComm#send} method
* @private
*/
doUnarchiveCallback: function(response, args)
{
this._cumulatedContentsIds.push(args.id);
this._count++;
if (Ametys.data.ServerComm.handleBadResponse("{{i18n plugin.cms:CONTENT_UNARCHIVE_ERROR}}", response, 'Ametys.plugins.cms.content.actions.ArchiveContentAction.unarchive'))
{
return;
}
var total = args.total;
if (this._count == total)
{
Ext.create('Ametys.message.Message', {
type: Ametys.message.Message.UNARCHIVED,
targets: {
id: Ametys.message.MessageTarget.CONTENT,
parameters: { ids: this._cumulatedContentsIds }
}
});
}
},
/**
* Action which schedules the archiving of the selected content(s).
* @param {Ametys.ribbon.element.ui.ButtonController} controller The button controller.
*/
schedule: function(controller)
{
this._scheduleContentsId = controller.getContentIds();
if (this._scheduleContentsId.length > 0)
{
if (!this._scheduleDelayedInitialize(controller))
{
return;
}
this._scheduleInitForm(this._scheduleContentsId, controller);
this._scheduleBox.show();
}
},
/**
* Inialize the archive schedule dialog box.
* @param {Ametys.ribbon.element.ui.ButtonController} controller The button controller.
* @return {Boolean} `true` if the dialog box was sucessfully initialized.
* @private
*/
_scheduleDelayedInitialize: function(controller)
{
if (this._scheduleInitialized)
{
return true;
}
// Scheduled date
this._dateField = Ext.create('Ext.form.field.Date', {
fieldLabel: "{{i18n plugin.cms:PLUGINS_CMS_ARCHIVE_SCHEDULE_DATE}}",
ametysDescription: "{{i18n plugin.cms:PLUGINS_CMS_ARCHIVE_SCHEDULE_DATE_DESC}}",
name: 'scheduledArchivingDate',
minValue: Ext.Date.add(new Date(), Ext.Date.DAY, 1),
submitFormat: Ext.Date.patterns.ISO8601DateTime,
width: '90%',
labelWidth: 100,
cls: 'ametys',
labelSeparator: '',
labelAlign: 'right'
});
// Dialog box.
this._scheduleBox = Ext.create('Ametys.window.DialogBox', {
title: "{{i18n plugin.cms:PLUGINS_CMS_ARCHIVE_SCHEDULE_DIALOG_TITLE}}",
iconCls: 'ametysicon-archive decorator-ametysicon-clock56',
width: 410,
scrollable: true,
items: [{
xtype: 'component',
cls: 'a-text',
html: "{{i18n plugin.cms:PLUGINS_CMS_ARCHIVE_SCHEDULE_HINT}}"
},
this._dateField
],
defaultFocus: this._dateField,
closeAction: 'hide',
referenceHolder: true,
defaultButton: 'validate',
buttons : [{
reference: 'validate',
text: "{{i18n plugin.cms:PLUGINS_CMS_ARCHIVE_SCHEDULE_DIALOG_OK_BTN}}",
handler: Ext.bind(this.scheduleOk, this, [controller]),
scope: this
}, {
text: "{{i18n plugin.cms:PLUGINS_CMS_ARCHIVE_SCHEDULE_DIALOG_CANCEL_BTN}}",
handler: this.scheduleCancel,
scope: this
}]
});
this._scheduleInitialized = true;
return true;
},
/**
* Inialize the form from a list of content IDs.
* @param {String[]} contentIds An array of the selected content IDs.
* @param {Ametys.ribbon.element.ui.ButtonController} controller The button controller.
* @private
*/
_scheduleInitForm: function (contentIds, controller)
{
controller.serverCall(
'getScheduledArchivingDate', [contentIds], Ext.bind (this._scheduleInitFormCb, this), null,
{
errorMessage: {
msg: "{{i18n plugin.cms:PLUGINS_CMS_ARCHIVE_SCHEDULE_ERROR}}",
category: "Ametys.plugins.cms.content.actions.ArchiveContentAction.schedule"
}
}
);
},
/**
* Callback function invoked when the scheduling information are returned.
* @param {Object} response The JSON server response
* @param {Object} args The callback parameters
* @private
*/
_scheduleInitFormCb: function(response, args)
{
var date = response['content']['date'];
if (date)
{
this._dateField.setValue(Ext.Date.parse(date, Ext.Date.patterns.ISO8601DateTime));
}
else
{
this._dateField.setValue('');
}
},
/**
* OK button handler: send the message saving the schedule date.
* @param {Ametys.ribbon.element.ui.ButtonController} controller The button controller.
* @private
*/
scheduleOk: function (controller)
{
if (this._dateField.isValid())
{
var date = Ext.Date.format(this._dateField.getValue(), Ext.Date.patterns.ISO8601DateTime);
controller.serverCall(
'setScheduledArchivingDate', [this._scheduleContentsId, date], Ext.bind (this._scheduleOkCb, this), null,
{
errorMessage: {
msg: "{{i18n plugin.cms:PLUGINS_CMS_ARCHIVE_SCHEDULE_ERROR}}",
category: "Ametys.plugins.cms.content.actions.ArchiveContentAction.schedule"
}
}
);
}
},
/**
* Callback function invoked when the schedule date storing action has finished.
* @param {Object} result The JSON server response
* @param {Object} args The callback parameters
* @private
*/
_scheduleOkCb: function(result, args)
{
this._scheduleBox.hide();
var failedContents = result.error;
if (failedContents.length > 0)
{
var message = "{{i18n plugin.cms:PLUGINS_CMS_ARCHIVE_SCHEDULE_ERROR_WITH_CONTENTS}}" + '<ul>';
Ext.Array.each (failedContents, function (content) {
message += '<li>' + content + '</li>';
});
message += '</ul>';
Ametys.log.ErrorDialog.display({
title: "{{i18n plugin.cms:PLUGINS_CMS_ARCHIVE_SCHEDULE_ERROR_TITLE}}",
text: message,
category: 'Ametys.plugins.cms.content.actions.ArchiveContentAction.schedule'
});
}
var successContents = result.success;
if (successContents.length > 0)
{
var contentIds = [];
Ext.Array.each (successContents, function (content) {
contentIds.push(content);
});
Ext.create('Ametys.message.Message', {
type: Ametys.message.Message.MODIFIED,
parameters: {major: false},
targets: {
id: Ametys.message.MessageTarget.CONTENT,
parameters: { ids: contentIds }
}
});
}
},
/**
* Cancel button handler: close the dialog box.
* @param {Ext.button.Button} btn The clicked button.
* @private
*/
scheduleCancel: function(btn)
{
this._scheduleBox.hide();
}
});