/*
* Copyright 2013 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.
*/
/**
* Singleton class to save content modifications
* @private
*/
Ext.define('Ametys.plugins.cms.content.actions.SaveAction', {
singleton: true,
/**
* Action function to be called by the controller.
* Quit the edition without saving
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
unsave: function (controller)
{
var target = controller.getMatchingTargets()[0];
var contentId = target.getParameters().id;
var tool = Ametys.tool.ToolsManager.getFocusedTool();
if (tool.isDirty())
{
Ametys.Msg.confirm("{{i18n CONTENT_EDITION_UNSAVE_LABEL}}",
"{{i18n CONTENT_EDITION_UNSAVE_CONFIRM}}",
Ext.bind(this._unsaveConfirm, this, [controller], 1),
this
);
}
else
{
this._unsaveConfirm('yes', controller);
}
},
/**
* Callback function invoked after the 'unsave' confirm box is closed
* @param {String} answer Id of the button that was clicked
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the #unsave function
* @private
*/
_unsaveConfirm: function (answer, controller)
{
if (answer == 'yes')
{
var target = controller.getMatchingTargets()[0];
var contentId = target.getParameters().id;
var tool = Ametys.tool.ToolsManager.getFocusedTool();
// Delete the automatic save.
Ametys.data.ServerComm.callMethod({
role: "org.ametys.cms.content.autosave.ContentBackupClientInteraction",
methodName: "deleteContentBackup",
parameters: [contentId],
callback: {
scope: this,
handler: this._deleteAutoBackupCb
},
errorMessage: false
});
tool.quitEditionMode();
tool.fireMessagesOnSuccessEdition();
// Unlock content
Ametys.cms.content.ContentDAO.unlockContent(contentId, target.getId());
}
},
/**
* Action function to be called by the controller.
* Will save the content modifications
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
save: function (controller)
{
this._startSave(controller, false, false);
},
/**
* Action function to be called by the controller.
* Will save the content modifications and quit edition form
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
saveAndQuit: function (controller)
{
this._startSave(controller, true, false);
},
/**
* Action function to save the content modifications
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
* @param {Boolean} quit true to quit edition form after saving modifications
* @param {Boolean} ignoreWarnings True to ignore warnings from server response
* @private
*/
_startSave: function (controller, quit, ignoreWarnings)
{
var form = Ametys.form.SaveHelper.getForm(controller.getMatchingTargets());
if (form != null)
{
var target = controller.getMatchingTargets()[0];
var contentId = target.getParameters().id;
var tool = Ametys.tool.ToolsManager.getFocusedTool();
// Validate form
var invalidFields = Ext.Array.merge(form.getInvalidFields(), form.getInvalidRepeaters());
if (invalidFields.length > 0)
{
Ametys.Msg.show({
title: "{{i18n PLUGINS_CMS_SAVE_ACTION_SAVE}}", //{{i18n CONTENT_EDITION_SAVE_LABEL}}",
msg: "{{i18n PLUGINS_CMS_SAVE_ACTION_INVALIDFIELDS}}" + Ametys.form.SaveHelper.getInvalidFieldsAsReadableList(invalidFields), //"{{i18n CONTENT_EDITION_SAVE_INVALID_FIELD}}",
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.ERROR
});
return;
}
var warnedFields = form.getWarnedFields();
if (!Ext.Object.isEmpty(warnedFields))
{
Ametys.Msg.show({
title: "{{i18n PLUGINS_CMS_SAVE_ACTION_SAVE}}",
msg: "{{i18n PLUGINS_CMS_SAVE_ACTION_WARNED_FIELDS_START}}" + Ametys.form.SaveHelper.getWarnedFieldsAsReadableList(warnedFields) + "{{i18n PLUGINS_CMS_SAVE_ACTION_WARNED_FIELDS_END}}",
buttons: Ext.Msg.YESNO,
icon: Ext.Msg.QUESTION,
modal: true,
fn: Ext.bind (this._bypassWarnedFields, this, [tool, form, contentId, quit, ignoreWarnings], 1),
scope: this
});
return;
}
this._continueSave (tool, form, contentId, quit, ignoreWarnings);
}
},
/**
* @private
* Next step to save the content
* @param {Ametys.tool.Tool} tool The content tool
* @param {Ametys.form.ConfigurableFormPanel} form The form panel
* @param {String} contentId The content id
* @param {Boolean} quit True to quit edition after saving
* @param {Boolean} ignoreWarnings True to ignore warnings during content modification
*/
_continueSave: function(tool, form, contentId, quit, ignoreWarnings)
{
let me = this;
// Determine if base version is still ok
tool._getData(next);
function _toReadableVersion(v)
{
let i = v.indexOf(".");
return parseInt(v.substring(i + 1)) + 1;
}
function next(response)
{
let currentData = tool._extractDataFromResponse(response);
tool.form.getField(tool.form.fieldNamePrefix + "_version").setValue(currentData.version);
if (tool._baseData.version == currentData.version
|| !currentData
|| currentData.data == tool._baseData.data)
{
me._doSave (tool, form, contentId, quit, ignoreWarnings);
}
else
{
// Show warning
Ametys.form.SaveHelper.SaveErrorDialog.showWarningDialog(
"{{i18n CONTENT_EDITION_VALIDATION_ERRORS_VERSION_COLLISION_TITLE}}",
"",
new Ext.Template("<p style='padding: 0 10px'>{{i18n plugin.cms:CONTENT_EDITION_VALIDATION_ERRORS_VERSION_COLLISION}}</p>").apply([
"Ext.getCmp(Ext.fly(this).findParent('.ametys-dialogbox').id).close(); Ametys.tool.ToolsManager.openTool('uitool-diff-content', { id: '" + contentId + "', contentId: '" + contentId + "', baseVersion: '" + tool._baseData.version + "', version: '" + currentData.version + "'" + (tool._viewName ? ", 'view-name': '" + tool._viewName + "'" : "") + ", 'allData': false });",
_toReadableVersion(tool._baseData.version),
_toReadableVersion(currentData.version)
]),
"{{i18n PLUGINS_CMS_SAVE_ACTION_WARNING_DESC_QUESTION}}",
function(yes) {
if (yes)
{
me._doSave (tool, form, contentId, quit, ignoreWarnings);
}
}
);
}
}
},
/**
* @private
* Save the content
* @param {Ametys.tool.Tool} tool The content tool
* @param {Ametys.form.ConfigurableFormPanel} form The form panel
* @param {String} contentId The content id
* @param {Boolean} quit True to quit edition after saving
* @param {Boolean} ignoreWarnings True to ignore warnings during content modification
*/
_doSave: function (tool, form, contentId, quit, ignoreWarnings)
{
// Disarm the autosave timer function.
tool.clearAutosaveTimeout();
var params = {};
params.values = form.getJsonValues();
params.contentId = contentId;
params.unlock = quit;
params.editWorkflowActionId = tool._workflowAction;
params.viewName = tool._viewName;
params.fallbackViewName = tool._fallbackViewName;
params.bypassedWarnings = form.getWarnedFields();
params.ignoreWarnings = ignoreWarnings;
Ametys.cms.content.ContentDAO.editContent(params, Ext.bind(this._saveCb, this, [quit, form, tool], true), this, false, null, null, tool.getContentPanel());
tool.fireMessageBeforeSaving();
},
/**
* @private
* This function is called after validated confirm dialog box
* @param {String} answer The button answer ('yes' or 'no')
* @param {Ametys.tool.Tool} tool The content tool
* @param {Ametys.form.ConfigurableFormPanel} form The form panel
* @param {String} contentId The content id
* @param {Boolean} quit True to quit edition after saving
* @param {Boolean} ignoreWarnings True to ignore warnings from server response
*/
_bypassWarnedFields : function (answer, tool, form, contentId, quit, ignoreWarnings)
{
if (answer == 'yes')
{
this._continueSave (tool, form, contentId, quit, ignoreWarnings);
}
},
/**
* Callback function called after #_doSave is processed.
* Fires {@link Ametys.message.Message#MODIFIED} message for edited contents
* @param {boolean} success If the save was successful
* @param {String} contentId The content id
* @param {String[]} workflowErrors Errors messages related to the workflow
* @param {Object} fieldsInError The list of fields in error associated with their error message
* @param {Object} fieldsWithWarning The list of fields with warning associated with their warning message
* @param {Boolean} ignoreWarnings True to ignore warnings from server response
* @param {Boolean} quit True to quit edition after saving
* @param {Ametys.form.ConfigurableFormPanel} form The form panel
* @param {Ametys.tool.Tool} tool The content tool
* @private
*/
_saveCb: function (success, contentId, workflowErrors, fieldsInError, fieldsWithWarning, ignoreWarnings, quit, form, tool)
{
// Re-arm the autosave timer function.
tool.armAutosaveTimeout();
if (!success && workflowErrors == null && fieldsInError == null)
{
tool.fireMessageOnFailEdition();
return;
}
if (!success && !Ext.Object.isEmpty(fieldsInError))
{
form.markFieldsInvalid (fieldsInError);
return;
}
if (!success && ignoreWarnings)
{
// The ignore warning can only be set to true if there was warnings
// But it can be warnings from global validator, then fieldsWithWarning is empty
this._doSave (tool, form, contentId, quit, true);
return;
}
if (!success && !Ext.Object.isEmpty(fieldsWithWarning))
{
form.markFieldsWarning (fieldsWithWarning);
return;
}
if (!success)
{
return;
}
// If the current content has indexing references, send a message.
if (tool.hasIndexingReferences())
{
Ametys.Msg.show({
title: "{{i18n PLUGINS_CMS_SAVE_ACTION_CONTENT_MODIFICATION}}",
msg: "{{i18n PLUGINS_CMS_SAVE_ACTION_CONTENT_HAS_INDEXING_REFERENCES}}",
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.INFO
});
}
// Delete the automatic save.
Ametys.data.ServerComm.callMethod({
role: "org.ametys.cms.content.autosave.ContentBackupClientInteraction",
methodName: "deleteContentBackup",
parameters: [contentId],
callback: {
scope: this,
handler: this._deleteAutoBackupCb
},
errorMessage: false
});
if (quit)
{
tool.quitEditionMode ();
}
else
{
// update base data
tool._getData(function(response) {
tool._baseData = tool._extractDataFromResponse(response);
});
}
tool.setDirty(false);
tool.fireMessagesOnSuccessEdition();
},
/**
* Callback invoked when an automatic save is deleted.
* @param {Object} response The XML response provided by the {@link Ametys.data.ServerComm}
* @param {Object} params The callback parameters passed to the {@link Ametys.data.ServerComm#send} method
* @private
*/
_deleteAutoBackupCb: function(response, params)
{
// Ignore the callback.
}
});