New adress book provider

This commit is contained in:
RainLoop Team 2014-04-18 19:31:30 +04:00
parent 5da5e8ac61
commit 91e3bd72d6
8 changed files with 2167 additions and 0 deletions

View file

@ -0,0 +1,65 @@
<?php
namespace RainLoop\Providers\AddressBook;
interface AddressBookInterface
{
/**
* @return bool
*/
public function IsSupported();
/**
* @param string $sEmail
* @param \RainLoop\Providers\AddressBook\Classes\Contact $oContact
*
* @return bool
*/
public function ContactSave($sEmail, &$oContact);
/**
* @param string $sEmail
* @param array $aContactIds
*
* @return bool
*/
public function DeleteContacts($sEmail, $aContactIds);
/**
* @param string $sEmail
* @param array $aTagsIds
*
* @return bool
*/
public function DeleteTags($sEmail, $aTagsIds);
/**
* @param string $sEmail
* @param int $iOffset = 0
* @param int $iLimit = 20
* @param string $sSearch = ''
* @param int $iResultCount = 0
*
* @return array
*/
public function GetContacts($sEmail, $iOffset = 0, $iLimit = 20, $sSearch = '', &$iResultCount = 0);
/**
* @param string $sEmail
* @param string $sSearch
* @param int $iLimit = 20
*
* @return array
*
* @throws \InvalidArgumentException
*/
public function GetSuggestions($sEmail, $sSearch, $iLimit = 20);
/**
* @param string $sEmail
* @param array $aEmails
*
* @return bool
*/
public function IncFrec($sEmail, $aEmails);
}

View file

