/*
* Copyright 2014 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 defining the actions on comments
* @private
*/
Ext.define('Ametys.plugins.cms.comment.CommentActions', {
singleton: true,
/**
* Action to edit a comment
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
edit: function (controller)
{
var commentTarget = controller.getMatchingTargets()[0];
if (commentTarget != null)
{
this._delayedInitialized(controller);
this._box.show();
this._initForm (commentTarget, controller);
}
},
/**
* @private
* Creates the dialog box
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
_delayedInitialized: function (controller)
{
if (this._initialized)
{
return;
}
this._form = Ext.create('Ext.form.Panel', {
border: false,
defaults: {
cls: 'ametys',
width: 360,
xtype: 'textfield',
msgTarget: 'side',
labelSeparator: '',
labelAlign: 'right'
},
items : [{
name: 'contentId',
xtype: 'hidden'
},
{
name: 'commentId',
xtype: 'hidden'
},
{
itemId: 'author-name',
name: 'author-name',
fieldLabel: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_EDIT_DIALOG_AUTHORNAME}}",
ametysDescription: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_EDIT_DIALOG_AUTHORNAME_DESC}}",
allowBlank: false
},
{
name: 'author-email',
fieldLabel: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_EDIT_DIALOG_AUTHOREMAIL}}",
ametysDescription: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_EDIT_DIALOG_AUTHOREMAIL_DESC}}",
regex: /^([a-z0-9._-]+@[a-z0-9.-]{2,}[.][a-z]{2,3})?$/
},
{
xtype: 'checkboxfield',
name: 'author-emailhidden',
inputValue: true,
uncheckedValue: false,
fieldLabel: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_EDIT_DIALOG_AUTHOREMAILHIDDEN}}",
ametysDescription: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_EDIT_DIALOG_AUTHOREMAILHIDDEN_DESC}}"
},
{
name: 'author-url',
fieldLabel: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_EDIT_DIALOG_AUTHORHOMEPAGE}}",
ametysDescription: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_EDIT_DIALOG_AUTHORHOMEPAGE_DESC}}",
regex: /^(https?:\/\/.+)?$/
},
{
xtype: 'textarea',
name: 'text',
fieldLabel: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_EDIT_DIALOG_CONTENT}}",
ametysDescription: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_EDIT_DIALOG_CONTENT_DESC}}",
height: 100,
allowBlank: false
}
]
});
this._box = Ext.create('Ametys.window.DialogBox', {
title :"{{i18n PLUGINS_CMS_CONTENT_COMMENTS_EDIT_DIALOG_CAPTION}}",
icon : Ametys.getPluginResourcesPrefix('cms') + "/img/content/comments/edit_comment_16.png",
width: 420,
scrollable: true,
layout: "fit",
items: [ this._form ],
defaultFocus: 'author-name',
closeAction: 'hide',
referenceHolder: true,
defaultButton: 'validate',
buttons : [{
reference: 'validate',
text :"{{i18n PLUGINS_CMS_CONTENT_COMMENTS_EDIT_DIALOG_OK}}",
handler : Ext.bind (this._save, this, [controller]),
scope: this
}, {
text :"{{i18n PLUGINS_CMS_CONTENT_COMMENTS_EDIT_DIALOG_CANCEL}}",
handler : function () { this._box.close()},
scope: this
} ]
});
this._initialized = true;
},
/**
* Init the form
* @param {Ametys.message.MessageTarget} commentTarget The comment target to edit
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
_initForm: function (commentTarget, controller)
{
this._mask = Ext.create('Ext.LoadMask', {
target: this._box,
msg: "{{i18n plugin.core-ui:PLUGINS_CORE_UI_LOADMASK_DEFAULT_MESSAGE}}"
});
this._mask.show();
controller.serverCall('getComment', [commentTarget.getParameters().content, commentTarget.getParameters().id], Ext.bind(this._initFormCb, this),
{
errorMessage: {
msg: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_EDIT_DIALOG_ERROROPEN}}",
category: 'Ametys.plugins.cms.comment.CommentActions.edit'
}
});
},
/**
* @private
* Callback function called after #_initForm is processed
* Fills the edition form
* @param {Object[]} response the server's response
*/
_initFormCb: function (response)
{
if (response['comments'] == null)
{
return;
}
var comment = response['comments']['comment'];
var form = this._form.getForm();
form.findField('commentId').setValue(comment['id']);
form.findField('contentId').setValue(comment['content']['id']);
form.findField('author-name').setValue(comment['author-name']);
var email = comment['author-email'];
form.findField('author-email').setValue(email != null ? email['value'] : '');
form.findField('author-emailhidden').setValue(email != null ? email['hidden'] == 'true' : false);
form.findField('author-url').setValue(comment['author-url']);
form.findField('text').setValue(comment['text']);
if (this._mask)
{
this._mask.hide();
delete this._mask;
}
},
/**
* @private
* Submit the form to save modifications
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
_save: function (controller)
{
var form = this._form.getForm();
if (!form.isValid())
{
return;
}
var params = form.getValues();
controller.serverCall('editComment', [params], Ext.bind(this._saveCb, this),
{
errorMessage: {
msg: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_EDIT_DIALOG_ERRORSAVE}}",
category: 'Ametys.plugins.cms.comment.CommentActions.edit'
}
});
},
/**
* Callback function after saving
* @param {Object[]} response the server's response in JSON.
*/
_saveCb: function (response)
{
Ext.create("Ametys.message.Message", {
type: Ametys.message.Message.MODIFIED,
targets: {
id: Ametys.message.MessageTarget.COMMENT,
parameters: {
id: response.id,
content: response.contentId,
reportsCount: response.reportsCount
}
}
});
this._box.hide();
},
// ------------------------ REMOVE ------------------------------------//
/**
* Action to delete comments
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
remove: function (controller)
{
var commentTargets = controller.getMatchingTargets();
if (commentTargets.length > 0)
{
Ametys.Msg.confirm("{{i18n PLUGINS_CMS_CONTENT_COMMENTS_DELETE_CONFIRM_TITLE}}",
"{{i18n PLUGINS_CMS_CONTENT_COMMENTS_DELETE_CONFIRM_DESCRIPTION}}",
Ext.bind(this._doRemove, this, [controller, commentTargets], 1),
this
);
}
},
/**
* Callback function invoked after the #remove 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 #act function
* @param {Ametys.message.MessageTarget[]} commentTargets The registered comments targets
* @private
*/
_doRemove: function (answer, controller, commentTargets)
{
if (answer == 'yes')
{
var contentIds = {};
for (var i=0; i < commentTargets.length; i++)
{
var contentId = commentTargets[i].getParameters().content;
if (!contentIds[contentId])
{
contentIds[contentId] = [];
}
contentIds[contentId].push(commentTargets[i].getParameters().id);
}
controller.serverCall('deleteComments', [contentIds], Ext.bind(this._removeCb, this),
{
errorMessage: {
msg: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_DELETE_UNKNOWN_ERROR}}",
category: 'Ametys.plugins.cms.comment.CommentActions.remove'
}
});
}
},
/**
* @private
* Callback function called after removing comments
* @param {Object[]} response the server's response in JSON.
*/
_removeCb: function (response)
{
var errorMsg = '';
errorMsg += this._getErrorMsg("{{i18n PLUGINS_CMS_CONTENT_COMMENTS_ERROR_UNKNOWN_CONTENTS}}", response['unknown-contents'], 'contentId');
errorMsg += this._getErrorMsg("{{i18n PLUGINS_CMS_CONTENT_COMMENTS_ERROR_NORIGHT_CONTENTS}}", response['noright-contents'], 'contentTitle');
errorMsg += this._getErrorMsg("{{i18n PLUGINS_CMS_CONTENT_COMMENTS_ERROR_UNCOMMENTABLE_CONTENTS}}", response['uncommentable-contents'], 'contentTitle');
errorMsg += this._getErrorMsg("{{i18n PLUGINS_CMS_CONTENT_COMMENTS_ERROR_UNKNOWN_COMMENTS}}", response['undeleted-comments'], 'contentTitle');
if (errorMsg.length > 0)
{
Ametys.log.ErrorDialog.display({
title: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_DELETE_ERRORS_TITLE}}",
text: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_DELETE_ERRORS_DESC}}",
details: errorMsg,
category: 'Ametys.plugins.cms.comment.CommentActions.remove'
});
}
var targets = [];
var deletedComments = response['deleted-comments'];
for (var i=0; i < deletedComments.length; i++)
{
targets.push({
id: Ametys.message.MessageTarget.COMMENT,
parameters: {
id: deletedComments[i].id,
content: deletedComments[i].contentId,
reportsCount: 0
}
});
}
if (targets.length > 0)
{
Ext.create("Ametys.message.Message", {
type: Ametys.message.Message.DELETED,
targets: targets
});
}
},
/**
* @private
* Constructs the error message
* @param {String} intro The introduction text
* @param {Object[]} elmts The elements in error
* @param {String} name The attribute to display for elements in error
*/
_getErrorMsg: function (intro, elmts, name)
{
if (elmts.length > 0)
{
var elmt = [];
for (var i=0; i < elmts.length; i++)
{
elmt.push(elmts[name])
}
return intro + elmt.join(', ') + '<br/>';
}
return '';
},
// ----------------------------- VALIDATE ------------------------------------//
/**
* Action to validate comments
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
validate: function (controller)
{
var comments = controller._matchingComments;
var contentIds = {};
for (var i=0; i < comments.length; i++)
{
var contentId = comments[i].content;
if (!contentIds[contentId])
{
contentIds[contentId] = [];
}
contentIds[contentId].push(comments[i].id);
}
controller.serverCall('validateComments', [contentIds], Ext.bind(this._validateCb, this),
{
errorMessage: {
msg: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_VALIDATE_UNKNOWN_ERROR}}",
category: 'Ametys.plugins.cms.comment.CommentActions.validate'
}
});
},
/**
* @private
* Callback function called after validating comments
* @param {Object[]} response The server's response in JSON.
*/
_validateCb: function (response)
{
var errorMsg = '';
errorMsg += this._getErrorMsg("{{i18n PLUGINS_CMS_CONTENT_COMMENTS_ERROR_UNKNOWN_CONTENTS}}", response['unknown-contents'], 'contentId');
errorMsg += this._getErrorMsg("{{i18n PLUGINS_CMS_CONTENT_COMMENTS_ERROR_NORIGHT_CONTENTS}}", response['noright-contents'], 'contentTitle');
errorMsg += this._getErrorMsg("{{i18n PLUGINS_CMS_CONTENT_COMMENTS_ERROR_UNCOMMENTABLE_CONTENTS}}", response['uncommentable-contents'], 'contentTitle');
errorMsg += this._getErrorMsg("{{i18n PLUGINS_CMS_CONTENT_COMMENTS_ERROR_UNKNOWN_COMMENTS}}", response['error-comments'], 'contentTitle');
if (errorMsg.length > 0)
{
Ametys.log.ErrorDialog.display({
title: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_VALIDATE_ERRORS_TITLE}}",
text: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_VALIDATE_ERRORS_DESC}}",
details: errorMsg,
category: 'Ametys.plugins.cms.comment.CommentActions.validate'
});
}
var targets = [];
var validatedComments = response['validated-comments'];
for (var i=0; i < validatedComments.length; i++)
{
targets.push({
id: Ametys.message.MessageTarget.COMMENT,
parameters: {
id: validatedComments[i].id,
content: validatedComments[i].contentId,
reportsCount: validatedComments[i].reportsCount
}
});
}
if (targets.length > 0)
{
Ext.create("Ametys.message.Message", {
type: Ametys.message.Message.MODIFIED,
targets: targets
});
}
},
// ----------------------------- INVALIDATE ------------------------------------//
/**
* Action to invalidate comments
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
invalidate: function (controller)
{
var comments = controller._matchingComments;
var contentIds = {};
for (var i=0; i < comments.length; i++)
{
var contentId = comments[i].content;
if (!contentIds[contentId])
{
contentIds[contentId] = [];
}
contentIds[contentId].push(comments[i].id);
}
controller.serverCall('invalidateComments', [contentIds], Ext.bind(this._invalidateCb, this),
{
errorMessage: {
msg: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_INVALIDATE_UNKNOWN_ERROR}}",
category: 'Ametys.plugins.cms.comment.CommentActions.invalidate'
}
});
},
/**
* @private
* Callback function called after invalidating comments
* @param {Object[]} response The server's response in JSON.
*/
_invalidateCb: function (response)
{
var errorMsg = '';
errorMsg += this._getErrorMsg("{{i18n PLUGINS_CMS_CONTENT_COMMENTS_ERROR_UNKNOWN_CONTENTS}}", response['unknown-contents'], 'contentId');
errorMsg += this._getErrorMsg("{{i18n PLUGINS_CMS_CONTENT_COMMENTS_ERROR_NORIGHT_CONTENTS}}", response['noright-contents'], 'contentTitle');
errorMsg += this._getErrorMsg("{{i18n PLUGINS_CMS_CONTENT_COMMENTS_ERROR_UNCOMMENTABLE_CONTENTS}}", response['uncommentable-contents'], 'contentTitle');
errorMsg += this._getErrorMsg("{{i18n PLUGINS_CMS_CONTENT_COMMENTS_ERROR_UNKNOWN_COMMENTS}}", response['error-comments'], 'contentTitle');
if (errorMsg.length > 0)
{
Ametys.log.ErrorDialog.display({
title: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_INVALIDATE_ERRORS_TITLE}}",
text: "{{i18n PLUGINS_CMS_CONTENT_COMMENTS_INVALIDATE_ERRORS_DESC}}",
details: errorMsg,
category: 'Ametys.plugins.cms.comment.CommentActions.invalidate'
});
}
var targets = [];
var unvalidatedComments = response['unvalidated-comments'];
for (var i=0; i < unvalidatedComments.length; i++)
{
targets.push({
id: Ametys.message.MessageTarget.COMMENT,
parameters: {
id: unvalidatedComments[i].id,
content: unvalidatedComments[i].contentId,
reportsCount: unvalidatedComments[i].reportsCount
}
});
}
if (targets.length > 0)
{
Ext.create("Ametys.message.Message", {
type: Ametys.message.Message.MODIFIED,
targets: targets
});
}
}
});