mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-04 06:57:03 +03:00
Contacts tags support (unstable - step 1).
+ Small fixes
This commit is contained in:
parent
74fa12c000
commit
0ca00dec40
34 changed files with 1790 additions and 801 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -23,7 +23,7 @@ abstract class PdoAbstract
|
|||
* @var string
|
||||
*/
|
||||
protected $sDbType;
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
|
|
@ -67,7 +67,7 @@ abstract class PdoAbstract
|
|||
{
|
||||
return $this->oPDO;
|
||||
}
|
||||
|
||||
|
||||
if (!\class_exists('PDO'))
|
||||
{
|
||||
throw new \Exception('Class PDO does not exist');
|
||||
|
|
@ -100,7 +100,7 @@ abstract class PdoAbstract
|
|||
{
|
||||
throw $oException;
|
||||
}
|
||||
|
||||
|
||||
if ($oPdo)
|
||||
{
|
||||
$this->oPDO = $oPdo;
|
||||
|
|
@ -127,7 +127,7 @@ abstract class PdoAbstract
|
|||
{
|
||||
$mName = \strtolower($sTabelName.'_'.$sColumnName.'_seq');
|
||||
}
|
||||
|
||||
|
||||
return null === $mName ? $this->getPDO()->lastInsertId() : $this->getPDO()->lastInsertId($mName);
|
||||
}
|
||||
|
||||
|
|
@ -222,15 +222,15 @@ abstract class PdoAbstract
|
|||
$mResult->closeCursor();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $sSql
|
||||
* @param mixed $mData
|
||||
*/
|
||||
protected function writeLog($sSql)
|
||||
protected function writeLog($mData)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->WriteMixed($sSql, \MailSo\Log\Enumerations\Type::INFO, 'SQL');
|
||||
$this->oLogger->WriteMixed($mData, \MailSo\Log\Enumerations\Type::INFO, 'SQL');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -324,7 +324,7 @@ abstract class PdoAbstract
|
|||
}
|
||||
|
||||
$this->writeLog($sQuery);
|
||||
|
||||
|
||||
$oStmt = $oPdo->prepare($sQuery);
|
||||
if ($oStmt->execute(array($sName)))
|
||||
{
|
||||
|
|
@ -355,7 +355,7 @@ abstract class PdoAbstract
|
|||
/**
|
||||
* @param string $sName
|
||||
* @param int $iVersion
|
||||
*
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function setVersion($sName, $iVersion)
|
||||
|
|
@ -371,7 +371,7 @@ abstract class PdoAbstract
|
|||
|
||||
$sQuery = 'DELETE FROM rainloop_system WHERE sys_name = ? AND value_int <= ?;';
|
||||
$this->writeLog($sQuery);
|
||||
|
||||
|
||||
$oStmt = $oPdo->prepare($sQuery);
|
||||
$bResult = !!$oStmt->execute(array($sName.'_version', $iVersion));
|
||||
if ($bResult)
|
||||
|
|
@ -507,7 +507,7 @@ rl_email text NOT NULL DEFAULT \'\'
|
|||
{
|
||||
$oPdo->rollBack();
|
||||
}
|
||||
|
||||
|
||||
throw $oException;
|
||||
}
|
||||
}
|
||||
|
|
@ -550,7 +550,7 @@ rl_email text NOT NULL DEFAULT \'\'
|
|||
{
|
||||
$oPdo = false;
|
||||
$bResult = false;
|
||||
|
||||
|
||||
foreach ($aData as $iVersion => $aQuery)
|
||||
{
|
||||
if (0 === \count($aQuery))
|
||||
|
|
@ -580,7 +580,7 @@ rl_email text NOT NULL DEFAULT \'\'
|
|||
if (false === $bExec)
|
||||
{
|
||||
$this->writeLog('Result: false');
|
||||
|
||||
|
||||
$bResult = false;
|
||||
break;
|
||||
}
|
||||
|
|
@ -605,7 +605,7 @@ rl_email text NOT NULL DEFAULT \'\'
|
|||
{
|
||||
$oPdo->rollBack();
|
||||
}
|
||||
|
||||
|
||||
throw $oException;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ class AddressBook extends \RainLoop\Providers\AbstractProvider
|
|||
{
|
||||
return $this->IsActive() ? $this->oDriver->Export($sEmail, $sType) : false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param \RainLoop\Providers\AddressBook\Classes\Contact $oContact
|
||||
|
|
@ -123,6 +123,16 @@ class AddressBook extends \RainLoop\Providers\AbstractProvider
|
|||
$iOffset, $iLimit, $sSearch, $iResultCount) : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetContactTags($sEmail)
|
||||
{
|
||||
return $this->IsActive() ? $this->oDriver->GetContactTags($sEmail) : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param string $mID
|
||||
|
|
@ -238,7 +248,7 @@ class AddressBook extends \RainLoop\Providers\AbstractProvider
|
|||
|
||||
$aMap = \array_change_key_case($aMap, CASE_LOWER);
|
||||
}
|
||||
|
||||
|
||||
$sCsvNameLower = \MailSo\Base\Utils::IsAscii($sCsvName) ? \preg_replace('/[\s\-]+/', '', \strtolower($sCsvName)) : '';
|
||||
return !empty($sCsvNameLower) && isset($aMap[$sCsvNameLower]) ? $aMap[$sCsvNameLower] : PropertyType::UNKNOWN;
|
||||
}
|
||||
|
|
@ -258,7 +268,7 @@ class AddressBook extends \RainLoop\Providers\AbstractProvider
|
|||
foreach ($aCsvData as $aItem)
|
||||
{
|
||||
\MailSo\Base\Utils::ResetTimeLimit();
|
||||
|
||||
|
||||
foreach ($aItem as $sItemName => $sItemValue)
|
||||
{
|
||||
$sItemName = \trim($sItemName);
|
||||
|
|
@ -294,10 +304,10 @@ class AddressBook extends \RainLoop\Providers\AbstractProvider
|
|||
|
||||
unset($oContact);
|
||||
}
|
||||
|
||||
|
||||
return $iCount;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param string $sVcfData
|
||||
|
|
@ -336,14 +346,14 @@ class AddressBook extends \RainLoop\Providers\AbstractProvider
|
|||
if ($oVCard instanceof \Sabre\VObject\Component\VCard)
|
||||
{
|
||||
\MailSo\Base\Utils::ResetTimeLimit();
|
||||
|
||||
|
||||
if (empty($oVCard->UID))
|
||||
{
|
||||
$oVCard->UID = \Sabre\DAV\UUIDUtil::getUUID();
|
||||
}
|
||||
|
||||
$oContact->PopulateByVCard($oVCard->serialize());
|
||||
|
||||
|
||||
if (0 < \count($oContact->Properties))
|
||||
{
|
||||
if ($this->ContactSave($sEmail, $oContact))
|
||||
|
|
|
|||
|
|
@ -37,6 +37,11 @@ class Contact
|
|||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $Tags;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $ReadOnly;
|
||||
|
||||
/**
|
||||
|
|
@ -58,15 +63,15 @@ class Contact
|
|||
{
|
||||
$this->IdContact = '';
|
||||
$this->IdContactStr = '';
|
||||
$this->IdUser = 0;
|
||||
$this->Display = '';
|
||||
$this->Changed = \time();
|
||||
$this->Properties = array();
|
||||
$this->Tags = array();
|
||||
$this->ReadOnly = false;
|
||||
$this->IdPropertyFromSearch = 0;
|
||||
$this->Etag = '';
|
||||
}
|
||||
|
||||
|
||||
public function UpdateDependentValues()
|
||||
{
|
||||
$sLastName = '';
|
||||
|
|
@ -75,7 +80,7 @@ class Contact
|
|||
$sOther = '';
|
||||
|
||||
$oFullNameProperty = null;
|
||||
|
||||
|
||||
foreach ($this->Properties as /* @var $oProperty \RainLoop\Providers\AddressBook\Classes\Property */ &$oProperty)
|
||||
{
|
||||
if ($oProperty)
|
||||
|
|
@ -133,7 +138,7 @@ class Contact
|
|||
}
|
||||
|
||||
$this->Display = \trim($sDisplay);
|
||||
|
||||
|
||||
if ($oFullNameProperty)
|
||||
{
|
||||
$oFullNameProperty->Value = $this->Display;
|
||||
|
|
@ -200,7 +205,7 @@ class Contact
|
|||
{
|
||||
$oVCard = new \Sabre\VObject\Component\VCard();
|
||||
}
|
||||
|
||||
|
||||
$oVCard->VERSION = '3.0';
|
||||
$oVCard->PRODID = '-//RainLoop//'.APP_VERSION.'//EN';
|
||||
|
||||
|
|
@ -482,7 +487,7 @@ class Contact
|
|||
public function PopulateByVCard($sVCard, $sEtag = '')
|
||||
{
|
||||
$this->Properties = array();
|
||||
|
||||
|
||||
if (!empty($sEtag))
|
||||
{
|
||||
$this->Etag = $sEtag;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers\AddressBook\Classes;
|
||||
|
||||
class Tag
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $IdContactTag;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $Name;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $ReadOnly;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->Clear();
|
||||
}
|
||||
|
||||
public function Clear()
|
||||
{
|
||||
$this->IdContactTag = '';
|
||||
$this->Name = '';
|
||||
$this->ReadOnly = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@ class PdoAddressBook
|
|||
* @var string
|
||||
*/
|
||||
private $sDsnType;
|
||||
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
|
|
@ -73,7 +73,7 @@ class PdoAddressBook
|
|||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
private function prepearDatabaseSyncData($iUserID)
|
||||
{
|
||||
$aResult = array();
|
||||
|
|
@ -122,7 +122,7 @@ class PdoAddressBook
|
|||
{
|
||||
$this->oLogger->WriteException($oException);
|
||||
}
|
||||
|
||||
|
||||
if (\is_array($aResponse))
|
||||
{
|
||||
$mResult = array();
|
||||
|
|
@ -159,7 +159,7 @@ class PdoAddressBook
|
|||
private function davClientRequest($oClient, $sCmd, $sUrl, $mData = null)
|
||||
{
|
||||
\MailSo\Base\Utils::ResetTimeLimit();
|
||||
|
||||
|
||||
$this->oLogger->Write($sCmd.' '.$sUrl.('PUT' === $sCmd && null !== $mData ? ' ('.\strlen($mData).')' : ''),
|
||||
\MailSo\Log\Enumerations\Type::INFO, 'DAV');
|
||||
|
||||
|
|
@ -183,7 +183,7 @@ class PdoAddressBook
|
|||
{
|
||||
$this->oLogger->WriteException($oException);
|
||||
}
|
||||
|
||||
|
||||
return $oResponse;
|
||||
}
|
||||
|
||||
|
|
@ -199,13 +199,13 @@ class PdoAddressBook
|
|||
public function Sync($sEmail, $sUrl, $sUser, $sPassword, $sProxy = '')
|
||||
{
|
||||
$this->SyncDatabase();
|
||||
|
||||
|
||||
$iUserID = $this->getUserId($sEmail);
|
||||
if (0 >= $iUserID)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$aUrl = \parse_url($sUrl);
|
||||
if (!\is_array($aUrl))
|
||||
{
|
||||
|
|
@ -233,6 +233,9 @@ class PdoAddressBook
|
|||
$oClient = new \Sabre\DAV\Client($aSettings);
|
||||
$oClient->setVerifyPeer(false);
|
||||
|
||||
$this->oLogger->AddSecret($sPassword);
|
||||
$this->oLogger->Write('User: '.$aSettings['userName'].', Url: '.$sUrl, \MailSo\Log\Enumerations\Type::INFO, 'DAV');
|
||||
|
||||
$aRemoteSyncData = $this->prepearRemoteSyncData($oClient, $sPath);
|
||||
if (false === $aRemoteSyncData)
|
||||
{
|
||||
|
|
@ -276,7 +279,7 @@ class PdoAddressBook
|
|||
//+++new or newer (from db)
|
||||
foreach ($aDatabaseSyncData as $sKey => $aData)
|
||||
{
|
||||
if (!$aData['deleted'] &&
|
||||
if (!$aData['deleted'] &&
|
||||
(empty($aData['etag']) && !isset($aRemoteSyncData[$sKey])) // new
|
||||
||
|
||||
(!empty($aData['etag']) && isset($aRemoteSyncData[$sKey]) && // newer
|
||||
|
|
@ -302,7 +305,7 @@ class PdoAddressBook
|
|||
|
||||
$oResponse = $this->davClientRequest($oClient, 'PUT',
|
||||
$sPath.$oContact->CardDavNameUri(), $oContact->ToVCard($sExsistensBody));
|
||||
|
||||
|
||||
if ($oResponse && isset($oResponse['headers'], $oResponse['headers']['etag']))
|
||||
{
|
||||
$sEtag = \trim(\trim($oResponse['headers']['etag']), '"\'');
|
||||
|
|
@ -314,7 +317,7 @@ class PdoAddressBook
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unset($oContact);
|
||||
}
|
||||
}
|
||||
|
|
@ -348,7 +351,7 @@ class PdoAddressBook
|
|||
{
|
||||
$oContact = new \RainLoop\Providers\AddressBook\Classes\Contact();
|
||||
}
|
||||
|
||||
|
||||
$oContact->PopulateByVCard($sBody,
|
||||
!empty($oResponse['headers']['etag']) ? \trim(\trim($oResponse['headers']['etag']), '"\'') : '');
|
||||
|
||||
|
|
@ -421,16 +424,16 @@ class PdoAddressBook
|
|||
{
|
||||
$this->SyncDatabase();
|
||||
}
|
||||
|
||||
|
||||
$iUserID = $this->getUserId($sEmail);
|
||||
|
||||
|
||||
$iIdContact = 0 < \strlen($oContact->IdContact) && \is_numeric($oContact->IdContact) ? (int) $oContact->IdContact : 0;
|
||||
|
||||
$bUpdate = 0 < $iIdContact;
|
||||
|
||||
$oContact->UpdateDependentValues();
|
||||
$oContact->Changed = \time();
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
if ($this->isTransactionSupported())
|
||||
|
|
@ -465,6 +468,14 @@ class PdoAddressBook
|
|||
':id_contact' => array($iIdContact, \PDO::PARAM_INT)
|
||||
)
|
||||
);
|
||||
|
||||
// clear previos tags
|
||||
$this->prepareAndExecute(
|
||||
'DELETE FROM rainloop_ab_tags_contacts WHERE id_contact = :id_contact',
|
||||
array(
|
||||
':id_contact' => array($iIdContact, \PDO::PARAM_INT)
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -517,6 +528,44 @@ class PdoAddressBook
|
|||
'(:id_contact, :id_user, :prop_type, :prop_type_str, :prop_value, :prop_value_custom, :prop_frec)';
|
||||
|
||||
$this->prepareAndExecute($sSql, $aParams, true);
|
||||
|
||||
$aTags = array();
|
||||
$aContactTags = $this->GetContactTags($sEmail);
|
||||
|
||||
$fFindFunc = function ($sName) use ($aContactTags) {
|
||||
|
||||
$iResult = 0;
|
||||
foreach ($aContactTags as $oItem)
|
||||
{
|
||||
if ($oItem && $oItem->Name === $sName)
|
||||
{
|
||||
$iResult = (int) $oItem->IdContactTag;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $iResult;
|
||||
};
|
||||
|
||||
foreach ($oContact->Tags as $sTagName)
|
||||
{
|
||||
$iTagID = $fFindFunc($sTagName);
|
||||
if (0 >= $iTagID)
|
||||
{
|
||||
$iTagID = $this->CreateTag($sEmail, $sTagName, false);
|
||||
}
|
||||
|
||||
if (\is_int($iTagID) && 0 < $iTagID)
|
||||
{
|
||||
$aTags[] = array(
|
||||
':id_tag' => array($iTagID, \PDO::PARAM_INT),
|
||||
':id_contact' => array($iIdContact, \PDO::PARAM_INT)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$sSql = 'INSERT INTO rainloop_ab_tags_contacts (id_tag, id_contact) VALUES (:id_tag, :id_contact)';
|
||||
$this->prepareAndExecute($sSql, $aTags, true);
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
|
|
@ -537,6 +586,64 @@ class PdoAddressBook
|
|||
return 0 < $iIdContact;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param string $sName
|
||||
* @param bool $bSyncDb = true
|
||||
*
|
||||
* @return bool|int
|
||||
*/
|
||||
public function CreateTag($sEmail, $sName, $bSyncDb = true)
|
||||
{
|
||||
if ($bSyncDb)
|
||||
{
|
||||
$this->SyncDatabase();
|
||||
}
|
||||
|
||||
$iUserID = $this->getUserId($sEmail);
|
||||
|
||||
$mResult = false;
|
||||
try
|
||||
{
|
||||
if ($this->isTransactionSupported())
|
||||
{
|
||||
$this->beginTransaction();
|
||||
}
|
||||
|
||||
$sSql = 'INSERT INTO rainloop_ab_tags '.
|
||||
'(id_user, tag_name) VALUES (:id_user, :tag_name)';
|
||||
|
||||
$this->prepareAndExecute($sSql,
|
||||
array(
|
||||
':id_user' => array($iUserID, \PDO::PARAM_INT),
|
||||
':tag_name' => array($sName, \PDO::PARAM_STR)
|
||||
)
|
||||
);
|
||||
|
||||
$sLast = $this->lastInsertId('rainloop_ab_contacts', 'id_contact');
|
||||
if (\is_numeric($sLast) && 0 < (int) $sLast)
|
||||
{
|
||||
$mResult = (int) $sLast;
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
if ($this->isTransactionSupported())
|
||||
{
|
||||
$this->rollBack();
|
||||
}
|
||||
|
||||
throw $oException;
|
||||
}
|
||||
|
||||
if ($this->isTransactionSupported())
|
||||
{
|
||||
$this->commit();
|
||||
}
|
||||
|
||||
return $mResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
* @param array $aContactIds
|
||||
|
|
@ -615,7 +722,7 @@ class PdoAddressBook
|
|||
* @param int $iLimit = 20
|
||||
* @param string $sSearch = ''
|
||||
* @param int $iResultCount = 0
|
||||
*
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetContacts($sEmail, $iOffset = 0, $iLimit = 20, $sSearch = '', &$iResultCount = 0)
|
||||
|
|
@ -631,7 +738,7 @@ class PdoAddressBook
|
|||
$iCount = 0;
|
||||
$aSearchIds = array();
|
||||
$aPropertyFromSearchIds = array();
|
||||
|
||||
|
||||
if (0 < \strlen($sSearch))
|
||||
{
|
||||
$sCustomSearch = $this->specialConvertSearchValueCustomPhone($sSearch);
|
||||
|
|
@ -645,7 +752,7 @@ class PdoAddressBook
|
|||
PropertyType::EMAIl, PropertyType::FIRST_NAME, PropertyType::LAST_NAME, PropertyType::NICK_NAME,
|
||||
PropertyType::PHONE, PropertyType::WEB_PAGE
|
||||
));
|
||||
|
||||
|
||||
$sSql = 'SELECT id_user, id_prop, id_contact FROM rainloop_ab_properties '.
|
||||
'WHERE (id_user = :id_user) AND prop_type IN ('.$sSearchTypes.') AND (prop_value LIKE :search ESCAPE \'=\''.
|
||||
(0 < \strlen($sCustomSearch) ? ' OR (prop_type = '.PropertyType::PHONE.' AND prop_value_custom <> \'\' AND prop_value_custom LIKE :search_custom_phone)' : '').
|
||||
|
|
@ -686,7 +793,7 @@ class PdoAddressBook
|
|||
{
|
||||
$sSql = 'SELECT COUNT(DISTINCT id_contact) as contact_count FROM rainloop_ab_properties '.
|
||||
'WHERE id_user = :id_user';
|
||||
|
||||
|
||||
$aParams = array(
|
||||
':id_user' => array($iUserID, \PDO::PARAM_INT)
|
||||
);
|
||||
|
|
@ -704,10 +811,11 @@ class PdoAddressBook
|
|||
|
||||
$iResultCount = $iCount;
|
||||
|
||||
$aResult = array();
|
||||
if (0 < $iCount)
|
||||
{
|
||||
$sSql = 'SELECT * FROM rainloop_ab_contacts WHERE deleted = 0 AND id_user = :id_user';
|
||||
|
||||
|
||||
$aParams = array(
|
||||
':id_user' => array($iUserID, \PDO::PARAM_INT)
|
||||
);
|
||||
|
|
@ -794,13 +902,136 @@ class PdoAddressBook
|
|||
$oItem->UpdateDependentValues();
|
||||
}
|
||||
|
||||
return \array_values($aContacts);
|
||||
$aResult = \array_values($aContacts);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array();
|
||||
if (\is_array($aResult) && 0 < \count($aResult))
|
||||
{
|
||||
$aIdContacts = array();
|
||||
$aIdTagsContacts = array();
|
||||
$aTags = $this->GetContactTags($sEmail);
|
||||
|
||||
if (\is_array($aTags) && 0 < \count($aTags))
|
||||
{
|
||||
foreach ($aResult as $oItem)
|
||||
{
|
||||
$aIdContacts[$oItem->IdContact] = true;
|
||||
}
|
||||
|
||||
if (0 < \count($aIdContacts))
|
||||
{
|
||||
$sSql = 'SELECT id_tag, id_contact FROM rainloop_ab_tags_contacts WHERE id_contact IN ('.\implode(',', \array_keys($aIdContacts)).')';
|
||||
$oStmt = $this->prepareAndExecute($sSql);
|
||||
|
||||
if ($oStmt)
|
||||
{
|
||||
$aFetch = $oStmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
if (\is_array($aFetch) && 0 < \count($aFetch))
|
||||
{
|
||||
foreach ($aFetch as $aItem)
|
||||
{
|
||||
if ($aItem && isset($aItem['id_tag'], $aItem['id_contact']))
|
||||
{
|
||||
$sID = (string) $aItem['id_contact'];
|
||||
if (!isset($aIdTagsContacts[$sID]))
|
||||
{
|
||||
$aIdTagsContacts[$sID] = array();
|
||||
}
|
||||
|
||||
$aIdTagsContacts[$sID][] = (string) $aItem['id_tag'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unset($aFetch);
|
||||
}
|
||||
|
||||
if (0 < \count($aIdTagsContacts))
|
||||
{
|
||||
$fFindFunc = function ($sID) use ($aTags) {
|
||||
|
||||
foreach ($aTags as $oItem)
|
||||
{
|
||||
if ($oItem && (string) $oItem->IdContactTag === $sID)
|
||||
{
|
||||
return\trim($oItem->Name);
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
};
|
||||
|
||||
foreach ($aResult as &$oItem)
|
||||
{
|
||||
$sID = $oItem ? (string) $oItem->IdContact : '';
|
||||
if (0 < \strlen($sID) && isset($aIdTagsContacts[$sID]) && \is_array($aIdTagsContacts[$sID]))
|
||||
{
|
||||
$aNames = array();
|
||||
foreach ($aIdTagsContacts[$sID] as $sSubID)
|
||||
{
|
||||
$sName = $fFindFunc($sSubID);
|
||||
if (0 < \strlen($sName))
|
||||
{
|
||||
$aNames[] = $sName;
|
||||
}
|
||||
}
|
||||
|
||||
$oItem->Tags = $aNames;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEmail
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetContactTags($sEmail)
|
||||
{
|
||||
$this->SyncDatabase();
|
||||
|
||||
$iUserID = $this->getUserId($sEmail);
|
||||
|
||||
$sSql = 'SELECT id_tag, id_user, tag_name FROM rainloop_ab_tags WHERE id_user = :id_user ORDER BY tag_name ASC';
|
||||
|
||||
$aParams = array(
|
||||
':id_user' => array($iUserID, \PDO::PARAM_INT)
|
||||
);
|
||||
|
||||
$aResult = array();
|
||||
$oStmt = $this->prepareAndExecute($sSql, $aParams);
|
||||
if ($oStmt)
|
||||
{
|
||||
$aFetch = $oStmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
if (\is_array($aFetch) && 0 < \count($aFetch))
|
||||
{
|
||||
foreach ($aFetch as $aItem)
|
||||
{
|
||||
$iIdContactTag = $aItem && isset($aItem['id_tag']) ? (int) $aItem['id_tag'] : 0;
|
||||
if (0 < $iIdContactTag)
|
||||
{
|
||||
$oContactTag = new \RainLoop\Providers\AddressBook\Classes\Tag();
|
||||
|
||||
$oContactTag->IdContactTag = (string) $iIdContactTag;
|
||||
$oContactTag->Name = isset($aItem['tag_name']) ? (string) $aItem['tag_name'] : '';
|
||||
$oContactTag->ReadOnly = $iUserID !== (isset($aItem['id_user']) ? (int) $aItem['id_user'] : 0);
|
||||
|
||||
$aResult[] = $oContactTag;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -924,7 +1155,7 @@ class PdoAddressBook
|
|||
}
|
||||
|
||||
$this->SyncDatabase();
|
||||
|
||||
|
||||
$iUserID = $this->getUserId($sEmail);
|
||||
|
||||
$sTypes = implode(',', array(
|
||||
|
|
@ -933,7 +1164,7 @@ class PdoAddressBook
|
|||
|
||||
$sSql = 'SELECT id_contact, id_prop, prop_type, prop_value FROM rainloop_ab_properties '.
|
||||
'WHERE (id_user = :id_user) AND prop_type IN ('.$sTypes.') AND prop_value LIKE :search ESCAPE \'=\'';
|
||||
|
||||
|
||||
$aParams = array(
|
||||
':id_user' => array($iUserID, \PDO::PARAM_INT),
|
||||
':limit' => array($iLimit, \PDO::PARAM_INT),
|
||||
|
|
@ -944,7 +1175,7 @@ class PdoAddressBook
|
|||
$sSql .= ' LIMIT :limit';
|
||||
|
||||
$aResult = array();
|
||||
|
||||
|
||||
$oStmt = $this->prepareAndExecute($sSql, $aParams);
|
||||
if ($oStmt)
|
||||
{
|
||||
|
|
@ -960,7 +1191,7 @@ class PdoAddressBook
|
|||
$iIdContact = $aItem && isset($aItem['id_contact']) ? (int) $aItem['id_contact'] : 0;
|
||||
$iIdProp = $aItem && isset($aItem['id_prop']) ? (int) $aItem['id_prop'] : 0;
|
||||
$iType = $aItem && isset($aItem['prop_type']) ? (int) $aItem['prop_type'] : 0;
|
||||
|
||||
|
||||
if (0 < $iIdContact && 0 < $iIdProp)
|
||||
{
|
||||
$aIdContacts[$iIdContact] = $iIdContact;
|
||||
|
|
@ -985,7 +1216,7 @@ class PdoAddressBook
|
|||
if (0 < count($aIdContacts))
|
||||
{
|
||||
$oStmt->closeCursor();
|
||||
|
||||
|
||||
$sTypes = \implode(',', array(
|
||||
PropertyType::EMAIl, PropertyType::FIRST_NAME, PropertyType::LAST_NAME, PropertyType::NICK_NAME
|
||||
));
|
||||
|
|
@ -1042,10 +1273,10 @@ class PdoAddressBook
|
|||
{
|
||||
$bName = \in_array(PropertyType::FIRST_NAME, $aContactAllAccess[$iId]) || \in_array(PropertyType::LAST_NAME, $aContactAllAccess[$iId]);
|
||||
$bNick = \in_array(PropertyType::NICK_NAME, $aContactAllAccess[$iId]);
|
||||
|
||||
|
||||
$aNameItem = isset($aNames[$iId]) && \is_array($aNames[$iId]) ? $aNames[$iId] : array('', '');
|
||||
$sNameItem = \trim($aNameItem[0].' '.$aNameItem[1]);
|
||||
|
||||
|
||||
$sNickItem = isset($aNicks[$iId]) ? $aNicks[$iId] : '';
|
||||
|
||||
foreach ($aItems as $sEmail)
|
||||
|
|
@ -1054,7 +1285,7 @@ class PdoAddressBook
|
|||
{
|
||||
$aResult[] = array($sEmail, $sNameItem);
|
||||
}
|
||||
|
||||
|
||||
if ($bNick)
|
||||
{
|
||||
$aResult[] = array($sEmail, $sNickItem);
|
||||
|
|
@ -1089,7 +1320,7 @@ class PdoAddressBook
|
|||
{
|
||||
$aResult = \array_slice($aResult, 0, $iLimit);
|
||||
}
|
||||
|
||||
|
||||
return $aResult;
|
||||
}
|
||||
}
|
||||
|
|
@ -1121,7 +1352,7 @@ class PdoAddressBook
|
|||
$aEmailsObjects = \array_filter($aEmailsObjects, function ($oItem) {
|
||||
return !!$oItem;
|
||||
});
|
||||
|
||||
|
||||
if (0 === \count($aEmailsObjects))
|
||||
{
|
||||
throw new \InvalidArgumentException('Empty Emails argument');
|
||||
|
|
@ -1156,7 +1387,7 @@ class PdoAddressBook
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$aEmailsToCreate = \array_filter($aEmailsObjects, function ($oItem) use ($aExists, &$aEmailsToUpdate) {
|
||||
if ($oItem)
|
||||
{
|
||||
|
|
@ -1185,7 +1416,7 @@ class PdoAddressBook
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unset($aEmails, $aEmailsObjects);
|
||||
|
||||
if (0 < \count($aEmailsToCreate))
|
||||
|
|
@ -1225,7 +1456,7 @@ class PdoAddressBook
|
|||
|
||||
$oContact->Properties[] = $oPropName;
|
||||
}
|
||||
|
||||
|
||||
if (0 < \strlen($sLast))
|
||||
{
|
||||
$oPropName = new \RainLoop\Providers\AddressBook\Classes\Property();
|
||||
|
|
@ -1240,17 +1471,17 @@ class PdoAddressBook
|
|||
{
|
||||
$this->ContactSave($sEmail, $oContact);
|
||||
}
|
||||
|
||||
|
||||
$oContact->Clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$sSql = 'UPDATE rainloop_ab_properties SET prop_frec = prop_frec + 1 WHERE id_user = :id_user AND prop_type = :prop_type';
|
||||
|
||||
$aEmailsQuoted = \array_map(function ($mItem) use ($self) {
|
||||
return $self->quoteValue($mItem);
|
||||
}, $aEmailsToUpdate);
|
||||
|
||||
|
||||
if (1 === \count($aEmailsQuoted))
|
||||
{
|
||||
$sSql .= ' AND prop_value = '.$aEmailsQuoted[0];
|
||||
|
|
@ -1259,7 +1490,7 @@ class PdoAddressBook
|
|||
{
|
||||
$sSql .= ' AND prop_value IN ('.\implode(',', $aEmailsQuoted).')';
|
||||
}
|
||||
|
||||
|
||||
return !!$this->prepareAndExecute($sSql, array(
|
||||
':id_user' => array($iUserID, \PDO::PARAM_INT),
|
||||
':prop_type' => array(PropertyType::EMAIl, \PDO::PARAM_INT)
|
||||
|
|
@ -1506,7 +1737,7 @@ SQLITEINITIAL;
|
|||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
return $mCache;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue