code beautifications

This commit is contained in:
Christoph Haas 2016-06-13 22:59:05 +02:00
parent 21af50aa6c
commit 4ce04ab6f9
12 changed files with 682 additions and 614 deletions

View File

@ -1,12 +1,10 @@
<?php
/** Disable the import plugin for all clients */
define('PLUGIN_CONTACTIMPORTER_USER_DEFAULT_ENABLE', false);
/** Disable the export feature for all clients */
define('PLUGIN_CONTACTIMPORTER_USER_DEFAULT_ENABLE_EXPORT', false);
/** Disable the import plugin for all clients */
define('PLUGIN_CONTACTIMPORTER_USER_DEFAULT_ENABLE', false);
/** The default addressbook to import to (default: contact)*/
define('PLUGIN_CONTACTIMPORTER_DEFAULT', "contact");
/** The default addressbook to import to (default: contact)*/
define('PLUGIN_CONTACTIMPORTER_DEFAULT', "contact");
/** Tempory path for uploaded files... */
define('PLUGIN_CONTACTIMPORTER_TMP_UPLOAD', "/var/lib/zarafa-webapp/tmp/");
/** Tempory path for uploaded files... */
define('PLUGIN_CONTACTIMPORTER_TMP_UPLOAD', "/var/lib/zarafa-webapp/tmp/");
?>

View File

@ -29,30 +29,30 @@ Ext.namespace('Zarafa.plugins.contactimporter');
* The copyright string holding the copyright notice for the Zarafa contactimporter Plugin.
*/
Zarafa.plugins.contactimporter.ABOUT = ""
+ "<p>Copyright (C) 2012-2013 Christoph Haas &lt;christoph.h@sprinternet.at&gt;</p>"
+ "<p>Copyright (C) 2012-2016 Christoph Haas &lt;christoph.h@sprinternet.at&gt;</p>"
+ "<p>This program is free software; you can redistribute it and/or "
+ "modify it under the terms of the GNU Lesser General Public "
+ "License as published by the Free Software Foundation; either "
+ "version 2.1 of the License, or (at your option) any later version.</p>"
+ "<p>This program is free software; you can redistribute it and/or "
+ "modify it under the terms of the GNU Lesser General Public "
+ "License as published by the Free Software Foundation; either "
+ "version 2.1 of the License, or (at your option) any later version.</p>"
+ "<p>This program is distributed in the hope that it will be useful, "
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of "
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU "
+ "Lesser General Public License for more details.</p>"
+ "<p>This program is distributed in the hope that it will be useful, "
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of "
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU "
+ "Lesser General Public License for more details.</p>"
+ "<p>You should have received a copy of the GNU Lesser General Public "
+ "License along with this program; if not, write to the Free Software "
+ "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA</p>"
+ "<p>You should have received a copy of the GNU Lesser General Public "
+ "License along with this program; if not, write to the Free Software "
+ "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA</p>"
+ "<hr />"
+ "<hr />"
+ "<p>The contactimporter plugin contains the following third-party components:</p>"
+ "<p>The contactimporter plugin contains the following third-party components:</p>"
+ "<h1>vCard-parser</h1>"
+ "<h1>vCard-parser</h1>"
+ "<p>Copyright (C) 2012 Nuovo</p>"
+ "<p>Copyright (C) 2016 Jeroen Desloovere</p>"
+ "<p>Licensed under the MIT License.</p>"
+ "<p>Licensed under the MIT License.</p>"
+ "<p>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.</p>"
+ "<p>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.</p>"

View File

@ -2,7 +2,7 @@
* ResponseHandler.js zarafa contact im/exporter
*
* Author: Christoph Haas <christoph.h@sprinternet.at>
* Copyright (C) 2012-2013 Christoph Haas
* Copyright (C) 2012-2016 Christoph Haas
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -38,13 +38,13 @@ Zarafa.plugins.contactimporter.data.ResponseHandler = Ext.extend(Zarafa.core.dat
* @cfg {Function} successCallback The function which
* will be called after success request.
*/
successCallback : null,
successCallback: null,
/**
* Call the successCallback callback function.
* @param {Object} response Object contained the response data.
*/
doLoad : function(response) {
doLoad: function (response) {
this.successCallback(response);
},
@ -52,7 +52,7 @@ Zarafa.plugins.contactimporter.data.ResponseHandler = Ext.extend(Zarafa.core.dat
* Call the successCallback callback function.
* @param {Object} response Object contained the response data.
*/
doImport : function(response) {
doImport: function (response) {
this.successCallback(response);
},
@ -60,7 +60,7 @@ Zarafa.plugins.contactimporter.data.ResponseHandler = Ext.extend(Zarafa.core.dat
* Call the successCallback callback function.
* @param {Object} response Object contained the response data.
*/
doExport : function(response) {
doExport: function (response) {
this.successCallback(response);
},
@ -68,7 +68,7 @@ Zarafa.plugins.contactimporter.data.ResponseHandler = Ext.extend(Zarafa.core.dat
* Call the successCallback callback function.
* @param {Object} response Object contained the response data.
*/
doImportattachment : function(response) {
doImportattachment: function (response) {
this.successCallback(response);
},
@ -77,7 +77,7 @@ Zarafa.plugins.contactimporter.data.ResponseHandler = Ext.extend(Zarafa.core.dat
* exception response with the code of exception.
* @param {Object} response Object contained the response data.
*/
doError: function(response) {
doError: function (response) {
alert("error response code: " + response.error.info.code);
}
});

View File

@ -2,7 +2,7 @@
* ImportContentPanel.js zarafa contact to vcf im/exporter
*
* Author: Christoph Haas <christoph.h@sprinternet.at>
* Copyright (C) 2012-2013 Christoph Haas
* Copyright (C) 2012-2016 Christoph Haas
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -40,23 +40,20 @@ Zarafa.plugins.contactimporter.dialogs.ImportContentPanel = Ext.extend(Zarafa.co
* @constructor
* @param config Configuration structure
*/
constructor : function(config) {
constructor: function (config) {
config = config || {};
var title = _('Import Contacts');
if(container.getSettingsModel().get("zarafa/v1/plugins/contactimporter/enable_export")){
title = _('Import/Export Contacts');
}
Ext.applyIf(config, {
layout : 'fit',
title : title,
closeOnSave : true,
closeOnSave: true,
width : 620,
height : 465,
//Add panel
items : [
{
xtype : 'contactimporter.importcontactpanel',
filename : config.filename
filename: config.filename
}
]
});
@ -66,4 +63,4 @@ Zarafa.plugins.contactimporter.dialogs.ImportContentPanel = Ext.extend(Zarafa.co
});
Ext.reg('contactimporter.contentpanel' ,Zarafa.plugins.contactimporter.dialogs.ImportContentPanel);
Ext.reg('contactimporter.contentpanel', Zarafa.plugins.contactimporter.dialogs.ImportContentPanel);

View File

@ -2,7 +2,7 @@
* ImportPanel.js zarafa contact to vcf im/exporter
*
* Author: Christoph Haas <christoph.h@sprinternet.at>
* Copyright (C) 2012-2013 Christoph Haas
* Copyright (C) 2012-2016 Christoph Haas
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -37,17 +37,17 @@ Zarafa.plugins.contactimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
vcffile: null,
/* The store for the selection grid */
store: null,
store : null,
/**
* @constructor
* @param {object} config
*/
constructor : function (config) {
constructor: function (config) {
config = config || {};
var self = this;
if(!Ext.isEmpty(config.filename)) {
if (!Ext.isEmpty(config.filename)) {
this.vcffile = config.filename;
}
@ -68,33 +68,33 @@ Zarafa.plugins.contactimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
ref : "importcontactpanel",
layout : {
type : 'form',
align : 'stretch'
align: 'stretch'
},
anchor : '100%',
bodyStyle : 'background-color: inherit;',
bodyStyle: 'background-color: inherit;',
defaults : {
border : true,
bodyStyle : 'background-color: inherit; padding: 3px 0px 3px 0px; border-style: none none solid none;'
bodyStyle: 'background-color: inherit; padding: 3px 0px 3px 0px; border-style: none none solid none;'
},
items : [
this.createSelectBox(),
this.initForm(),
this.createGrid()
],
buttons: [
buttons : [
this.createSubmitAllButton(),
this.createSubmitButton(),
this.createCancelButton()
],
listeners: {
afterrender: function (cmp) {
this.loadMask = new Ext.LoadMask(this.getEl(), {msg:'Loading...'});
this.loadMask = new Ext.LoadMask(this.getEl(), {msg: 'Loading...'});
if(this.vcffile != null) { // if we have got the filename from an attachment
if (this.vcffile != null) { // if we have got the filename from an attachment
this.parseContacts(this.vcffile);
}
},
scope: this
scope : this
}
});
@ -106,22 +106,22 @@ Zarafa.plugins.contactimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
* posted and contains the attachments
* @private
*/
initForm : function () {
initForm: function () {
return {
xtype: 'form',
ref: 'addContactFormPanel',
xtype : 'form',
ref : 'addContactFormPanel',
layout : 'column',
fileUpload: true,
autoWidth: true,
autoWidth : true,
autoHeight: true,
border: false,
bodyStyle: 'padding: 5px;',
defaults: {
anchor: '95%',
border: false,
border : false,
bodyStyle : 'padding: 5px;',
defaults : {
anchor : '95%',
border : false,
bodyStyle: 'padding: 5px;'
},
items: [this.createUploadField()]
items : [this.createUploadField()]
};
},
@ -129,13 +129,13 @@ Zarafa.plugins.contactimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
* Reloads the data of the grid
* @private
*/
reloadGridStore: function(contactdata) {
reloadGridStore: function (contactdata) {
var parsedData = [];
if(contactdata) {
if (contactdata) {
parsedData = new Array(contactdata.contacts.length);
var i = 0;
for(i = 0; i < contactdata.contacts.length; i++) {
for (i = 0; i < contactdata.contacts.length; i++) {
parsedData[i] = [
contactdata.contacts[i]["display_name"],
@ -157,36 +157,36 @@ Zarafa.plugins.contactimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
* posted and contains the attachments
* @private
*/
createGrid : function() {
createGrid: function () {
return {
xtype: 'grid',
ref: 'contactGrid',
xtype : 'grid',
ref : 'contactGrid',
columnWidth: 1.0,
store: this.store,
width: '100%',
height: 300,
title: 'Select contacts to import',
frame: false,
viewConfig:{
forceFit:true
store : this.store,
width : '100%',
height : 300,
title : 'Select contacts to import',
frame : false,
viewConfig : {
forceFit: true
},
colModel: new Ext.grid.ColumnModel({
colModel : new Ext.grid.ColumnModel({
defaults: {
width: 300,
width : 300,
sortable: true
},
columns: [
columns : [
{id: 'Displayname', header: 'Displayname', width: 350, sortable: true, dataIndex: 'display_name'},
{header: 'Firstname', width: 200, sortable: true, dataIndex: 'given_name'},
{header: 'Lastname', width: 200, sortable: true, dataIndex: 'surname'},
{header: 'Company', sortable: true, dataIndex: 'company_name'}
]
}),
sm: new Ext.grid.RowSelectionModel({multiSelect:true})
sm : new Ext.grid.RowSelectionModel({multiSelect: true})
}
},
createSelectBox: function() {
createSelectBox: function () {
var defaultFolder = container.getHierarchyStore().getDefaultFolder('contact'); // @type: Zarafa.hierarchy.data.MAPIFolderRecord
var subFolders = defaultFolder.getChildren();
var myStore = [];
@ -194,7 +194,7 @@ Zarafa.plugins.contactimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
/* add all local contact folders */
var i = 0;
myStore.push([defaultFolder.getDefaultFolderKey(), defaultFolder.getDisplayName()]);
for(i = 0; i < subFolders.length; i++) {
for (i = 0; i < subFolders.length; i++) {
/* Store all subfolders */
myStore.push([subFolders[i].getDisplayName(), subFolders[i].getDisplayName(), false]); // 3rd field = isPublicfolder
}
@ -202,12 +202,12 @@ Zarafa.plugins.contactimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
/* add all shared contact folders */
var pubStore = container.getHierarchyStore().getPublicStore();
if(typeof pubStore !== "undefined") {
if (typeof pubStore !== "undefined") {
try {
var pubFolder = pubStore.getDefaultFolder("publicfolders");
var pubSubFolders = pubFolder.getChildren();
for(i = 0; i < pubSubFolders.length; i++) {
if(pubSubFolders[i].isContainerClass("IPF.Contact")){
for (i = 0; i < pubSubFolders.length; i++) {
if (pubSubFolders[i].isContainerClass("IPF.Contact")) {
myStore.push([pubSubFolders[i].getDisplayName(), pubSubFolders[i].getDisplayName() + " [Shared]", true]); // 3rd field = isPublicfolder
}
}
@ -218,81 +218,81 @@ Zarafa.plugins.contactimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
}
return {
xtype: "selectbox",
ref: 'addressbookSelector',
editable: false,
name: "choosen_addressbook",
value: container.getSettingsModel().get("zarafa/v1/plugins/contactimporter/default_addressbook"),
width: 100,
fieldLabel: "Select an addressbook",
store: myStore,
mode: 'local',
xtype : "selectbox",
ref : 'addressbookSelector',
editable : false,
name : "choosen_addressbook",
value : container.getSettingsModel().get("zarafa/v1/plugins/contactimporter/default_addressbook"),
width : 100,
fieldLabel : "Select an addressbook",
store : myStore,
mode : 'local',
labelSeperator: ":",
border: false,
anchor: "100%",
scope: this,
allowBlank: false
border : false,
anchor : "100%",
scope : this,
allowBlank : false
}
},
createUploadField: function() {
createUploadField: function () {
return {
xtype: "fileuploadfield",
ref: 'contactfileuploadfield',
xtype : "fileuploadfield",
ref : 'contactfileuploadfield',
columnWidth: 1.0,
id: 'form-file',
name: 'vcfdata',
emptyText: 'Select an .vcf addressbook',
border: false,
anchor: "100%",
scope: this,
allowBlank: false,
listeners: {
id : 'form-file',
name : 'vcfdata',
emptyText : 'Select an .vcf addressbook',
border : false,
anchor : "100%",
scope : this,
allowBlank : false,
listeners : {
'fileselected': this.onFileSelected,
scope: this
scope : this
}
}
},
createSubmitButton: function() {
createSubmitButton: function () {
return {
xtype: "button",
ref: "../submitButton",
disabled: true,
width: 100,
border: false,
text: _("Import"),
anchor: "100%",
handler: this.importCheckedContacts,
scope: this,
xtype : "button",
ref : "../submitButton",
disabled : true,
width : 100,
border : false,
text : _("Import"),
anchor : "100%",
handler : this.importCheckedContacts,
scope : this,
allowBlank: false
}
},
createSubmitAllButton: function() {
createSubmitAllButton: function () {
return {
xtype: "button",
ref: "../submitAllButton",
disabled: true,
width: 100,
border: false,
text: _("Import All"),
anchor: "100%",
handler: this.importAllContacts,
scope: this,
xtype : "button",
ref : "../submitAllButton",
disabled : true,
width : 100,
border : false,
text : _("Import All"),
anchor : "100%",
handler : this.importAllContacts,
scope : this,
allowBlank: false
}
},
createCancelButton: function() {
createCancelButton: function () {
return {
xtype: "button",
width: 100,
border: false,
text: _("Cancel"),
anchor: "100%",
handler: this.close,
scope: this,
xtype : "button",
width : 100,
border : false,
text : _("Cancel"),
anchor : "100%",
handler : this.close,
scope : this,
allowBlank: false
}
},
@ -302,24 +302,24 @@ Zarafa.plugins.contactimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
* in the {@link Ext.ux.form.FileUploadField} and the dialog is closed
* @param {Ext.ux.form.FileUploadField} uploadField being added a file to
*/
onFileSelected : function(uploadField) {
onFileSelected: function (uploadField) {
var form = this.addContactFormPanel.getForm();
if (form.isValid()) {
form.submit({
waitMsg: 'Uploading and parsing contacts...',
url: 'plugins/contactimporter/php/upload.php',
failure: function(file, action) {
url : 'plugins/contactimporter/php/upload.php',
failure: function (file, action) {
this.submitButton.disable();
this.submitAllButton.disable();
Zarafa.common.dialogs.MessageBox.show({
title : _('Error'),
msg : _(action.result.error),
icon : Zarafa.common.dialogs.MessageBox.ERROR,
buttons : Zarafa.common.dialogs.MessageBox.OK
buttons: Zarafa.common.dialogs.MessageBox.OK
});
},
success: function(file, action){
success: function (file, action) {
uploadField.reset();
this.vcffile = action.result.vcf_file;
@ -348,10 +348,10 @@ Zarafa.plugins.contactimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
);
},
handleParsingResult: function(response) {
handleParsingResult: function (response) {
this.loadMask.hide();
if(response["status"] == true) {
if (response["status"] == true) {
this.submitButton.enable();
this.submitAllButton.enable();
@ -363,7 +363,7 @@ Zarafa.plugins.contactimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
title : _('Parser Error'),
msg : _(response["message"]),
icon : Zarafa.common.dialogs.MessageBox.ERROR,
buttons : Zarafa.common.dialogs.MessageBox.OK
buttons: Zarafa.common.dialogs.MessageBox.OK
});
}
},
@ -393,21 +393,21 @@ Zarafa.plugins.contactimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
//receive existing contact store
var folderValue = this.addressbookSelector.getValue();
if(folderValue == undefined) { // no addressbook choosen
if (folderValue == undefined) { // no addressbook choosen
Zarafa.common.dialogs.MessageBox.show({
title : _('Error'),
msg : _('You have to choose an addressbook!'),
icon : Zarafa.common.dialogs.MessageBox.ERROR,
buttons : Zarafa.common.dialogs.MessageBox.OK
buttons: Zarafa.common.dialogs.MessageBox.OK
});
} else {
var addressbookexist = true;
if(this.contactGrid.selModel.getCount() < 1) {
if (this.contactGrid.selModel.getCount() < 1) {
Zarafa.common.dialogs.MessageBox.show({
title : _('Error'),
msg : _('You have to choose at least one contact to import!'),
icon : Zarafa.common.dialogs.MessageBox.ERROR,
buttons : Zarafa.common.dialogs.MessageBox.OK
buttons: Zarafa.common.dialogs.MessageBox.OK
});
} else {
var contactStore = new Zarafa.contact.ContactStore();
@ -416,41 +416,41 @@ Zarafa.plugins.contactimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
var pubFolder = pubStore.getDefaultFolder("publicfolders");
var pubSubFolders = pubFolder.getChildren();
if(folderValue != "contact") {
if (folderValue != "contact") {
var subFolders = contactFolder.getChildren();
var i = 0;
for(i = 0; i < pubSubFolders.length; i++) {
if(pubSubFolders[i].isContainerClass("IPF.Contact")){
for (i = 0; i < pubSubFolders.length; i++) {
if (pubSubFolders[i].isContainerClass("IPF.Contact")) {
subFolders.push(pubSubFolders[i]);
}
}
for(i=0;i<subFolders.length;i++) {
for (i = 0; i < subFolders.length; i++) {
// look up right folder
// TODO: improve!!
if(subFolders[i].getDisplayName() == folderValue) {
if (subFolders[i].getDisplayName() == folderValue) {
contactFolder = subFolders[i];
break;
}
}
if(contactFolder.isDefaultFolder()) {
if (contactFolder.isDefaultFolder()) {
Zarafa.common.dialogs.MessageBox.show({
title : _('Error'),
msg : _('Selected addressbook does not exist!'),
icon : Zarafa.common.dialogs.MessageBox.ERROR,
buttons : Zarafa.common.dialogs.MessageBox.OK
buttons: Zarafa.common.dialogs.MessageBox.OK
});
addressbookexist = false;
}
}
if(addressbookexist) {
if (addressbookexist) {
this.loadMask.show();
var uids = [];
var store_entryid = "";
//receive Records from grid rows
Ext.each(contacts, function(newRecord) {
Ext.each(contacts, function (newRecord) {
uids.push(newRecord.data.record.internal_fields.contact_uid);
}, this);
store_entryid = contactFolder.get('store_entryid');
@ -463,9 +463,9 @@ Zarafa.plugins.contactimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
'contactmodule',
'import',
{
storeid: contactFolder.get("store_entryid"),
folderid: contactFolder.get("entryid"),
uids: uids,
storeid : contactFolder.get("store_entryid"),
folderid : contactFolder.get("entryid"),
uids : uids,
vcf_filepath: this.vcffile
},
responseHandler
@ -476,17 +476,17 @@ Zarafa.plugins.contactimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
}
},
importContactsDone : function (response) {
importContactsDone: function (response) {
this.loadMask.hide();
this.dialog.close();
if(response.status == true) {
if (response.status == true) {
container.getNotifier().notify('info', 'Imported', 'Imported ' + response.count + ' contacts. Please reload your addressbook!');
} else {
Zarafa.common.dialogs.MessageBox.show({
title : _('Error'),
msg : _('Import failed: ') + response.message,
icon : Zarafa.common.dialogs.MessageBox.ERROR,
buttons : Zarafa.common.dialogs.MessageBox.OK
buttons: Zarafa.common.dialogs.MessageBox.OK
});
}
}

View File

@ -2,7 +2,7 @@
* plugin.contactimporter.js zarafa contactimporter
*
* Author: Christoph Haas <christoph.h@sprinternet.at>
* Copyright (C) 2012-2013 Christoph Haas
* Copyright (C) 2012-2016 Christoph Haas
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -39,14 +39,14 @@ Zarafa.plugins.contactimporter.ImportPlugin = Ext.extend(Zarafa.core.Plugin, {
* initialises insertion point for plugin
* @protected
*/
initPlugin : function() {
initPlugin: function () {
Zarafa.plugins.contactimporter.ImportPlugin.superclass.initPlugin.apply(this, arguments);
/* our panel */
Zarafa.core.data.SharedComponentType.addProperty('plugins.contactimporter.dialogs.importcontacts');
/* directly import received vcfs */
this.registerInsertionPoint('common.contextmenu.attachment.actions', this.createAttachmentImportButton);
this.registerInsertionPoint('common.contextmenu.attachment.actions', this.createAttachmentImportButton, this);
/* add import button to south navigation */
this.registerInsertionPoint("navigation.south", this.createImportButton, this);
@ -66,15 +66,11 @@ Zarafa.plugins.contactimporter.ImportPlugin = Ext.extend(Zarafa.core.Plugin, {
xtype : 'button',
text : _('Import Contacts'),
iconCls : 'icon_contactimporter_button',
navigationContext : container.getContextByName('contact'),
navigationContext: container.getContextByName('contact'),
handler : this.onImportButtonClick,
scope : this
};
if(container.getSettingsModel().get("zarafa/v1/plugins/contactimporter/enable_export")) {
button.text = _('Import/Export Contacts');
}
return button;
},
@ -94,20 +90,20 @@ Zarafa.plugins.contactimporter.ImportPlugin = Ext.extend(Zarafa.core.Plugin, {
};
},
exportToVCF: function(btn) {
if(btn.records.length == 0) {
exportToVCF: function (btn) {
if (btn.records.length == 0) {
return; // skip if no records where given!
}
var recordIds = [];
for(var i=0;i<btn.records.length;i++) {
for (var i = 0; i < btn.records.length; i++) {
recordIds.push(btn.records[i].get("entryid"));
}
var responseHandler = new Zarafa.plugins.contactimporter.data.ResponseHandler({
successCallback: this.downloadVCF,
scope: this
scope : this
});
// request attachment preperation
@ -115,14 +111,14 @@ Zarafa.plugins.contactimporter.ImportPlugin = Ext.extend(Zarafa.core.Plugin, {
'contactmodule',
'export',
{
storeid : btn.records[0].get("store_entryid"),
storeid: btn.records[0].get("store_entryid"),
records: recordIds
},
responseHandler
);
},
downloadVCF: function(response) {
downloadVCF: function (response) {
var downloadFrame = Ext.getBody().createChild({
tag: 'iframe',
cls: 'x-hidden'
@ -143,16 +139,16 @@ Zarafa.plugins.contactimporter.ImportPlugin = Ext.extend(Zarafa.core.Plugin, {
* @return {Object} Configuration object for a {@link Ext.Button button}
*/
createAttachmentImportButton : function(include, btn) {
createAttachmentImportButton: function (include, btn) {
return {
text : _('Import Contacts'),
handler : this.getAttachmentFileName.createDelegate(this, [btn]),
scope : this,
iconCls : 'icon_contactimporter_button',
beforeShow : function(item, record) {
beforeShow: function (item, record) {
var extension = record.data.name.split('.').pop().toLowerCase();
if(record.data.filetype == "text/vcard" || record.data.filetype == "text/x-vcard" || extension == "vcf" || extension == "vcard") {
if (record.data.filetype == "text/vcard" || record.data.filetype == "text/x-vcard" || extension == "vcf" || extension == "vcard") {
item.setVisible(true);
} else {
item.setVisible(false);
@ -164,15 +160,15 @@ Zarafa.plugins.contactimporter.ImportPlugin = Ext.extend(Zarafa.core.Plugin, {
/**
* Callback for getAttachmentFileName
*/
gotAttachmentFileName: function(response) {
if(response.status == true) {
gotAttachmentFileName: function (response) {
if (response.status == true) {
this.openImportDialog(response.tmpname);
} else {
Zarafa.common.dialogs.MessageBox.show({
title : _('Error'),
msg : _(response["message"]),
icon : Zarafa.common.dialogs.MessageBox.ERROR,
buttons : Zarafa.common.dialogs.MessageBox.OK
buttons: Zarafa.common.dialogs.MessageBox.OK
});
}
},
@ -182,27 +178,27 @@ Zarafa.plugins.contactimporter.ImportPlugin = Ext.extend(Zarafa.core.Plugin, {
*/
getAttachmentFileName: function (btn) {
Zarafa.common.dialogs.MessageBox.show({
title: 'Please wait',
msg: 'Loading attachment...',
title : 'Please wait',
msg : 'Loading attachment...',
progressText: 'Initializing...',
width:300,
progress:true,
closable:false
width : 300,
progress : true,
closable : false
});
// progress bar... ;)
var f = function(v){
return function(){
if(v == 100){
var f = function (v) {
return function () {
if (v == 100) {
Zarafa.common.dialogs.MessageBox.hide();
}else{
Zarafa.common.dialogs.MessageBox.updateProgress(v/100, Math.round(v)+'% loaded');
} else {
Zarafa.common.dialogs.MessageBox.updateProgress(v / 100, Math.round(v) + '% loaded');
}
};
};
for(var i = 1; i < 101; i++){
setTimeout(f(i), 20*i);
for (var i = 1; i < 101; i++) {
setTimeout(f(i), 20 * i);
}
/* store the attachment to a temporary folder and prepare it for uploading */
@ -212,16 +208,17 @@ Zarafa.plugins.contactimporter.ImportPlugin = Ext.extend(Zarafa.core.Plugin, {
var store = attachmentStore.getParentRecord().get('store_entryid');
var entryid = attachmentStore.getAttachmentParentRecordEntryId();
var attachNum = new Array(1);
if (attachmentRecord.get('attach_num') != -1)
if (attachmentRecord.get('attach_num') != -1) {
attachNum[0] = attachmentRecord.get('attach_num');
else
} else {
attachNum[0] = attachmentRecord.get('tmpname');
}
var dialog_attachments = attachmentStore.getId();
var filename = attachmentRecord.data.name;
var responseHandler = new Zarafa.plugins.contactimporter.data.ResponseHandler({
successCallback: this.gotAttachmentFileName.createDelegate(this),
scope: this
scope : this
});
// request attachment preperation
@ -230,10 +227,10 @@ Zarafa.plugins.contactimporter.ImportPlugin = Ext.extend(Zarafa.core.Plugin, {
'importattachment',
{
entryid : entryid,
store: store,
attachNum: attachNum,
store : store,
attachNum : attachNum,
dialog_attachments: dialog_attachments,
filename: filename
filename : filename
},
responseHandler
);
@ -251,7 +248,7 @@ Zarafa.plugins.contactimporter.ImportPlugin = Ext.extend(Zarafa.core.Plugin, {
*
* @param {String} filename
*/
openImportDialog: function(filename) {
openImportDialog: function (filename) {
var componentType = Zarafa.core.data.SharedComponentType['plugins.contactimporter.dialogs.importcontacts'];
var config = {
filename: filename
@ -268,9 +265,9 @@ Zarafa.plugins.contactimporter.ImportPlugin = Ext.extend(Zarafa.core.Plugin, {
* @param {Ext.data.Record} record Optionally passed record.
* @return {Number} The bid for the shared component
*/
bidSharedComponent : function(type, record) {
bidSharedComponent: function (type, record) {
var bid = -1;
switch(type) {
switch (type) {
case Zarafa.core.data.SharedComponentType['plugins.contactimporter.dialogs.importcontacts']:
bid = 1;
break;
@ -285,9 +282,9 @@ Zarafa.plugins.contactimporter.ImportPlugin = Ext.extend(Zarafa.core.Plugin, {
* @param {Ext.data.Record} record Optionally passed record.
* @return {Ext.Component} Component
*/
getSharedComponent : function(type, record) {
getSharedComponent: function (type, record) {
var component;
switch(type) {
switch (type) {
case Zarafa.core.data.SharedComponentType['plugins.contactimporter.dialogs.importcontacts']:
component = Zarafa.plugins.contactimporter.dialogs.ImportContentPanel;
break;
@ -301,11 +298,11 @@ Zarafa.plugins.contactimporter.ImportPlugin = Ext.extend(Zarafa.core.Plugin, {
/*############################################################################################################################
* STARTUP
*############################################################################################################################*/
Zarafa.onReady(function() {
Zarafa.onReady(function () {
container.registerPlugin(new Zarafa.core.PluginMetaData({
name : 'contactimporter',
displayName : _('Contactimporter Plugin'),
about : Zarafa.plugins.contactimporter.ABOUT,
pluginConstructor : Zarafa.plugins.contactimporter.ImportPlugin
pluginConstructor: Zarafa.plugins.contactimporter.ImportPlugin
}));
});

View File

@ -1,9 +1,30 @@
<?php
/**
* download.php, zarafa contact to vcf im/exporter
*
* Author: Christoph Haas <christoph.h@sprinternet.at>
* Copyright (C) 2012-2016 Christoph Haas
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
class DownloadHandler
{
public static function doDownload() {
public static function doDownload()
{
if (isset($_GET["token"])) {
$token = $_GET["token"];
} else {
@ -23,7 +44,7 @@ class DownloadHandler
$file = PLUGIN_CONTACTIMPORTER_TMP_UPLOAD . "vcf_" . $token . ".vcf";
if(!file_exists($file)) { // invalid token
if (!file_exists($file)) { // invalid token
return false;
}

View File

@ -3,7 +3,7 @@
* class.calendar.php, zarafa contact to vcf im/exporter
*
* Author: Christoph Haas <christoph.h@sprinternet.at>
* Copyright (C) 2012-2013 Christoph Haas
* Copyright (C) 2012-2016 Christoph Haas
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -26,7 +26,8 @@ include_once('vendor/autoload.php');
use JeroenDesloovere\VCard\VCard;
use JeroenDesloovere\VCard\VCardParser;
class ContactModule extends Module {
class ContactModule extends Module
{
private $DEBUG = true; // enable error_log debugging
@ -35,7 +36,8 @@ class ContactModule extends Module {
* @param $id
* @param $data
*/
public function __construct($id, $data) {
public function __construct($id, $data)
{
parent::Module($id, $data);
}
@ -44,21 +46,22 @@ class ContactModule extends Module {
* Exception part is used for authentication errors also
* @return boolean true on success or false on failure.
*/
public function execute() {
public function execute()
{
$result = false;
if(!$this->DEBUG) {
if (!$this->DEBUG) {
/* disable error printing - otherwise json communication might break... */
ini_set('display_errors', '0');
}
foreach($this->data as $actionType => $actionData) {
if(isset($actionType)) {
foreach ($this->data as $actionType => $actionData) {
if (isset($actionType)) {
try {
if($this->DEBUG) {
if ($this->DEBUG) {
error_log("exec: " . $actionType);
}
switch($actionType) {
switch ($actionType) {
case "load":
$result = $this->loadContacts($actionType, $actionData);
break;
@ -76,11 +79,11 @@ class ContactModule extends Module {
}
} catch (MAPIException $e) {
if($this->DEBUG) {
if ($this->DEBUG) {
error_log("mapi exception: " . $e->getMessage());
}
} catch (Exception $e) {
if($this->DEBUG) {
if ($this->DEBUG) {
error_log("exception: " . $e->getMessage());
}
}
@ -95,11 +98,12 @@ class ContactModule extends Module {
* @param $length the lenght of the generated string
* @return string a random string
*/
private function randomstring($length = 6) {
private function randomstring($length = 6)
{
// $chars - all allowed charakters
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
srand((double)microtime()*1000000);
srand((double)microtime() * 1000000);
$i = 0;
$pass = "";
while ($i < $length) {
@ -116,29 +120,30 @@ class ContactModule extends Module {
* @param $actionType
* @param $actionData
*/
private function importContacts($actionType, $actionData) {
private function importContacts($actionType, $actionData)
{
// Get uploaded vcf path
$vcffile = false;
if(isset($actionData["vcf_filepath"])) {
if (isset($actionData["vcf_filepath"])) {
$vcffile = $actionData["vcf_filepath"];
}
// Get store id
$storeid = false;
if(isset($actionData["storeid"])) {
if (isset($actionData["storeid"])) {
$storeid = $actionData["storeid"];
}
// Get folder entryid
$folderid = false;
if(isset($actionData["folderid"])) {
if (isset($actionData["folderid"])) {
$folderid = $actionData["folderid"];
}
// Get uids
$uids = array();
if(isset($actionData["uids"])) {
if (isset($actionData["uids"])) {
$uids = $actionData["uids"];
}
@ -157,13 +162,13 @@ class ContactModule extends Module {
$contacts = array();
if(!$error && iterator_count($parser) > 0) {
if (!$error && iterator_count($parser) > 0) {
$contacts = $this->parseContactsToArray($parser);
$store = $GLOBALS["mapisession"]->openMessageStore(hex2bin($storeid));
$folder = mapi_msgstore_openentry($store, hex2bin($folderid));
$importall = false;
if(count($uids) == count($contacts)) {
if (count($uids) == count($contacts)) {
$importall = true;
}
@ -173,12 +178,12 @@ class ContactModule extends Module {
$count = 0;
// iterate through all contacts and import them :)
foreach($contacts as $contact) {
foreach ($contacts as $contact) {
if (isset($contact["display_name"]) && ($importall || in_array($contact["internal_fields"]["contact_uid"], $uids))) {
// parse the arraykeys
// TODO: this is very slow...
foreach($contact as $key => $value) {
if($key !== "internal_fields") {
foreach ($contact as $key => $value) {
if ($key !== "internal_fields") {
$propValuesMAPI[$properties[$key]] = $value;
}
}
@ -188,7 +193,7 @@ class ContactModule extends Module {
$message = mapi_folder_createmessage($folder);
if(isset($contact["internal_fields"]["x_photo_path"])) {
if (isset($contact["internal_fields"]["x_photo_path"])) {
$propValuesMAPI[$properties["picture"]] = 1; // contact has an image
// import the photo
@ -212,7 +217,7 @@ class ContactModule extends Module {
mapi_setprops($attach, $propValuesIMG);
mapi_savechanges($attach);
if($this->DEBUG) {
if ($this->DEBUG) {
error_log("Contactpicture imported!");
}
@ -223,7 +228,7 @@ class ContactModule extends Module {
mapi_setprops($message, $propValuesMAPI);
mapi_savechanges($message);
if($this->DEBUG) {
if ($this->DEBUG) {
error_log("New contact added: \"" . $propValuesMAPI[$properties["display_name"]] . "\".\n");
}
$count++;
@ -244,9 +249,10 @@ class ContactModule extends Module {
$GLOBALS["bus"]->addData($this->getResponseData());
}
private function getProp($props, $propname) {
private function getProp($props, $propname)
{
$p = $this->getProperties();
if(isset($props["props"][$propname])){
if (isset($props["props"][$propname])) {
return $props["props"][$propname];
}
return "";
@ -299,98 +305,98 @@ class ContactModule extends Module {
$vcard->addName($lastname, $firstname, $additional, $prefix, $suffix);
$company = $this->getProp($messageProps, "company_name");
if(!empty($company)) {
if (!empty($company)) {
$vcard->addCompany($company);
}
$jobtitle = $this->getProp($messageProps, "title");
if(!empty($jobtitle)) {
if (!empty($jobtitle)) {
$vcard->addJobtitle($jobtitle);
}
// MAIL
$mail = $this->getProp($messageProps, "email_address_1");
if(!empty($mail)) {
if (!empty($mail)) {
$vcard->addEmail($mail);
}
$mail = $this->getProp($messageProps, "email_address_2");
if(!empty($mail)) {
if (!empty($mail)) {
$vcard->addEmail($mail);
}
$mail = $this->getProp($messageProps, "email_address_3");
if(!empty($mail)) {
if (!empty($mail)) {
$vcard->addEmail($mail);
}
// PHONE
$wphone = $this->getProp($messageProps, "business_telephone_number");
if(!empty($wphone)) {
if (!empty($wphone)) {
$vcard->addPhoneNumber($wphone, 'WORK');
}
$wphone = $this->getProp($messageProps, "home_telephone_number");
if(!empty($wphone)) {
if (!empty($wphone)) {
$vcard->addPhoneNumber($wphone, 'HOME');
}
$wphone = $this->getProp($messageProps, "cellular_telephone_number");
if(!empty($wphone)) {
if (!empty($wphone)) {
$vcard->addPhoneNumber($wphone, 'CELL');
}
$wphone = $this->getProp($messageProps, "business_fax_number");
if(!empty($wphone)) {
if (!empty($wphone)) {
$vcard->addPhoneNumber($wphone, 'FAX');
}
$wphone = $this->getProp($messageProps, "pager_telephone_number");
if(!empty($wphone)) {
if (!empty($wphone)) {
$vcard->addPhoneNumber($wphone, 'PAGER');
}
$wphone = $this->getProp($messageProps, "car_telephone_number");
if(!empty($wphone)) {
if (!empty($wphone)) {
$vcard->addPhoneNumber($wphone, 'CAR');
}
// ADDRESS
$addr = $this->getProp($messageProps, "business_address");
if(!empty($addr)) {
if (!empty($addr)) {
$vcard->addAddress(null, null, $this->getProp($messageProps, "business_address_street"), $this->getProp($messageProps, "business_address_city"), $this->getProp($messageProps, "business_address_state"), $this->getProp($messageProps, "business_address_postal_code"), $this->getProp($messageProps, "business_address_country"), "WORK");
}
$addr = $this->getProp($messageProps, "home_address");
if(!empty($addr)) {
if (!empty($addr)) {
$vcard->addAddress(null, null, $this->getProp($messageProps, "home_address_street"), $this->getProp($messageProps, "home_address_city"), $this->getProp($messageProps, "home_address_state"), $this->getProp($messageProps, "home_address_postal_code"), $this->getProp($messageProps, "home_address_country"), "HOME");
}
$addr = $this->getProp($messageProps, "other_address");
if(!empty($addr)) {
if (!empty($addr)) {
$vcard->addAddress(null, null, $this->getProp($messageProps, "other_address_street"), $this->getProp($messageProps, "other_address_city"), $this->getProp($messageProps, "other_address_state"), $this->getProp($messageProps, "other_address_postal_code"), $this->getProp($messageProps, "other_address_country"), "OTHER");
}
// MISC
$url = $this->getProp($messageProps, "webpage");
if(!empty($url)) {
if (!empty($url)) {
$vcard->addURL($url);
}
$bday = $this->getProp($messageProps, "birthday");
if(!empty($bday)) {
if (!empty($bday)) {
$vcard->addBirthday(date("Y-m-d", $bday));
}
$notes = $this->getProp($messageProps, "body");
if(!empty($notes)) {
if (!empty($notes)) {
$vcard->addNote($notes);
}
$haspicture = $this->getProp($messageProps, "has_picture");
if(!empty($haspicture) && $haspicture === true) {
if (!empty($haspicture) && $haspicture === true) {
$attachnum = -1;
if(isset($messageProps["attachments"]) && isset($messageProps["attachments"]["item"])) {
foreach($messageProps["attachments"]["item"] as $attachment) {
if($attachment["props"]["attachment_contactphoto"] == true) {
if (isset($messageProps["attachments"]) && isset($messageProps["attachments"]["item"])) {
foreach ($messageProps["attachments"]["item"] as $attachment) {
if ($attachment["props"]["attachment_contactphoto"] == true) {
$attachnum = $attachment["props"]["attach_num"];
break;
}
}
}
if($attachnum >= 0) {
if ($attachnum >= 0) {
$attachment = $this->getAttachmentByAttachNum($message, $attachnum); // get first attachment only
$phototoken = $this->randomstring(16);
$tmpphoto = PLUGIN_CONTACTIMPORTER_TMP_UPLOAD . "photo_" . $phototoken . ".jpg";
@ -408,7 +414,7 @@ class ContactModule extends Module {
$response['status'] = true;
$response['download_token'] = $token;
$response['filename'] = count($records)."contacts.vcf";
$response['filename'] = count($records) . "contacts.vcf";
$this->addActionData($actionType, $response);
$GLOBALS["bus"]->addData($this->getResponseData());
@ -435,16 +441,17 @@ class ContactModule extends Module {
* @param MAPIAttach $attachment attachment which will be dumped to client side
* @return Response response to sent to client including attachment data
*/
private function storeSavedAttachment($temppath, $attachment) {
private function storeSavedAttachment($temppath, $attachment)
{
// Check if the attachment is opened
if($attachment) {
if ($attachment) {
// Open a stream to get the attachment data
$stream = mapi_openproperty($attachment, PR_ATTACH_DATA_BIN, IID_IStream, 0, 0);
$stat = mapi_stream_stat($stream);
// Read the attachment content from the stream
$body = '';
for($i = 0; $i < $stat['cb']; $i += BLOCK_SIZE) {
for ($i = 0; $i < $stat['cb']; $i += BLOCK_SIZE) {
$body .= mapi_stream_read($stream, BLOCK_SIZE);
}
@ -452,25 +459,26 @@ class ContactModule extends Module {
}
}
private function replaceStringPropertyTags($store, $properties) {
private function replaceStringPropertyTags($store, $properties)
{
$newProperties = array();
$ids = array("name"=>array(), "id"=>array(), "guid"=>array(), "type"=>array()); // this array stores all the information needed to retrieve a named property
$ids = array("name" => array(), "id" => array(), "guid" => array(), "type" => array()); // this array stores all the information needed to retrieve a named property
$num = 0;
// caching
$guids = array();
foreach($properties as $name => $val) {
if(is_string($val)) {
foreach ($properties as $name => $val) {
if (is_string($val)) {
$split = explode(":", $val);
if(count($split) != 3) { // invalid string, ignore
trigger_error(sprintf("Invalid property: %s \"%s\"",$name,$val), E_USER_NOTICE);
if (count($split) != 3) { // invalid string, ignore
trigger_error(sprintf("Invalid property: %s \"%s\"", $name, $val), E_USER_NOTICE);
continue;
}
if(substr($split[2], 0, 2) == "0x") {
if (substr($split[2], 0, 2) == "0x") {
$id = hexdec(substr($split[2], 2));
} else {
$id = $split[2];
@ -504,7 +512,7 @@ class ContactModule extends Module {
// get the ids
$named = mapi_getidsfromnames($store, $ids["id"], $ids["guid"]);
foreach($named as $num => $prop) {
foreach ($named as $num => $prop) {
$newProperties[$ids["name"][$num]] = mapi_prop_tag(constant($ids["type"][$num]), mapi_prop_id($prop));
}
@ -516,7 +524,8 @@ class ContactModule extends Module {
*
* @return [array] the propertyarray
*/
private function getProperties() {
private function getProperties()
{
$properties = array();
$properties["subject"] = PR_SUBJECT;
@ -596,7 +605,7 @@ class ContactModule extends Module {
$properties["radio_telephone_number"] = PR_RADIO_TELEPHONE_NUMBER;
$properties["telex_telephone_number"] = PR_TELEX_NUMBER;
$properties["ttytdd_telephone_number"] = PR_TTYTDD_PHONE_NUMBER;
$properties["business_telephone_number"] =PR_BUSINESS_TELEPHONE_NUMBER;
$properties["business_telephone_number"] = PR_BUSINESS_TELEPHONE_NUMBER;
// Additional fax properties
$properties["fax_1_address_type"] = "PT_STRING8:PSETID_Address:0x80B2";
@ -655,11 +664,12 @@ class ContactModule extends Module {
* @param $actionType
* @param $actionData
*/
private function loadContacts($actionType, $actionData) {
private function loadContacts($actionType, $actionData)
{
$error = false;
$error_msg = "";
if(is_readable ($actionData["vcf_filepath"])) {
if (is_readable($actionData["vcf_filepath"])) {
$parser = null;
try {
@ -668,30 +678,30 @@ class ContactModule extends Module {
$error = true;
$error_msg = $e->getMessage();
}
if($error) {
if ($error) {
$response['status'] = false;
$response['message']= $error_msg;
$response['message'] = $error_msg;
} else {
if(iterator_count($parser) == 0) {
if (iterator_count($parser) == 0) {
$response['status'] = false;
$response['message']= "No contacts in vcf file";
$response['message'] = "No contacts in vcf file";
} else {
$response['status'] = true;
$response['parsed_file']= $actionData["vcf_filepath"];
$response['parsed'] = array (
$response['parsed_file'] = $actionData["vcf_filepath"];
$response['parsed'] = array(
'contacts' => $this->parseContactsToArray($parser)
);
}
}
} else {
$response['status'] = false;
$response['message']= "File could not be read by server";
$response['message'] = "File could not be read by server";
}
$this->addActionData($actionType, $response);
$GLOBALS["bus"]->addData($this->getResponseData());
if($this->DEBUG) {
if ($this->DEBUG) {
error_log("parsing done, bus data written!");
}
}
@ -704,16 +714,17 @@ class ContactModule extends Module {
* @return array parsed contacts
* @private
*/
private function parseContactsToArray($contacts, $csv = false) {
private function parseContactsToArray($contacts, $csv = false)
{
$carr = array();
if(!$csv) {
if (!$csv) {
foreach ($contacts as $Index => $vCard) {
$properties = array();
if (isset($vCard->fullname)) {
$properties["display_name"] = $vCard->fullname;
$properties["fileas"] = $vCard->fullname;
} elseif(!isset($vCard->organization)) {
} elseif (!isset($vCard->organization)) {
error_log("Skipping entry! No fullname/organization given.");
continue;
}
@ -732,25 +743,39 @@ class ContactModule extends Module {
if (isset($vCard->phone) && count($vCard->phone) > 0) {
foreach ($vCard->phone as $type => $number) {
$number = $number[0]; // we only can store one number
if($this->startswith(strtolower($type), "home") || strtolower($type) === "default") {
if ($this->startswith(strtolower($type), "home") || strtolower($type) === "default") {
$properties["home_telephone_number"] = $number;
} else if($this->startswith(strtolower($type), "cell")) {
} else {
if ($this->startswith(strtolower($type), "cell")) {
$properties["cellular_telephone_number"] = $number;
} else if($this->startswith(strtolower($type), "work")) {
} else {
if ($this->startswith(strtolower($type), "work")) {
$properties["business_telephone_number"] = $number;
} else if($this->startswith(strtolower($type), "fax")) {
} else {
if ($this->startswith(strtolower($type), "fax")) {
$properties["business_fax_number"] = $number;
} else if($this->startswith(strtolower($type), "pager")) {
} else {
if ($this->startswith(strtolower($type), "pager")) {
$properties["pager_telephone_number"] = $number;
} else if($this->startswith(strtolower($type), "isdn")) {
} else {
if ($this->startswith(strtolower($type), "isdn")) {
$properties["isdn_number"] = $number;
} else if($this->startswith(strtolower($type), "car")) {
} else {
if ($this->startswith(strtolower($type), "car")) {
$properties["car_telephone_number"] = $number;
} else if($this->startswith(strtolower($type), "modem")) {
} else {
if ($this->startswith(strtolower($type), "modem")) {
$properties["ttytdd_telephone_number"] = $number;
}
}
}
}
}
}
}
}
}
}
if (isset($vCard->email) && count($vCard->email) > 0) {
$emailcount = 0;
$properties["address_book_long"] = 0;
@ -806,7 +831,7 @@ class ContactModule extends Module {
}
if (isset($vCard->organization)) {
$properties["company_name"] = $vCard->organization;
if(empty($properties["display_name"])) {
if (empty($properties["display_name"])) {
$properties["display_name"] = $vCard->organization; // if we have no displayname - use the company name as displayname
$properties["fileas"] = $vCard->organization;
}
@ -825,9 +850,9 @@ class ContactModule extends Module {
foreach ($vCard->address as $type => $address) {
$address = $address[0]; // we only can store one address per type
if($this->startswith(strtolower($type), "work")) {
if ($this->startswith(strtolower($type), "work")) {
$properties["business_address_street"] = $address->street;
if(!empty($address->extended)) {
if (!empty($address->extended)) {
$properties["business_address_street"] .= "\n" . $address->extended;
}
$properties["business_address_city"] = $address->city;
@ -835,9 +860,10 @@ class ContactModule extends Module {
$properties["business_address_postal_code"] = $address->zip;
$properties["business_address_country"] = $address->country;
$properties["business_address"] = $this->buildAddressString($properties["business_address_street"], $address->zip, $address->city, $address->region, $address->country);
} else if($this->startswith(strtolower($type), "home")) {
} else {
if ($this->startswith(strtolower($type), "home")) {
$properties["home_address_street"] = $address->street;
if(!empty($address->extended)) {
if (!empty($address->extended)) {
$properties["home_address_street"] .= "\n" . $address->extended;
}
$properties["home_address_city"] = $address->city;
@ -847,7 +873,7 @@ class ContactModule extends Module {
$properties["home_address"] = $this->buildAddressString($properties["home_address_street"], $address->zip, $address->city, $address->region, $address->country);
} else {
$properties["other_address_street"] = $address->street;
if(!empty($address->extended)) {
if (!empty($address->extended)) {
$properties["other_address_street"] .= "\n" . $address->extended;
}
$properties["other_address_city"] = $address->city;
@ -858,6 +884,7 @@ class ContactModule extends Module {
}
}
}
}
if (isset($vCard->birthday)) {
$properties["birthday"] = $vCard->birthday->getTimestamp();
}
@ -865,23 +892,23 @@ class ContactModule extends Module {
$properties["notes"] = $vCard->note;
}
if (isset($vCard->rawPhoto) || isset($vCard->photo)) {
if(!is_writable(TMP_PATH . "/")) {
if (!is_writable(TMP_PATH . "/")) {
error_log("Can not write to export tmp directory!");
} else {
$tmppath = TMP_PATH . "/" . $this->randomstring(15);
if(isset($vCard->rawPhoto)) {
if(file_put_contents($tmppath, $vCard->rawPhoto)) {
if (isset($vCard->rawPhoto)) {
if (file_put_contents($tmppath, $vCard->rawPhoto)) {
$properties["internal_fields"]["x_photo_path"] = $tmppath;
}
} elseif(isset($vCard->photo)) {
if($this->startswith(strtolower($vCard->photo), "http://") || $this->startswith(strtolower($vCard->photo), "https://")) { // check if it starts with http
$ctx = stream_context_create(array('http'=>
} elseif (isset($vCard->photo)) {
if ($this->startswith(strtolower($vCard->photo), "http://") || $this->startswith(strtolower($vCard->photo), "https://")) { // check if it starts with http
$ctx = stream_context_create(array('http' =>
array(
'timeout' => 3, //3 Seconds timout
)
));
if(file_put_contents($tmppath, file_get_contents($vCard->photo, false, $ctx))) {
if (file_put_contents($tmppath, file_get_contents($vCard->photo, false, $ctx))) {
$properties["internal_fields"]["x_photo_path"] = $tmppath;
}
} else {
@ -910,18 +937,31 @@ class ContactModule extends Module {
* @return string the concatinated address string
* @private
*/
private function buildAddressString($street, $zip, $city, $state, $country) {
private function buildAddressString($street, $zip, $city, $state, $country)
{
$out = "";
if (isset($country) && $street != "") $out = $country;
if (isset($country) && $street != "") {
$out = $country;
}
$zcs = "";
if (isset($zip) && $zip != "") $zcs = $zip;
if (isset($city) && $city != "") $zcs .= (($zcs)?" ":"") . $city;
if (isset($state) && $state != "") $zcs .= (($zcs)?" ":"") . $state;
if ($zcs) $out = $zcs . "\n" . $out;
if (isset($zip) && $zip != "") {
$zcs = $zip;
}
if (isset($city) && $city != "") {
$zcs .= (($zcs) ? " " : "") . $city;
}
if (isset($state) && $state != "") {
$zcs .= (($zcs) ? " " : "") . $state;
}
if ($zcs) {
$out = $zcs . "\n" . $out;
}
if (isset($street) && $street != "") $out = $street . (($out)?"\n\n". $out: "") ;
if (isset($street) && $street != "") {
$out = $street . (($out) ? "\n\n" . $out : "");
}
return $out;
}
@ -932,16 +972,17 @@ class ContactModule extends Module {
* @param $actionData
* @private
*/
private function getAttachmentPath($actionType, $actionData) {
private function getAttachmentPath($actionType, $actionData)
{
// Get store id
$storeid = false;
if(isset($actionData["store"])) {
if (isset($actionData["store"])) {
$storeid = $actionData["store"];
}
// Get message entryid
$entryid = false;
if(isset($actionData["entryid"])) {
if (isset($actionData["entryid"])) {
$entryid = $actionData["entryid"];
}
@ -950,41 +991,40 @@ class ContactModule extends Module {
// Get number of attachment which should be opened.
$attachNum = false;
if(isset($actionData["attachNum"])) {
if (isset($actionData["attachNum"])) {
$attachNum = $actionData["attachNum"];
}
// Check if storeid and entryid isset
if($storeid && $entryid) {
if ($storeid && $entryid) {
// Open the store
$store = $GLOBALS["mapisession"]->openMessageStore(hex2bin($storeid));
if($store) {
if ($store) {
// Open the message
$message = mapi_msgstore_openentry($store, hex2bin($entryid));
if($message) {
if ($message) {
$attachment = false;
// Check if attachNum isset
if($attachNum) {
if ($attachNum) {
// Loop through the attachNums, message in message in message ...
for($i = 0; $i < (count($attachNum) - 1); $i++)
{
for ($i = 0; $i < (count($attachNum) - 1); $i++) {
// Open the attachment
$tempattach = mapi_message_openattach($message, (int) $attachNum[$i]);
if($tempattach) {
$tempattach = mapi_message_openattach($message, (int)$attachNum[$i]);
if ($tempattach) {
// Open the object in the attachment
$message = mapi_attach_openobj($tempattach);
}
}
// Open the attachment
$attachment = mapi_message_openattach($message, (int) $attachNum[(count($attachNum) - 1)]);
$attachment = mapi_message_openattach($message, (int)$attachNum[(count($attachNum) - 1)]);
}
// Check if the attachment is opened
if($attachment) {
if ($attachment) {
// Get the props of the attachment
$props = mapi_attach_getprops($attachment, array(PR_ATTACH_LONG_FILENAME, PR_ATTACH_MIME_TAG, PR_DISPLAY_NAME, PR_ATTACH_METHOD));
@ -994,29 +1034,33 @@ class ContactModule extends Module {
$filename = "ERROR";
// Set filename
if(isset($props[PR_ATTACH_LONG_FILENAME])) {
if (isset($props[PR_ATTACH_LONG_FILENAME])) {
$filename = $props[PR_ATTACH_LONG_FILENAME];
} else if(isset($props[PR_ATTACH_FILENAME])) {
} else {
if (isset($props[PR_ATTACH_FILENAME])) {
$filename = $props[PR_ATTACH_FILENAME];
} else if(isset($props[PR_DISPLAY_NAME])) {
} else {
if (isset($props[PR_DISPLAY_NAME])) {
$filename = $props[PR_DISPLAY_NAME];
}
}
}
// Set content type
if(isset($props[PR_ATTACH_MIME_TAG])) {
if (isset($props[PR_ATTACH_MIME_TAG])) {
$contentType = $props[PR_ATTACH_MIME_TAG];
} else {
// Parse the extension of the filename to get the content type
if(strrpos($filename, ".") !== false) {
if (strrpos($filename, ".") !== false) {
$extension = strtolower(substr($filename, strrpos($filename, ".")));
$contentType = "application/octet-stream";
if (is_readable("mimetypes.dat")){
$fh = fopen("mimetypes.dat","r");
if (is_readable("mimetypes.dat")) {
$fh = fopen("mimetypes.dat", "r");
$ext_found = false;
while (!feof($fh) && !$ext_found){
while (!feof($fh) && !$ext_found) {
$line = fgets($fh);
preg_match("/(\.[a-z0-9]+)[ \t]+([^ \t\n\r]*)/i", $line, $result);
if ($extension == $result[1]){
if ($extension == $result[1]) {
$ext_found = true;
$contentType = $result[2];
}
@ -1034,12 +1078,12 @@ class ContactModule extends Module {
$stat = mapi_stream_stat($stream);
// File length = $stat["cb"]
$fhandle = fopen($tmpname,'w');
$fhandle = fopen($tmpname, 'w');
$buffer = null;
for($i = 0; $i < $stat["cb"]; $i += BLOCK_SIZE) {
for ($i = 0; $i < $stat["cb"]; $i += BLOCK_SIZE) {
// Write stream
$buffer = mapi_stream_read($stream, BLOCK_SIZE);
fwrite($fhandle,$buffer,strlen($buffer));
fwrite($fhandle, $buffer, strlen($buffer));
}
fclose($fhandle);
@ -1065,10 +1109,13 @@ class ContactModule extends Module {
}
}
private function startswith($haystack, $needle) {
private function startswith($haystack, $needle)
{
$haystack = str_replace("type=", "", $haystack); // remove type from string
return substr($haystack, 0, strlen($needle)) === $needle;
}
};
}
;
?>

View File

@ -3,7 +3,7 @@
* plugin.contactimporter.php, zarafa contact to vcf im/exporter
*
* Author: Christoph Haas <christoph.h@sprinternet.at>
* Copyright (C) 2012-2013 Christoph Haas
* Copyright (C) 2012-2016 Christoph Haas
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -28,18 +28,22 @@ require_once __DIR__ . "/download.php";
* With this plugin you can import a vcf file to your zarafa addressbook
*
*/
class Plugincontactimporter extends Plugin {
class Plugincontactimporter extends Plugin
{
/**
* Constructor
*/
function Plugincontactimporter() {}
function Plugincontactimporter()
{
}
/**
* Function initializes the Plugin and registers all hooks
*
* @return void
*/
function init() {
function init()
{
$this->registerHook('server.core.settings.init.before');
$this->registerHook('server.index.load.custom');
}
@ -51,8 +55,9 @@ class Plugincontactimporter extends Plugin {
* @param mixed $data object(s) related to the hook
* @return void
*/
function execute($eventID, &$data) {
switch($eventID) {
function execute($eventID, &$data)
{
switch ($eventID) {
case 'server.core.settings.init.before' :
$this->injectPluginSettings($data);
break;
@ -69,14 +74,14 @@ class Plugincontactimporter extends Plugin {
* settings.
* @param Array $data Reference to the data of the triggered hook
*/
function injectPluginSettings(&$data) {
function injectPluginSettings(&$data)
{
$data['settingsObj']->addSysAdminDefaults(Array(
'zarafa' => Array(
'v1' => Array(
'plugins' => Array(
'contactimporter' => Array(
'enable' => PLUGIN_CONTACTIMPORTER_USER_DEFAULT_ENABLE,
'enable_export' => PLUGIN_CONTACTIMPORTER_USER_DEFAULT_ENABLE_EXPORT,
'default_addressbook' => PLUGIN_CONTACTIMPORTER_DEFAULT
)
)
@ -85,4 +90,5 @@ class Plugincontactimporter extends Plugin {
));
}
}
?>

View File

@ -3,7 +3,7 @@
* upload.php, zarafa contact to vcf im/exporter
*
* Author: Christoph Haas <christoph.h@sprinternet.at>
* Copyright (C) 2012-2013 Christoph Haas
* Copyright (C) 2012-2016 Christoph Haas
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -26,11 +26,12 @@ require_once("../config.php");
/* disable error printing - otherwise json communication might break... */
ini_set('display_errors', '0');
/**
/**
* respond/echo JSON
* @param $arr
*/
function respondJSON($arr) {
function respondJSON($arr)
{
echo json_encode($arr);
}
@ -39,11 +40,12 @@ function respondJSON($arr) {
* @param $length the lenght of the generated string
* @return string a random string
*/
function randomstring($length = 6) {
function randomstring($length = 6)
{
// $chars - all allowed charakters
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
srand((double)microtime()*1000000);
srand((double)microtime() * 1000000);
$i = 0;
$pass = "";
while ($i < $length) {
@ -58,15 +60,15 @@ function randomstring($length = 6) {
$destpath = PLUGIN_CONTACTIMPORTER_TMP_UPLOAD;
$destpath .= $_FILES['vcfdata']['name'] . randomstring();
if(is_readable ($_FILES['vcfdata']['tmp_name'])) {
$result = move_uploaded_file($_FILES['vcfdata']['tmp_name'],$destpath);
if (is_readable($_FILES['vcfdata']['tmp_name'])) {
$result = move_uploaded_file($_FILES['vcfdata']['tmp_name'], $destpath);
if($result) {
respondJSON(array ('success'=>true, 'vcf_file'=>$destpath));
if ($result) {
respondJSON(array('success' => true, 'vcf_file' => $destpath));
} else {
respondJSON(array ('success'=>false,'error'=>"File could not be moved to TMP path! Check plugin config and folder permissions!"));
respondJSON(array('success' => false, 'error' => "File could not be moved to TMP path! Check plugin config and folder permissions!"));
}
} else {
respondJSON(array ('success'=>false,'error'=>"File could not be read by server, upload error!"));
respondJSON(array('success' => false, 'error' => "File could not be read by server, upload error!"));
}
?>

View File

@ -2,7 +2,7 @@
background: url(../images/import_icon.png) no-repeat !important;
background-repeat: no-repeat;
background-position: center;
background-size: 18px!important;
background-size: 18px !important;
}
.icon_contactimporter_export {