Ext.namespace('Zarafa.common.attachment.ui');
/**
* @class Zarafa.common.attachment.ui.AttachmentDownloader
* @extends Ext.Component
* @xtype zarafa.attachmentdownloader
*
* Independent component to encapsulate process of downloading attachments,
* this is achieved by use of hidden iframe, in which we will set url of the
* attachment that needs to be downloaded. The file pointed by url should
* return attachment data with content disposition type as attachment, so
* browser will show a dialog to open/save attachment, but if the server side
* needs to send an error then make sure it returns it with content disposition
* type as inline, so that iframe's onload event will be fired and proper error
* message will be displayed to user.
*/
Zarafa.common.attachment.ui.AttachmentDownloader = Ext.extend(Ext.Component, {
/**
* @constructor
* @param {Object} config Configuration structure
*/
constructor : function(config)
{
config = config || {};
Ext.applyIf(config, {
xtype : 'zarafa.attachmentdownloader',
renderTo : Ext.getBody(),
hidden : true,
autoEl: {
tag: 'iframe',
src: Ext.SSL_SECURE_URL
}
});
Zarafa.common.attachment.ui.AttachmentDownloader.superclass.constructor.call(this, config);
//Register a listener to onload event of iframe, but please take a note that
//the 'load' event is fired only if content disposition type is configured as 'inline'.
Ext.EventManager.on(this.getEl(), 'load', this.onIframeLoad, this);
},
/**
* Will get iframe element and set its src property to the supplied url.
* After successfull response, iframe will pops up and ask user to start/cancel
* downloading of that particular message/attachment as file.
* @param {String} url The url to download message/attachment, containing necessary parameters.
*/
downloadItem : function(url)
{
var iframeElement = Ext.getDom(this.getEl());
//setting iframe's location to the download url
iframeElement.src = url;
},
/**
* Function prepares necessary HTML structure to send post request containing
* entryids of all the selected messages needs to be downloaded as eml in ZIP.
* Will get iframe element and create a form element dynamically.
* Create input elements for every entryid we need to send into post request,
* and append those dynamically created input elements into form.
*
* @param {Zarafa.core.data.IPMRecord} records The records which user want to save in eml format as ZIP.
*/
downloadMessageAsZip : function(records)
{
// Get the total size of all the messages which is requested to be included in ZIP
var totalSize = 0;
Ext.each(records, function(record) {
totalSize += record.get('message_size');
}, this);
// Check if total size of eml is more than 30 MB, avoid ZIP creation as the request will
// be timed out by the time while preparing eml for next message and there is no
// technical provision to detect request-time-out exception.
// 31457280 byte is equivalent to 30MB.
if (totalSize < 31457280) {
var url = records[0].getDownloadMessageUrl(true);
var iframeBody = Ext.getDom(this.getEl()).contentDocument.body;
var form = Ext.DomHelper.append( iframeBody || Ext.getBody(), {tag : 'form', action : url, method : 'POST'}, true);
// Create and append input elements containing entryid as its value
for (var i = 0; i < records.length; i++) {
Ext.DomHelper.append(form, {tag : 'input', type : 'hidden', name : 'entryids[]', value : records[i].get('entryid')});
}
// Submit the form to send a POST request
form.dom.submit();
} else {
container.getNotifier().notify(
'error.attachment',
_('Attachment error'),
_('Cannot create ZIP, The allowed maximum size is 30 MB.')
);
return;
}
},
/**
* Handler for the 'load' event of iframe, fired immediately after iframe is loaded.
* The exception response is received in json format, so we are using {@link Ext.util.JSON#decode}
* to decode (parse) a JSON string to an object.
* @private
*/
onIframeLoad : function()
{
var contentDocument;
var responseText;
contentDocument = this.getEl().dom.contentDocument;
if (!Ext.isEmpty(contentDocument)) {
responseText = contentDocument.body.textContent;
}
if (!Ext.isEmpty(responseText)) {
var responseObject = Ext.util.JSON.decode(responseText);
this.displaySaveEmailException(responseObject);
}
},
/**
* Raise a warning dialog to inform user that there is some embedded attachments which can not be included in ZIP.
* otherwise continue with creating ZIP for normal attachments.
*
* @param {Zarafa.core.data.IPMAttachmentRecord} records The record of the file to be downloaded
* @param {Boolean} allAsZip (optional) True to downloading all the attachments as ZIP
*/
checkForEmbeddedAttachments : function(record, allAsZip)
{
var containsEmbedded = false;
var attachmentStore = record.store;
// We need all this additional checking only when we are going to download attachments as ZIP, skip otherwise.
if(allAsZip) {
// If user already made his/her decision to not show this warning again then it is there is state setting, just act accordingly.
var dontShowWarning = container.getSettingsModel().get('zarafa/v1/state/dialogs/mixattachitemcontentpanel/dontshowagain');
// Check if there is any embedded attachments only when user want this warning to be raised
// and there is more than one attachments.
if(!dontShowWarning && attachmentStore.getCount() > 1) {
attachmentStore.each(function(record){
if(record.isEmbeddedMessage()){
containsEmbedded = true;
return false;
}
});
}
}
// Embedded attachment(s) found, raise warning dialog
if(containsEmbedded) {
this.openMixAttachmentsDialog(attachmentStore.getRange(), {'allAsZip' : allAsZip});
} else {
this.downloadItem(record.getAttachmentUrl(allAsZip));
}
},
/**
* Opens a {@link Zarafa.common.attachment.dialogs.MixAttachItemContentPanel MixAttachItemContentPanel} for informing
* user that there is some embedded attachments are requested to be included in ZIP, which is not possible.
*
* @param {Zarafa.core.data.IPMRecord} records The record, or records for which the attachments are
* requested to be downloaded as ZIP
* @param {Object} config (optional) Configuration object for creating the ContentPanel
*/
openMixAttachmentsDialog : function(records, config)
{
if (!Array.isArray(records)) {
records = [ records ];
}
config = Ext.applyIf(config || {}, {
modal : true,
downloadItem : this.downloadItem.createDelegate(this, [ records[0].getAttachmentUrl(config.allAsZip) ], 1)
});
var componentType = Zarafa.core.data.SharedComponentType['common.attachment.dialog.mixattachitem'];
Zarafa.core.data.UIFactory.openLayerComponent(componentType, records, config);
},
/**
* It displays proper message to user, as per the exception received
* while unsuccessful download.
* @param {Object} responseObject Object contained the exception details.
* @private
*/
displaySaveEmailException : function(responseObject)
{
Ext.MessageBox.show({
title : _('Kopano WebApp'),
msg : responseObject.zarafa.error.info.display_message,
icon: Ext.MessageBox.ERROR,
buttons : Ext.MessageBox.OK
});
}
});
Ext.reg('zarafa.attachmentdownloader', Zarafa.common.attachment.ui.AttachmentDownloader);