diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/build.xml b/build.xml
index 687da16..c47e16b 100644
--- a/build.xml
+++ b/build.xml
@@ -1,18 +1,15 @@
-
-
-
-
-
-
-
+
+
+
+
+
-
@@ -21,30 +18,8 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -54,8 +29,7 @@
-
-
+
@@ -68,16 +42,6 @@
-
-
-
-
-
-
-
-
-
-
@@ -89,19 +53,11 @@
-
-
-
-
-
-
-
-
-
+
@@ -110,8 +66,8 @@
-
-
+
+
@@ -155,16 +111,7 @@
var npgettext = function(msgctxt, msgid, msgid_plural, count) {};
var pgettext = function(msgctxt, msgid) {};
-
-
+
@@ -172,105 +119,81 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
- Processing manifest.xml
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/config.php b/config.php
index f8c526e..29ed52f 100644
--- a/config.php
+++ b/config.php
@@ -2,7 +2,7 @@
/** 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); // currently not available
+ define('PLUGIN_CONTACTIMPORTER_USER_DEFAULT_ENABLE_EXPORT', false);
/** The default addressbook to import to (default: contact)*/
define('PLUGIN_CONTACTIMPORTER_DEFAULT', "contact");
diff --git a/js/dialogs/ImportPanel.js b/js/dialogs/ImportPanel.js
index c58fbe5..0840159 100644
--- a/js/dialogs/ImportPanel.js
+++ b/js/dialogs/ImportPanel.js
@@ -47,7 +47,7 @@ Zarafa.plugins.contactimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
config = config || {};
var self = this;
- if(typeof config.filename !== "undefined") {
+ if(!Ext.isEmpty(config.filename)) {
this.vcffile = config.filename;
}
@@ -146,13 +146,13 @@ Zarafa.plugins.contactimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
var i = 0;
for(i = 0; i < contactdata.contacts.length; i++) {
- parsedData[i] = new Array(
+ parsedData[i] = [
contactdata.contacts[i]["display_name"],
contactdata.contacts[i]["given_name"],
contactdata.contacts[i]["surname"],
contactdata.contacts[i]["company_name"],
contactdata.contacts[i]
- );
+ ];
}
} else {
return null;
@@ -202,10 +202,10 @@ Zarafa.plugins.contactimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
/* add all local contact folders */
var i = 0;
- myStore.push(new Array(defaultFolder.getDefaultFolderKey(), defaultFolder.getDisplayName()));
+ myStore.push([defaultFolder.getDefaultFolderKey(), defaultFolder.getDisplayName()]);
for(i = 0; i < subFolders.length; i++) {
/* Store all subfolders */
- myStore.push(new Array(subFolders[i].getDisplayName(), subFolders[i].getDisplayName(), false)); // 3rd field = isPublicfolder
+ myStore.push([subFolders[i].getDisplayName(), subFolders[i].getDisplayName(), false]); // 3rd field = isPublicfolder
}
/* add all shared contact folders */
@@ -217,7 +217,7 @@ Zarafa.plugins.contactimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
var pubSubFolders = pubFolder.getChildren();
for(i = 0; i < pubSubFolders.length; i++) {
if(pubSubFolders[i].isContainerClass("IPF.Contact")){
- myStore.push(new Array(pubSubFolders[i].getDisplayName(), pubSubFolders[i].getDisplayName() + " [Shared]", true)); // 3rd field = isPublicfolder
+ myStore.push([pubSubFolders[i].getDisplayName(), pubSubFolders[i].getDisplayName() + " [Shared]", true]); // 3rd field = isPublicfolder
}
}
} catch (e) {
@@ -455,7 +455,7 @@ Zarafa.plugins.contactimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
if(addressbookexist) {
this.loadMask.show();
- var uids = new Array();
+ var uids = [];
var store_entryid = "";
//receive Records from grid rows
diff --git a/js/plugin.contactimporter.js b/js/plugin.contactimporter.js
index aba36a7..c36a696 100644
--- a/js/plugin.contactimporter.js
+++ b/js/plugin.contactimporter.js
@@ -47,6 +47,7 @@ Zarafa.plugins.contactimporter.ImportPlugin = Ext.extend(Zarafa.core.Plugin, {
/* directly import received vcfs */
this.registerInsertionPoint('common.contextmenu.attachment.actions', this.createAttachmentImportButton);
+
/* add import button to south navigation */
this.registerInsertionPoint("navigation.south", this.createImportButton, this);
},
@@ -60,7 +61,6 @@ Zarafa.plugins.contactimporter.ImportPlugin = Ext.extend(Zarafa.core.Plugin, {
createImportButton: function () {
var button = {
xtype : 'button',
- id : "importcontactsbutton",
text : _('Import Contacts'),
iconCls : 'icon_contactimporter_button',
navigationContext : container.getContextByName('contact'),
@@ -90,9 +90,9 @@ Zarafa.plugins.contactimporter.ImportPlugin = Ext.extend(Zarafa.core.Plugin, {
var extension = record.data.name.split('.').pop().toLowerCase();
if(record.data.filetype == "text/vcard" || extension == "vcf" || extension == "vcard") {
- item.setDisabled(false);
+ item.setVisible(false);
} else {
- item.setDisabled(true);
+ item.setVisible(true);
}
}
};
@@ -103,10 +103,7 @@ Zarafa.plugins.contactimporter.ImportPlugin = Ext.extend(Zarafa.core.Plugin, {
*/
gotAttachmentFileName: function(response) {
if(response.status == true) {
- Zarafa.core.data.UIFactory.openLayerComponent(Zarafa.core.data.SharedComponentType['plugins.contactimporter.dialogs.importcontacts'], undefined, {
- manager : Ext.WindowMgr,
- filename : response.tmpname
- });
+ this.openImportDialog(response.tmpname);
} else {
Zarafa.common.dialogs.MessageBox.show({
title : _('Error'),
@@ -182,12 +179,23 @@ Zarafa.plugins.contactimporter.ImportPlugin = Ext.extend(Zarafa.core.Plugin, {
* Clickhandler for the button
*/
onImportButtonClick: function () {
- Ext.getCmp("importcontactsbutton").disable();
- Zarafa.core.data.UIFactory.openLayerComponent(Zarafa.core.data.SharedComponentType['plugins.contactimporter.dialogs.importcontacts'], undefined, {
- manager : Ext.WindowMgr
- });
+ this.openImportDialog();
},
-
+
+ /**
+ * Open the import dialog.
+ *
+ * @param {String} filename
+ */
+ openImportDialog: function(filename) {
+ var componentType = Zarafa.core.data.SharedComponentType['plugins.contactimporter.dialogs.importcontacts'];
+ var config = {
+ filename: filename
+ };
+
+ Zarafa.core.data.UIFactory.openLayerComponent(componentType, undefined, config);
+ },
+
/**
* Bid for the type of shared component
* and the given record.
@@ -200,7 +208,7 @@ Zarafa.plugins.contactimporter.ImportPlugin = Ext.extend(Zarafa.core.Plugin, {
var bid = -1;
switch(type) {
case Zarafa.core.data.SharedComponentType['plugins.contactimporter.dialogs.importcontacts']:
- bid = 2;
+ bid = 1;
break;
}
return bid;
diff --git a/manifest.xml b/manifest.xml
index bcd1b92..acafc6f 100644
--- a/manifest.xml
+++ b/manifest.xml
@@ -2,7 +2,7 @@
- @_@PLUGIN_VERSION@_@
+ 2.0.0
contactimporter
VCF Contact Importer/Exporter
Christoph Haas
@@ -24,6 +24,7 @@
js/contactimporter-debug.js
js/plugin.contactimporter.js
+ js/ABOUT.js
js/data/ResponseHandler.js
js/dialogs/ImportContentPanel.js
js/dialogs/ImportPanel.js
diff --git a/php/vcf/class.vCard.php b/php/vcf/class.vCard.php
index 3b30e7e..bed6891 100644
--- a/php/vcf/class.vCard.php
+++ b/php/vcf/class.vCard.php
@@ -5,9 +5,8 @@
* @link https://github.com/nuovo/vCard-parser
* @author Martins Pilsetnieks, Roberts Bruveris
* @see RFC 2426, RFC 2425
- * @version 0.4.8
-*/
-
+ * @version 0.4.9
+ */
class vCard implements Countable, Iterator
{
const MODE_ERROR = 'error';
@@ -42,15 +41,15 @@ class vCard implements Countable, Iterator
* @static Parts of structured elements according to the spec.
*/
private static $Spec_StructuredElements = array(
- 'n' => array('LastName', 'FirstName', 'AdditionalNames', 'Prefixes', 'Suffixes'),
- 'adr' => array('POBox', 'ExtendedAddress', 'StreetAddress', 'Locality', 'Region', 'PostalCode', 'Country'),
- 'geo' => array('Latitude', 'Longitude'),
- 'org' => array('Name', 'Unit1', 'Unit2')
+ 'n' => array('lastname', 'firstname', 'additionalnames', 'prefixes', 'suffixes'),
+ 'adr' => array('pobox', 'extendedaddress', 'streetaddress', 'locality', 'region', 'postalcode', 'country'),
+ 'geo' => array('latitude', 'longitude'),
+ 'org' => array('name', 'unit1', 'unit2')
);
private static $Spec_MultipleValueElements = array('nickname', 'categories');
private static $Spec_ElementTypes = array(
- 'email' => array('internet', 'x400', 'pref'),
+ 'email' => array('internet', 'x400', 'pref', 'home', 'work'),
'adr' => array('dom', 'intl', 'postal', 'parcel', 'home', 'work', 'pref'),
'label' => array('dom', 'intl', 'postal', 'parcel', 'home', 'work', 'pref'),
'tel' => array('home', 'msg', 'work', 'pref', 'voice', 'fax', 'cell', 'video', 'pager', 'bbs', 'modem', 'car', 'isdn', 'pcs'),
@@ -121,21 +120,26 @@ class vCard implements Countable, Iterator
$this -> Mode = $vCardBeginCount == 1 ? vCard::MODE_SINGLE : vCard::MODE_MULTIPLE;
// Removing/changing inappropriate newlines, i.e., all CRs or multiple newlines are changed to a single newline
- $this -> RawData = str_replace("\r", "\n", $this -> RawData);
- $this -> RawData = preg_replace('{(\n+)}', "\n", $this -> RawData);
+
+ // MCA: removed, this break crlf vcard specification, all line dilimiter are CRLF
+ //$this -> RawData = str_replace("\r", "\n", $this -> RawData);
+ //$this -> RawData = preg_replace('{(\n)+}', "\n", $this -> RawData);
// In multiple card mode the raw text is split at card beginning markers and each
// fragment is parsed in a separate vCard object.
if ($this -> Mode == self::MODE_MULTIPLE)
{
- $this -> RawData = explode('BEGIN:VCARD', $this -> RawData);
+ //Cannot use "explode", because we need to ignore, for example, 'AGENT:BEGIN:VCARD'
+ $this -> RawData = preg_split('{^BEGIN\:VCARD}miS', $this -> RawData);
$this -> RawData = array_filter($this -> RawData);
foreach ($this -> RawData as $SinglevCardRawData)
{
+ // mca: remove \n and \r at start
+ //$SinglevCardRawData=ltrim($SinglevCardRawData);
// Prepending "BEGIN:VCARD" to the raw string because we exploded on that one.
// If there won't be the BEGIN marker in the new object, it will fail.
- $SinglevCardRawData = 'BEGIN:VCARD'."\n".$SinglevCardRawData;
+ $SinglevCardRawData = 'BEGIN:VCARD'.$SinglevCardRawData;
$ClassName = get_class($this);
$this -> Data[] = new $ClassName(false, $SinglevCardRawData);
@@ -143,20 +147,20 @@ class vCard implements Countable, Iterator
}
else
{
- // Protect the BASE64 final = sign (detected by the line beginning with whitespace), otherwise the next replace will get rid of it
- $this -> RawData = preg_replace('{(\n\s.+)=(\n)}', '$1-base64=-$2', $this -> RawData);
-
// Joining multiple lines that are split with a hard wrap and indicated by an equals sign at the end of line
// (quoted-printable-encoded values in v2.1 vCards)
- $this -> RawData = str_replace("=\n", '', $this -> RawData);
+ $this -> RawData = str_replace("=\r\n", '', $this -> RawData);
+
+ // Protect the BASE64 final = sign (detected by the line beginning with whitespace), otherwise the next replace will get rid of it
+ $this -> RawData = preg_replace('{(\r\n\s.+)=(\r\n)}', '$1-base64=-$2', $this -> RawData);
// Joining multiple lines that are split with a soft wrap (space or tab on the beginning of the next line
- $this -> RawData = str_replace(array("\n ", "\n\t"), '-wrap-', $this -> RawData);
+ $this -> RawData = str_replace(array("\r\n ", "\r\n\t"), '-wrap-', $this -> RawData);
// Restoring the BASE64 final equals sign (see a few lines above)
- $this -> RawData = str_replace("-base64=-\n", "=\n", $this -> RawData);
+ $this -> RawData = str_replace("-base64=-\r\n", "=\r\n", $this -> RawData);
- $Lines = explode("\n", $this -> RawData);
+ $Lines = explode("\r\n", $this -> RawData);
foreach ($Lines as $Line)
{
@@ -212,6 +216,7 @@ class vCard implements Countable, Iterator
$ItemIndex = (int)str_ireplace('item', '', $TmpKey[0]);
}
+
if (count($KeyParts) > 1)
{
$Parameters = self::ParseParameters($Key, array_slice($KeyParts, 1));
@@ -262,7 +267,7 @@ class vCard implements Countable, Iterator
$Value = self::ParseStructuredValue($Value, $Key);
if ($Type)
{
- $Value['Type'] = $Type;
+ $Value['type'] = $Type;
}
}
else
@@ -275,15 +280,15 @@ class vCard implements Countable, Iterator
if ($Type)
{
$Value = array(
- 'Value' => $Value,
- 'Type' => $Type
+ 'value' => $Value,
+ 'type' => $Type
);
}
}
if (is_array($Value) && $Encoding)
{
- $Value['Encoding'] = $Encoding;
+ $Value['encoding'] = $Encoding;
}
if (!isset($this -> Data[$Key]))
@@ -296,6 +301,22 @@ class vCard implements Countable, Iterator
}
}
+ /**
+ * method to get key list of the current vcard
+ *
+ * @return array list of key
+ */
+ public function getKeyList()
+ {
+ $keylist=array();
+ if (isset($this -> Data))
+ {
+ foreach($this -> Data as $key => $val)
+ $keylist[]=$key;
+ }
+ return $keylist;
+ }
+
/**
* Magic method to get the various vCard values as object members, e.g.
* a call to $vCard -> N gets the "N" value
@@ -318,10 +339,10 @@ class vCard implements Countable, Iterator
$Value = $this -> Data[$Key];
foreach ($Value as $K => $V)
{
- if (stripos($V['Value'], 'uri:') === 0)
+ if (isset($V['Value']) && stripos($V['Value'], 'uri:') === 0)
{
- $Value[$K]['Value'] = substr($V, 4);
- $Value[$K]['Encoding'] = 'uri';
+ $Value[$K]['value'] = substr($V, 4);
+ $Value[$K]['encoding'] = 'uri';
}
}
return $Value;
@@ -340,6 +361,20 @@ class vCard implements Countable, Iterator
return array();
}
+ /**
+ * Magic method to check isset for the various vCard values as object members, e.g.
+ * a call to isset( $vCard -> fn ) checks existence of a value.
+ *
+ * @param string Key
+ *
+ * @return bool isset
+ */
+ public function __isset($Key) {
+ $Key = strtolower($Key);
+ $val = $this->$Key;
+ return isset($val);
+ }
+
/**
* Saves an embedded file
*
@@ -361,15 +396,15 @@ class vCard implements Countable, Iterator
}
// Returing false if it is an image URL
- if (stripos($this -> Data[$Key][$Index]['Value'], 'uri:') === 0)
+ if (stripos($this -> Data[$Key][$Index]['value'], 'uri:') === 0)
{
return false;
}
if (is_writable($TargetPath) || (!file_exists($TargetPath) && is_writable(dirname($TargetPath))))
{
- $RawContent = $this -> Data[$Key][$Index]['Value'];
- if (isset($this -> Data[$Key][$Index]['Encoding']) && $this -> Data[$Key][$Index]['Encoding'] == 'b')
+ $RawContent = $this -> Data[$Key][$Index]['value'];
+ if (isset($this -> Data[$Key][$Index]['encoding']) && $this -> Data[$Key][$Index]['encoding'] == 'b')
{
$RawContent = base64_decode($RawContent);
}
@@ -404,10 +439,10 @@ class vCard implements Countable, Iterator
if (count($Arguments) > 1)
{
- $Types = array_values(array_slice($Arguments, 1));
+ $Types = array_map('strtolower', array_values(array_slice($Arguments, 1)));
if (isset(self::$Spec_StructuredElements[$Key]) &&
- in_array($Arguments[1], self::$Spec_StructuredElements[$Key])
+ in_array(strtolower($Arguments[1]), self::$Spec_StructuredElements[$Key])
)
{
$LastElementIndex = 0;
@@ -439,8 +474,8 @@ class vCard implements Countable, Iterator
elseif (isset(self::$Spec_ElementTypes[$Key]))
{
$this -> Data[$Key][] = array(
- 'Value' => $Value,
- 'Type' => $Types
+ 'value' => $Value,
+ 'type' => $Types
);
}
}
@@ -475,9 +510,9 @@ class vCard implements Countable, Iterator
foreach ($Values as $Index => $Value)
{
$Text .= $KeyUC;
- if (is_array($Value) && isset($Value['Type']))
+ if (is_array($Value) && isset($Value['type']))
{
- $Text .= ';TYPE='.self::PrepareTypeStrForOutput($Value['Type']);
+ $Text .= ';TYPE='.self::PrepareTypeStrForOutput($Value['type']);
}
$Text .= ':';
@@ -492,7 +527,7 @@ class vCard implements Countable, Iterator
}
elseif (is_array($Value) && isset(self::$Spec_ElementTypes[$Key]))
{
- $Text .= $Value['Value'];
+ $Text .= $Value['value'];
}
else
{
@@ -574,7 +609,8 @@ class vCard implements Countable, Iterator
$Parameters = array();
foreach ($RawParams as $Item)
{
- $Parameters[] = explode('=', strtolower($Item));
+ // try to correct issue https://github.com/nuovo/vCard-parser/issues/20
+ $Parameters[] = explode('=', strtolower($Item),2);
}
$Type = array();
@@ -604,10 +640,13 @@ class vCard implements Countable, Iterator
}
elseif (count($Parameter) > 2)
{
- $TempTypeParams = self::ParseParameters($Key, explode(',', $RawParams[$Index]));
- if ($TempTypeParams['type'])
+ if(count(explode(',', $RawParams[$Index], -1)) > 0)
{
- $Type = array_merge($Type, $TempTypeParams['type']);
+ $TempTypeParams = self::ParseParameters($Key, explode(',', $RawParams[$Index]));
+ if ($TempTypeParams['type'])
+ {
+ $Type = array_merge($Type, $TempTypeParams['type']);
+ }
}
}
else