diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Contacts.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Contacts.php index 4da915d6f..002a8f384 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Contacts.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Contacts.php @@ -133,9 +133,8 @@ trait Contacts \ini_set('auto_detect_line_endings', '1'); $mData = $this->FilesProvider()->GetFile($oAccount, $sSavedName); if ($mData) { - $sFileStart = \fread($mData, 20); + $sFileStart = \fread($mData, 128); \rewind($mData); - if (false !== $sFileStart) { $sFileStart = \trim($sFileStart); if (false !== \strpos($sFileStart, 'BEGIN:VCARD')) { @@ -254,65 +253,30 @@ trait Contacts private function importContactsFromVcfFile(\RainLoop\Model\Account $oAccount, /*resource*/ $rFile): int { - $iCount = 0; - if ($oAccount && \is_resource($rFile)) { - $oAddressBookProvider = $this->AddressBookProvider($oAccount); - if ($oAddressBookProvider && $oAddressBookProvider->IsActive()) { - $sFile = \stream_get_contents($rFile); - if (\is_resource($rFile)) { - \fclose($rFile); - } - - if (is_string($sFile) && 5 < \strlen($sFile)) { - $this->Logger()->Write('Import contacts from vcf'); - $iCount = $oAddressBookProvider->ImportVcfFile($sFile); - } + $oAddressBookProvider = $this->AddressBookProvider($oAccount); + if (\is_resource($rFile) && $oAddressBookProvider && $oAddressBookProvider->IsActive()) { + $sFile = \stream_get_contents($rFile); + if (\is_string($sFile) && 5 < \strlen($sFile)) { + $this->Logger()->Write('Import contacts from vcf'); + return $oAddressBookProvider->ImportVcfFile($sFile); } } - - return $iCount; + return 0; } private function importContactsFromCsvFile(\RainLoop\Model\Account $oAccount, /*resource*/ $rFile, string $sFileStart): int { $iCount = 0; - $aHeaders = null; - $aData = array(); - - if ($oAccount && \is_resource($rFile)) { - $oAddressBookProvider = $this->AddressBookProvider($oAccount); - if ($oAddressBookProvider && $oAddressBookProvider->IsActive()) { - $sDelimiter = ((int)\strpos($sFileStart, ',') > (int)\strpos($sFileStart, ';')) ? ',' : ';'; - - \setlocale(LC_CTYPE, 'en_US.UTF-8'); - while (false !== ($mRow = \fgetcsv($rFile, 5000, $sDelimiter, '"'))) { - if (null === $aHeaders) { - if (3 >= \count($mRow)) { - return 0; - } - - $aHeaders = $mRow; - - foreach ($aHeaders as $iIndex => $sHeaderValue) { - $aHeaders[$iIndex] = \MailSo\Base\Utils::Utf8Clear($sHeaderValue); - } - } else { - $aNewItem = array(); - foreach ($aHeaders as $iIndex => $sHeaderValue) { - $aNewItem[$sHeaderValue] = isset($mRow[$iIndex]) ? $mRow[$iIndex] : ''; - } - - $aData[] = $aNewItem; - } - } - - if (\count($aData)) { - $this->oLogger->Write('Import contacts from csv'); - $iCount = $oAddressBookProvider->ImportCsvArray($aData); + $oAddressBookProvider = $this->AddressBookProvider($oAccount); + if (\is_resource($rFile) && $oAddressBookProvider && $oAddressBookProvider->IsActive()) { + $this->oLogger->Write('Import contacts from csv'); + $sDelimiter = ((int)\strpos($sFileStart, ',') > (int)\strpos($sFileStart, ';')) ? ',' : ';'; + foreach (\RainLoop\Providers\AddressBook\Utils::CsvStreamToContacts($rFile, $sDelimiter) as $oContact) { + if ($oAddressBookProvider->ContactSave($oContact)) { + ++$iCount; } } } - return $iCount; } diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook.php index 6136e07c5..6e2125724 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook.php @@ -83,19 +83,6 @@ class AddressBook extends AbstractProvider return $this->IsActive() ? $this->oDriver->IncFrec($aEmails, $bCreateAuto) : false; } - public function ImportCsvArray(array $aCsvData) : int - { - $iCount = 0; - if ($this->IsActive()) { - foreach (AddressBook\Utils::CsvArrayToContacts($aCsvData) as $oContact) { - if ($this->ContactSave($oContact)) { - ++$iCount; - } - } - } - return $iCount; - } - public function ImportVcfFile(string $sVcfData) : int { $iCount = 0; diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/Utils.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/Utils.php index 00834404d..62b1250f9 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/Utils.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Providers/AddressBook/Utils.php @@ -22,20 +22,29 @@ class Utils 'namesuffix' => 4, 'shortname' => 'NICKNAME', 'nickname' => 'NICKNAME', + 'birthday' => 'BDAY', + + 'mobile' => array('TEL', 'CELL'), + 'mobilephone' => array('TEL', 'CELL'), + + 'businessemail' => array('EMAIL', 'WORK'), + 'businessemail2' => array('EMAIL', 'WORK'), + 'businessemail3' => array('EMAIL', 'WORK'), 'businessphone' => array('TEL', 'WORK'), 'businessphone2' => array('TEL', 'WORK'), 'businessphone3' => array('TEL', 'WORK'), + 'businessmobile' => array('TEL', 'WORK,CELL'), + 'businessmobilephone' => array('TEL', 'WORK,CELL'), + 'businessweb' => array('URL', 'WORK'), + 'businesswebpage' => array('URL', 'WORK'), + 'businesswebsite' => array('URL', 'WORK'), 'companyphone' => array('TEL', 'WORK'), 'companymainphone' => array('TEL', 'WORK'), + + 'primaryphone' => array('TEL', 'PREF,HOME'), 'homephone' => array('TEL', 'HOME'), 'homephone2' => array('TEL', 'HOME'), 'homephone3' => array('TEL', 'HOME'), - 'mobile' => array('TEL', 'CELL'), - 'mobilephone' => array('TEL', 'CELL'), - 'businessmobile' => array('TEL', 'WORK,CELL'), - 'businessmobilephone' => array('TEL', 'WORK,CELL'), - 'otherphone' => 'TEL', - 'primaryphone' => array('TEL', 'PREF,HOME'), 'email' => array('EMAIL', 'HOME'), 'email2' => array('EMAIL', 'HOME'), 'email3' => array('EMAIL', 'HOME'), @@ -48,53 +57,73 @@ class Utils 'emailaddress' => array('EMAIL', 'HOME'), 'email2address' => array('EMAIL', 'HOME'), 'email3address' => array('EMAIL', 'HOME'), - 'otheremail' => 'EMAIL', - 'businessemail' => array('EMAIL', 'WORK'), - 'businessemail2' => array('EMAIL', 'WORK'), - 'businessemail3' => array('EMAIL', 'WORK'), 'personalemail' => array('EMAIL', 'HOME'), 'personalemail2' => array('EMAIL', 'HOME'), 'personalemail3' => array('EMAIL', 'HOME'), + 'personalwebsite' => array('URL', 'HOME'), + + 'otheremail' => 'EMAIL', + 'otherphone' => 'TEL', 'notes' => 'NOTE', 'web' => 'URL', - 'businessweb' => array('URL', 'WORK'), 'webpage' => 'URL', - 'businesswebpage' => array('URL', 'WORK'), - 'website' => 'URL', - 'businesswebsite' => array('URL', 'WORK'), - 'personalwebsite' => 'URL', - 'birthday' => 'BDAY' + 'website' => 'URL' +/* + TODO: + 'company' => '', + 'department' => '', + 'jobtitle' => '', + 'officelocation' => '', + 'homestreet' => '', + 'homecity' => '', + 'homestate' => '', + 'homepostalcode' => '', + 'homecountry' => '', + 'businessstreet' => '', + 'businesscity' => '', + 'businessstate' => '', + 'businesspostalcode' => '', + 'businesscountry' => '', +*/ ); - public static function CsvArrayToContacts(array $aCsvData) : iterable + public static function CsvStreamToContacts(/*resource*/ $rFile, string $sDelimiter) : iterable { - foreach ($aCsvData as $aItem) { + \setlocale(LC_CTYPE, 'en_US.UTF-8'); + + $aHeaders = \fgetcsv($rFile, 5000, $sDelimiter, '"'); + if (!$aHeaders || 3 >= \count($aHeaders)) { + return; + } + foreach ($aHeaders as $iIndex => $sItemName) { + $sItemName = \MailSo\Base\Utils::Utf8Clear($sItemName); + $sItemName = \strtoupper(\trim(\preg_replace('/[\s\-]+/', '', $sItemName))); + if (!\array_key_exists($sItemName, \Sabre\VObject\Component\VCard::$propertyMap)) { + $sItemName = \strtolower($sItemName); + $sItemName = isset(static::$aMap[$sItemName]) ? static::$aMap[$sItemName] : null; + } + $aHeaders[$iIndex] = $sItemName; + } + + while (false !== ($mRow = \fgetcsv($rFile, 5000, $sDelimiter, '"'))) { \MailSo\Base\Utils::ResetTimeLimit(); $iCount = 0; $oVCard = new \Sabre\VObject\Component\VCard; $aName = ['','','','','']; - foreach ($aItem as $sItemName => $sItemValue) { - $sItemName = \strtoupper(\trim(\preg_replace('/[\s\-]+/', '', $sItemName))); + foreach ($mRow as $iIndex => $sItemValue) { + $sItemName = $aHeaders[$iIndex]; $sItemValue = \trim($sItemValue); - if (!empty($sItemName) && !empty($sItemValue)) { - if (\array_key_exists($sItemName, \Sabre\VObject\Component\VCard::$propertyMap)) { - $mData = $sItemName; + if (isset($sItemName) && !empty($sItemValue)) { + $mType = \is_array($sItemName) ? $sItemName[0] : $sItemName; + ++$iCount; + if (\is_int($mType)) { + $aName[$mType] = $sItemValue; + } else if (\is_array($sItemName)) { + $oVCard->add($mType, $sItemValue, ['type' => $sItemName[1]]); + } else if ('FN' === $mType || 'NICKNAME' === $mType) { + $oVCard->$mType = $sItemValue; } else { - $sItemName = \strtolower($sItemName); - $mData = !empty($sItemName) && isset($aMap[$sItemName]) ? $aMap[$sItemName] : null; - } - if ($mData) { - $mType = \is_array($mData) ? $mData[0] : $mData; - ++$iCount; - if (\is_int($mType)) { - $aName[$mType] = $sItemValue; - } else if (\is_array($mData)) { - $oVCard->add($mType, $sItemValue, ['type' => $mData[1]]); - } else if ('FN' === $mType || 'NICKNAME' === $mType) { - $oVCard->$mType = $sItemValue; - } else { - $oVCard->add($mType, $sItemValue); - } + $oVCard->add($mType, $sItemValue); } } }