@ -0,0 +1,545 @@
<?php
namespace RainLoop\Providers\AddressBook\Classes;
use
RainLoop\Providers\AddressBook\Enumerations\PropertyType,
RainLoop\Providers\AddressBook\Classes\Property
;
class Contact
{
/**
* @var string
*/
public $IdContact;
/**
* @var string
*/
public $IdContactStr;
/**
* @var string
*/
public $Display;
/**
* @var int
*/
public $Changed;
/**
* @var array
*/
public $Properties;
/**
* @var array
*/
public $ReadOnly;
/**
* @var int
*/
public $IdPropertyFromSearch;
/**
* @var string
*/
public $Hash;
public function __construct()
{
$this->Clear();
}
public function Clear()
{
$this->IdContact = '';
$this->IdContactStr = '';
$this->IdUser = 0;
$this->Display = '';
$this->Changed = \time();
$this->Properties = array();
$this->ReadOnly = false;
$this->IdPropertyFromSearch = 0;
$this->Hash = '';
}
public function UpdateDependentValues()
{
$sLastName = '';
$sFirstName = '';
$sEmail = '';
$sOther = '';
$oFullNameProperty = null;
foreach ($this->Properties as /* @var $oProperty \RainLoop\Providers\AddressBook\Classes\Property */ &$oProperty)
{
if ($oProperty)
{
$oProperty->UpdateDependentValues();
if (!$oFullNameProperty && PropertyType::FULLNAME === $oProperty->Type)
{
$oFullNameProperty =& $oProperty;
}
if (0 < \strlen($oProperty->Value))
{
if ('' === $sEmail && $oProperty->IsEmail())
{
$sEmail = $oProperty->Value;
}
else if ('' === $sLastName && PropertyType::LAST_NAME === $oProperty->Type)
{
$sLastName = $oProperty->Value;
}
else if ('' === $sFirstName && PropertyType::FIRST_NAME === $oProperty->Type)
{
$sFirstName = $oProperty->Value;
}
else if (\in_array($oProperty->Type, array(PropertyType::FULLNAME,
PropertyType::PHONE_PERSONAL, PropertyType::PHONE_BUSSINES, PropertyType::PHONE_OTHER,
PropertyType::MOBILE_PERSONAL, PropertyType::MOBILE_BUSSINES, PropertyType::MOBILE_OTHER
)))
{
$sOther = $oProperty->Value;
}
}
}
}
if (empty($this->IdContactStr))
{
$this->RegenerateContactStr();
}
$sDisplay = '';
if (0 < \strlen($sLastName) || 0 < \strlen($sFirstName))
{
$sDisplay = \trim($sFirstName.' '.$sLastName);
}
if ('' === $sDisplay && 0 < \strlen($sEmail))
{
$sDisplay = \trim($sEmail);
}
if ('' === $sDisplay)
{
$sDisplay = $sOther;
}
$this->Display = \trim($sDisplay);
$bNewFull = false;
if (!$oFullNameProperty)
{
$oFullNameProperty = new \RainLoop\Providers\AddressBook\Classes\Property(PropertyType::FULLNAME, $this->Display);
$bNewFull = true;
}
$oFullNameProperty->Value = $this->Display;
$oFullNameProperty->UpdateDependentValues();
if ($bNewFull)
{
$this->Properties[] = $oFullNameProperty;
}
}
/**
* @return array
*/
public function RegenerateContactStr()
{
$this->IdContactStr = \Sabre\DAV\UUIDUtil::getUUID();
}
/**
* @return array
*/
public function GetEmails()
{
$aResult = array();
foreach ($this->Properties as /* @var $oProperty \RainLoop\Providers\AddressBook\Classes\Property */ &$oProperty)
{
if ($oProperty && $oProperty->IsEmail())
{
$aResult[] = $oProperty->Value;
}
}
return \array_unique($aResult);
}
/**
* @param \Sabre\VObject\Document $oVCard
*/
public function ParseVCard($oVCard)
{
$bNew = empty($this->IdContact);
if (!$bNew)
{
$this->Properties = array();
}
$aProperties = array();
if ($oVCard)
{
$bOldVersion = empty($oVCard->VERSION) ? false :
\in_array((string) $oVCard->VERSION, array('2.1', '2.0', '1.0'));
$this->IdContactStr = !empty($oVCard->UID) ? (string) $oVCard->UID : \Sabre\DAV\UUIDUtil::getUUID();
if (isset($oVCard->FN) && '' !== \trim($oVCard->FN))
{
$sValue = \trim($oVCard->FN);
if ($bOldVersion && !isset($oVCard->FN->parameters['CHARSET']))
{
if (0 < \strlen($sValue))
{
$sEncValue = @\utf8_encode($sValue);
if (0 === \strlen($sEncValue))
{
$sEncValue = $sValue;
}
$sValue = $sEncValue;
}
}
$sValue = \MailSo\Base\Utils::Utf8Clear($sValue);
$aProperties[] = new Property(PropertyType::FULLNAME, $sValue);
}
if (isset($oVCard->NICKNAME) && '' !== \trim($oVCard->NICKNAME))
{
$sValue = \trim($oVCard->NICKNAME);
if ($bOldVersion && !isset($oVCard->NICKNAME->parameters['CHARSET']))
{
if (0 < \strlen($sValue))
{
$sEncValue = @\utf8_encode($sValue);
if (0 === \strlen($sEncValue))
{
$sEncValue = $sValue;
}
$sValue = $sEncValue;
}
}
$sValue = \MailSo\Base\Utils::Utf8Clear($sValue);
$aProperties[] = new Property(PropertyType::NICK_NAME, $sValue);
}
// if (isset($oVCard->NOTE) && '' !== \trim($oVCard->NOTE))
// {
// $sValue = \trim($oVCard->NOTE);
// if ($bOldVersion)
// {
// if (0 < \strlen($sValue))
// {
// $sEncValue = @\utf8_encode($sValue);
// if (0 === \strlen($sEncValue))
// {
// $sEncValue = $sValue;
// }
//
// $sValue = $sEncValue;
// }
// }
//
// $sValue = \MailSo\Base\Utils::Utf8Clear($sValue);
// $aProperties[] = new Property(PropertyType::NOTE, $sValue);
// }
if (isset($oVCard->N))
{
$aNames = $oVCard->N->getParts();
foreach ($aNames as $iIndex => $sValue)
{
$sValue = \trim($sValue);
if ($bOldVersion && !isset($oVCard->N->parameters['CHARSET']))
{
if (0 < \strlen($sValue))
{
$sEncValue = @\utf8_encode($sValue);
if (0 === \strlen($sEncValue))
{
$sEncValue = $sValue;
}
$sValue = $sEncValue;
}
}
$sValue = \MailSo\Base\Utils::Utf8Clear($sValue);
switch ($iIndex) {
case 0:
$aProperties[] = new Property(PropertyType::LAST_NAME, $sValue);
break;
case 1:
$aProperties[] = new Property(PropertyType::FIRST_NAME, $sValue);
break;
case 2:
$aProperties[] = new Property(PropertyType::MIDDLE_NAME, $sValue);
break;
case 3:
$aProperties[] = new Property(PropertyType::NAME_PREFIX, $sValue);
break;
case 4:
$aProperties[] = new Property(PropertyType::NAME_SUFFIX, $sValue);
break;
}
}
}
if (isset($oVCard->EMAIL))
{
$bPref = false;
foreach($oVCard->EMAIL as $oEmail)
{
$oTypes = $oEmail ? $oEmail['TYPE'] : null;
$sEmail = $oEmail ? \trim($oEmail->getValue()) : '';
if (0 < \strlen($sEmail))
{
if ($oTypes)
{
$oProp = new Property($oTypes->has('WORK') ? PropertyType::EMAIl_BUSSINES : PropertyType::EMAIl_PERSONAL, $sEmail);
if (!$bPref && $oTypes->has('pref'))
{
$bPref = true;
\array_unshift($aProperties, $oProp);
}
else
{
\array_push($aProperties, $oProp);
}
}
else
{
\array_unshift($aProperties,
new Property(PropertyType::EMAIl_PERSONAL, $sEmail));
}
}
}
}
// if (isset($oVCard->URL))
// {
// foreach($oVCard->URL as $oUrl)
// {
// $oTypes = $oUrl ? $oUrl['TYPE'] : null;
// $sUrl = $oUrl ? \trim((string) $oUrl) : '';
//
// if (0 < \strlen($sUrl))
// {
// \array_push($aProperties,
// new Property($oTypes && $oTypes->has('WORK') ?
// PropertyType::WEB_PAGE_BUSSINES : PropertyType::WEB_PAGE_PERSONAL, $sUrl));
// }
// }
// }
if (isset($oVCard->TEL))
{
$bPref = false;
foreach($oVCard->TEL as $oTel)
{
$oTypes = $oTel ? $oTel['TYPE'] : null;
$sTel = $oTypes ? \trim((string) $oTel) : '';
if (0 < \strlen($sTel))
{
if ($oTypes)
{
$oProp = null;
$bWork = $oTypes->has('WORK');
switch (true)
{
case $oTypes->has('VOICE'):
$oProp = new Property($bWork ? PropertyType::PHONE_BUSSINES : PropertyType::PHONE_PERSONAL, $sTel);
break;
case $oTypes->has('CELL'):
$oProp = new Property($bWork ? PropertyType::MOBILE_BUSSINES : PropertyType::MOBILE_PERSONAL, $sTel);
break;
case $oTypes->has('FAX'):
$oProp = new Property($bWork ? PropertyType::FAX_BUSSINES : PropertyType::FAX_PERSONAL, $sTel);
break;
case $oTypes->has('WORK'):
$oProp = new Property(PropertyType::MOBILE_BUSSINES, $sTel);
break;
default:
$oProp = new Property(PropertyType::MOBILE_PERSONAL, $sTel);
break;
}
if ($oProp)
{
if (!$bPref && $oTypes->has('pref'))
{
$bPref = true;
\array_unshift($aProperties, $oProp);
}
else
{
\array_push($aProperties, $oProp);
}
}
}
else
{
\array_unshift($aProperties,
new Property(PropertyType::MOBILE_PERSONAL, $sTel));
}
}
}
}
$this->Properties = $aProperties;
}
$this->UpdateDependentValues(false);
}
/**
* @return string
*/
public function ToVCardObject($sPreVCard = '')
{
$oVCard = null;
if (0 < \strlen($sPreVCard))
{
try
{
$oVCard = \Sabre\VObject\Reader::read($sPreVCard);
}
catch (\Exception $oExc) {};
}
if (!$oVCard)
{
$oVCard = new \Sabre\VObject\Component\VCard();
}
$oVCard->VERSION = '3.0';
$oVCard->PRODID = '-//RainLoop//'.APP_VERSION.'//EN';
unset($oVCard->FN, $oVCard->EMAIL, $oVCard->TEL);
$bPrefEmail = $bPrefPhone = false;
$sFirstName = $sLastName = $sMiddleName = $sSuffix = $sPrefix = '';
foreach ($this->Properties as /* @var $oProperty \RainLoop\Providers\AddressBook\Classes\Property */ &$oProperty)
{
if ($oProperty)
{
switch ($oProperty->Type)
{
case PropertyType::FULLNAME:
$oVCard->FN = $oProperty->Value;
break;
case PropertyType::NICK_NAME:
$oVCard->NICKNAME = $oProperty->Value;
break;
case PropertyType::FIRST_NAME:
$sFirstName = $oProperty->Value;
break;
case PropertyType::LAST_NAME:
$sLastName = $oProperty->Value;
break;
case PropertyType::MIDDLE_NAME:
$sMiddleName = $oProperty->Value;
break;
case PropertyType::NAME_SUFFIX:
$sSuffix = $oProperty->Value;
break;
case PropertyType::NAME_PREFIX:
$sPrefix = $oProperty->Value;
break;
case PropertyType::EMAIl_PERSONAL:
case PropertyType::EMAIl_BUSSINES:
case PropertyType::EMAIl_OTHER:
$aParams = array('TYPE' => array('INTERNET'));
$aParams['TYPE'][] = PropertyType::EMAIl_BUSSINES === $oProperty->Type ? 'WORK' : 'HOME';
if (!$bPrefEmail)
{
$bPrefEmail = true;
$aParams['TYPE'][] = 'pref';
}
$oVCard->add('EMAIL', $oProperty->Value, $aParams);
break;
case PropertyType::WEB_PAGE_PERSONAL:
case PropertyType::WEB_PAGE_BUSSINES:
case PropertyType::WEB_PAGE_OTHER:
$aParams = array('TYPE' => array());
$aParams['TYPE'][] = PropertyType::WEB_PAGE_BUSSINES === $oProperty->Type ? 'WORK' : 'HOME';
$oVCard->add('URL', $oProperty->Value, $aParams);
break;
case PropertyType::PHONE_PERSONAL:
case PropertyType::PHONE_BUSSINES:
case PropertyType::PHONE_OTHER:
case PropertyType::MOBILE_PERSONAL:
case PropertyType::MOBILE_BUSSINES:
case PropertyType::MOBILE_OTHER:
case PropertyType::FAX_PERSONAL:
case PropertyType::FAX_BUSSINES:
case PropertyType::FAX_OTHER:
$aParams = array('TYPE' => array());
$sType = '';
if (\in_array($oProperty->Type, array(PropertyType::PHONE_PERSONAL, PropertyType::PHONE_BUSSINES, PropertyType::PHONE_OTHER)))
{
$sType = 'VOICE';
}
else if (\in_array($oProperty->Type, array(PropertyType::MOBILE_PERSONAL, PropertyType::MOBILE_BUSSINES, PropertyType::MOBILE_OTHER)))
{
$sType = 'CELL';
}
else if (\in_array($oProperty->Type, array(PropertyType::FAX_PERSONAL, PropertyType::FAX_BUSSINES, PropertyType::FAX_OTHER)))
{
$sType = 'FAX';
}
if (!empty($sType))
{
$aParams['TYPE'][] = $sType;
}
$aParams['TYPE'][] = \in_array($oProperty->Type, array(
PropertyType::PHONE_BUSSINES, PropertyType::MOBILE_BUSSINES, PropertyType::FAX_BUSSINES)) ? 'WORK' : 'HOME';
if (!$bPrefPhone)
{
$bPrefPhone = true;
$aParams['TYPE'][] = 'pref';
}
$oVCard->add('TEL', $oProperty->Value, $aParams);
break;
}
}
}
$oVCard->UID = $this->IdContactStr;
$oVCard->N = array($sLastName, $sFirstName, $sMiddleName, $sPrefix, $sSuffix);
$oVCard->REV = \gmdate('Ymd', $this->Changed).'T'.\gmdate('His', $this->Changed).'Z';
return $oVCard;
}
/**
* @return string
*/
public function VCardUri()
{
return $this->IdContactStr.'.vcf';
}
}

View file

@ -0,0 +1,107 @@
<?php
namespace RainLoop\Providers\AddressBook\Classes;
use RainLoop\Providers\AddressBook\Enumerations\PropertyType;
class Property
{
/**
* @var int
*/
public $IdProperty;
/**
* @var int
*/
public $Type;
/**
* @var string
*/
public $TypeCustom;
/**
* @var string
*/
public $Value;
/**
* @var string
*/
public $ValueCustom;
/**
* @var int
*/
public $Frec;
public function __construct(
$iType = \RainLoop\Providers\AddressBook\Enumerations\PropertyType::UNKNOWN, $sValue = '')
{
$this->Clear();
$this->Type = $iType;
$this->Value = $sValue;
}
public function Clear()
{
$this->IdProperty = 0;
$this->Type = PropertyType::UNKNOWN;
$this->TypeCustom = '';
$this->Value = '';
$this->ValueCustom = '';
$this->Frec = 0;
}
/**
* @return bool
*/
public function IsEmail()
{
return \in_array($this->Type, array(
PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES, PropertyType::EMAIl_OTHER
));
}
/**
* @return bool
*/
public function IsPhone()
{
return \in_array($this->Type, array(
PropertyType::PHONE_PERSONAL, PropertyType::PHONE_BUSSINES, PropertyType::PHONE_OTHER,
PropertyType::MOBILE_PERSONAL, PropertyType::MOBILE_BUSSINES, PropertyType::MOBILE_OTHER,
PropertyType::FAX_PERSONAL, PropertyType::FAX_BUSSINES, PropertyType::FAX_OTHER
));
}
public function UpdateDependentValues()
{
$this->Value = \trim($this->Value);
$this->ValueCustom = \trim($this->ValueCustom);
$this->TypeCustom = \trim($this->TypeCustom);
if (0 < \strlen($this->Value))
{
// lower
if ($this->IsEmail())
{
$this->Value = \strtolower($this->Value);
}
// phones clear value for searching
if ($this->IsPhone())
{
$sPhone = $this->Value;
$sPhone = \preg_replace('/^[+]+/', '', $sPhone);
$sPhone = \preg_replace('/[^\d]/', '', $sPhone);
$this->ValueCustom = $sPhone;
}
}
}
}

View file

@ -0,0 +1,46 @@
<?php
namespace RainLoop\Providers\AddressBook\Enumerations;
class PropertyType
{
const UNKNOWN = 0;
const FULLNAME = 10;
const FIRST_NAME = 15;
const LAST_NAME = 16;
const MIDDLE_NAME = 17;
const NICK_NAME = 18;
const NAME_PREFIX = 20;
const NAME_SUFFIX = 21;
const EMAIl_PERSONAL = 30;
const EMAIl_BUSSINES = 31;
const EMAIl_OTHER = 32;
const PHONE_PERSONAL = 50;
const PHONE_BUSSINES = 51;
const PHONE_OTHER = 52;
const MOBILE_PERSONAL = 60;
const MOBILE_BUSSINES = 61;
const MOBILE_OTHER = 62;
const FAX_PERSONAL = 70;
const FAX_BUSSINES = 71;
const FAX_OTHER = 72;
const FACEBOOK = 90;
const SKYPE = 91;
const GITHUB = 92;
const NOTE = 110;
const WEB_PAGE_PERSONAL = 220;
const WEB_PAGE_BUSSINES = 221;
const WEB_PAGE_OTHER = 222;
const CUSTOM = 250;
}

View file

@ -0,0 +1,9 @@
<?php
namespace RainLoop\Providers\AddressBook\Enumerations;
class ScopeType
{
const DEFAULT_ = 0;
const SHARE_ALL = 2;
}

File diff suppressed because it is too large Load diff