Completion and preparation contacts to release.

This commit is contained in:
RainLoop Team 2013-12-10 04:40:21 +04:00
parent 45d34e64f4
commit eeda3dbb85
24 changed files with 505 additions and 236 deletions

View file

@ -17,10 +17,52 @@ function AdminContacts()
this.pdoDsnTrigger = ko.observable(Enums.SaveSettingsStep.Idle); this.pdoDsnTrigger = ko.observable(Enums.SaveSettingsStep.Idle);
this.pdoUserTrigger = ko.observable(Enums.SaveSettingsStep.Idle); this.pdoUserTrigger = ko.observable(Enums.SaveSettingsStep.Idle);
this.pdoPasswordTrigger = ko.observable(Enums.SaveSettingsStep.Idle); this.pdoPasswordTrigger = ko.observable(Enums.SaveSettingsStep.Idle);
this.testing = ko.observable(false);
this.testContactsSuccess = ko.observable(false);
this.testContactsError = ko.observable(false);
this.testContactsCommand = Utils.createCommand(this, function () {
this.testContactsSuccess(false);
this.testContactsError(false);
this.testing(true);
RL.remote().testContacts(this.onTestContactsResponse, {
'ContactsPdoDsn': this.pdoDsn(),
'ContactsPdoUser': this.pdoUser(),
'ContactsPdoPassword': this.pdoPassword()
});
}, function () {
return '' !== this.pdoDsn() && '' !== this.pdoUser();
});
this.onTestContactsResponse = _.bind(this.onTestContactsResponse, this);
} }
Utils.addSettingsViewModel(AdminContacts, 'AdminSettingsContacts', 'Contacts', 'contacts'); Utils.addSettingsViewModel(AdminContacts, 'AdminSettingsContacts', 'Contacts', 'contacts');
AdminContacts.prototype.onTestContactsResponse = function (sResult, oData)
{
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
{
this.testContactsSuccess(true);
}
else
{
this.testContactsError(true);
}
this.testing(false);
};
AdminContacts.prototype.onShow = function ()
{
this.testContactsSuccess(false);
this.testContactsError(false);
};
AdminContacts.prototype.onBuild = function () AdminContacts.prototype.onBuild = function ()
{ {
var self = this; var self = this;

View file

@ -24,8 +24,6 @@ function AdminSecurity()
this.adminPasswordUpdateSuccess(false); this.adminPasswordUpdateSuccess(false);
}, this); }, this);
this.onNewAdminPasswordResponse = _.bind(this.onNewAdminPasswordResponse, this);
this.saveNewAdminPasswordCommand = Utils.createCommand(this, function () { this.saveNewAdminPasswordCommand = Utils.createCommand(this, function () {
this.adminPasswordUpdateError(false); this.adminPasswordUpdateError(false);
@ -39,6 +37,8 @@ function AdminSecurity()
}, function () { }, function () {
return '' !== this.adminPassword() && '' !== this.adminPasswordNew(); return '' !== this.adminPassword() && '' !== this.adminPasswordNew();
}); });
this.onNewAdminPasswordResponse = _.bind(this.onNewAdminPasswordResponse, this);
} }
Utils.addSettingsViewModel(AdminSecurity, 'AdminSettingsSecurity', 'Security', 'security'); Utils.addSettingsViewModel(AdminSecurity, 'AdminSettingsSecurity', 'Security', 'security');

View file

@ -492,7 +492,7 @@ Utils.fixLongSubject = function (sSubject)
sSubject = sSubject.replace(/[\s]+/, ' '); sSubject = sSubject.replace(/[\s]+/, ' ');
return sSubject; return sSubject;
} };
/** /**
* @param {number} iNum * @param {number} iNum

View file

@ -218,6 +218,15 @@ AdminAjaxRemoteStorage.prototype.testConnectionForDomain = function (fCallback,
}); });
}; };
/**
* @param {?Function} fCallback
* @param {?} oData
*/
AdminAjaxRemoteStorage.prototype.testContacts = function (fCallback, oData)
{
this.defaultRequest(fCallback, 'AdminContactsTest', oData);
};
/** /**
* @param {?Function} fCallback * @param {?Function} fCallback
* @param {?} oData * @param {?} oData

View file

@ -36,7 +36,7 @@ html.rl-no-preview-pane {
.e-quota { .e-quota {
display: inline-block; display: inline-block;
margin-left: 10px; margin-top: 5px;
font-size: 18px; font-size: 18px;
cursor: help; cursor: help;
} }

View file

@ -32,6 +32,10 @@
} }
} }
span {
padding-right: 3px;
}
&.inputosaurus-required { &.inputosaurus-required {
padding-rigth: 5px; padding-rigth: 5px;
} }

View file

@ -222,7 +222,7 @@ class Logger extends \MailSo\Base\Collection
*/ */
public function WriteMixed($mData, $iDescType = null, $sName = '', $bSearchSecretWords = true) public function WriteMixed($mData, $iDescType = null, $sName = '', $bSearchSecretWords = true)
{ {
$iType = null === $iDescType ? \MailSo\Log\Enumerations\Type::INFO : $iType; $iType = null === $iDescType ? \MailSo\Log\Enumerations\Type::INFO : $iDescType;
if (\is_array($mData) || \is_object($mData)) if (\is_array($mData) || \is_object($mData))
{ {
if ($mData instanceof \Exception) if ($mData instanceof \Exception)

View file

@ -228,15 +228,13 @@ class Actions
break; break;
case 'personal-address-book': case 'personal-address-book':
// \RainLoop\Providers\PersonalAddressBook\PersonalAddressBookInterface // \RainLoop\Providers\PersonalAddressBook\PersonalAddressBookInterface
if ($this->Config()->Get('contacts', 'enable', false))
{ $sDsn = \trim($this->Config()->Get('contacts', 'pdo_dsn', ''));
$sDsn = \trim($this->Config()->Get('contacts', 'pdo_dsn', '')); $sUser = \trim($this->Config()->Get('contacts', 'pdo_user', ''));
$sUser = \trim($this->Config()->Get('contacts', 'pdo_user', '')); $sPassword = (string) $this->Config()->Get('contacts', 'pdo_password', '');
$sPassword = (string) $this->Config()->Get('contacts', 'pdo_password', '');
$oResult = new \RainLoop\Providers\PersonalAddressBook\MySqlPersonalAddressBook($sDsn, $sUser, $sPassword); $oResult = new \RainLoop\Providers\PersonalAddressBook\PdoPersonalAddressBook($sDsn, $sUser, $sPassword);
$oResult->SetLogger($this->Logger()); $oResult->SetLogger($this->Logger());
}
break; break;
case 'suggestions': case 'suggestions':
// \RainLoop\Providers\Suggestions\SuggestionsInterface // \RainLoop\Providers\Suggestions\SuggestionsInterface
@ -541,31 +539,19 @@ class Actions
} }
/** /**
* @param \RainLoop\Account $oAccount = null
* @param bool $bForceEnable = false
*
* @return \RainLoop\Providers\PersonalAddressBook * @return \RainLoop\Providers\PersonalAddressBook
*/ */
public function PersonalAddressBookProvider($oAccount = null) public function PersonalAddressBookProvider($oAccount = null, $bForceEnable = false)
{ {
if (null === $this->oPersonalAddressBookProvider) if (null === $this->oPersonalAddressBookProvider)
{ {
$this->oPersonalAddressBookProvider = new \RainLoop\Providers\PersonalAddressBook( $this->oPersonalAddressBookProvider = new \RainLoop\Providers\PersonalAddressBook(
$this->fabrica('personal-address-book', $oAccount)); $this->Config()->Get('contacts', 'enable', false) || $bForceEnable ? $this->fabrica('personal-address-book', $oAccount) : null);
$sPabVersion = $this->oPersonalAddressBookProvider->Version();
$sVersion = (string) $this->StorageProvider()->Get(null,
\RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, 'PersonalAddressBookVersion', '');
if ($sVersion !== $sPabVersion &&
$this->oPersonalAddressBookProvider->IsActive())
{
if ($this->oPersonalAddressBookProvider->SynchronizeStorage())
{
$this->StorageProvider()->Put(null, \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY,
'PersonalAddressBookVersion', $sPabVersion);
}
}
} }
else if ($oAccount && $this->oPersonalAddressBookProvider->IsSupported())
if ($oAccount)
{ {
$this->oPersonalAddressBookProvider->SetAccount($oAccount); $this->oPersonalAddressBookProvider->SetAccount($oAccount);
} }
@ -1035,7 +1021,7 @@ class Actions
$aResult['DesktopNotifications'] = false; $aResult['DesktopNotifications'] = false;
$aResult['UseThreads'] = false; $aResult['UseThreads'] = false;
$aResult['ReplySameFolder'] = false; $aResult['ReplySameFolder'] = false;
$aResult['UsePreviewPane'] = true; $aResult['UsePreviewPane'] = (bool) $oConfig->Get('webmail', 'use_preview_pane', true);
$aResult['UseCheckboxesInList'] = true; $aResult['UseCheckboxesInList'] = true;
$aResult['DisplayName'] = ''; $aResult['DisplayName'] = '';
$aResult['ReplyTo'] = ''; $aResult['ReplyTo'] = '';
@ -1941,6 +1927,22 @@ class Actions
return $this->DefaultResponse(__FUNCTION__, true); return $this->DefaultResponse(__FUNCTION__, true);
} }
/**
* @return array
*/
public function DoAdminContactsTest()
{
$this->IsAdminLoggined();
$oConfig = $this->Config();
$this->setConfigFromParams($oConfig, 'ContactsPdoDsn', 'contacts', 'pdo_dsn', 'string');
$this->setConfigFromParams($oConfig, 'ContactsPdoUser', 'contacts', 'pdo_user', 'string');
$this->setConfigFromParams($oConfig, 'ContactsPdoPassword', 'contacts', 'pdo_password', 'dummy');
return $this->DefaultResponse(__FUNCTION__, $this->PersonalAddressBookProvider()->Test());
}
/** /**
* @return array * @return array
*/ */
@ -4026,7 +4028,7 @@ class Actions
{ {
$iCount = 0; $iCount = 0;
$mResult = $this->PersonalAddressBookProvider($oAccount)->GetContacts($oAccount, $mResult = $this->PersonalAddressBookProvider($oAccount)->GetContacts($oAccount,
$iOffset, $iLimit, $sSearch, false, $iCount); $iOffset, $iLimit, $sSearch, \RainLoop\Providers\PersonalAddressBook\Enumerations\ScopeType::DEFAULT_, $iCount);
} }
return $this->DefaultResponse(__FUNCTION__, array( return $this->DefaultResponse(__FUNCTION__, array(

View file

@ -209,13 +209,14 @@ abstract class PdoAbstract
{ {
if ($this->oLogger) if ($this->oLogger)
{ {
$this->oLogger->Write($sSql, \MailSo\Log\Enumerations\Type::INFO, 'SQL'); $this->oLogger->WriteMixed($sSql, \MailSo\Log\Enumerations\Type::INFO, 'SQL');
} }
} }
/** /**
* @param string $sEmail * @param string $sEmail
* @param bool $bSkipInsert = false * @param bool $bSkipInsert = false
* @param bool $bSkipUpdateTables = false
* *
* @return int * @return int
*/ */
@ -226,7 +227,7 @@ abstract class PdoAbstract
{ {
throw new \InvalidArgumentException('Empty Email argument'); throw new \InvalidArgumentException('Empty Email argument');
} }
$oStmt = $this->prepareAndExecute('SELECT id_user FROM rainloop_users WHERE rl_email = :rl_email', $oStmt = $this->prepareAndExecute('SELECT id_user FROM rainloop_users WHERE rl_email = :rl_email',
array(':rl_email' => array($sEmail, \PDO::PARAM_STR))); array(':rl_email' => array($sEmail, \PDO::PARAM_STR)));
@ -271,17 +272,28 @@ abstract class PdoAbstract
$oPdo = $this->getPDO(); $oPdo = $this->getPDO();
if ($oPdo) if ($oPdo)
{ {
$sQuery = 'SELECT * FROM rainloop_system WHERE sys_name = ?'; if ($bReturnIntValue)
{
$sQuery = 'SELECT value_int FROM rainloop_system WHERE sys_name = ?';
}
else
{
$sQuery = 'SELECT value_str FROM rainloop_system WHERE sys_name = ?';
}
$this->writeLog($sQuery); $this->writeLog($sQuery);
$oStmt = $oPdo->prepare($sQuery); $oStmt = $oPdo->prepare($sQuery);
if ($oStmt->execute(array($sName))) if ($oStmt->execute(array($sName)))
{ {
$mRow = $oStmt->fetchAll(\PDO::FETCH_ASSOC); $mRow = $oStmt->fetchAll(\PDO::FETCH_ASSOC);
if ($mRow && isset($mRow[0]['sys_name'], $mRow[0]['value_int'], $mRow[0]['value_str'])) $sKey = $bReturnIntValue ? 'value_int' : 'value_str';
if ($mRow && isset($mRow[0][$sKey]))
{ {
return $bReturnIntValue ? (int) $mRow[0]['value_int'] : (string) $mRow[0]['value_str']; return $bReturnIntValue ? (int) $mRow[0][$sKey] : (string) $mRow[0][$sKey];
} }
return $bReturnIntValue ? 0 : '';
} }
} }
@ -290,7 +302,6 @@ abstract class PdoAbstract
/** /**
* @param string $sType * @param string $sType
* @param bool $bReturnIntValue = true
* *
* @return int|string|bool * @return int|string|bool
*/ */
@ -356,18 +367,37 @@ abstract class PdoAbstract
$aQ = array(); $aQ = array();
if ('mysql' === $this->sDbType) if ('mysql' === $this->sDbType)
{ {
$aQ[] = 'CREATE TABLE IF NOT EXISTS `rainloop_system` ( $aQ[] = 'CREATE TABLE IF NOT EXISTS rainloop_system (
`sys_name` varchar(50) NOT NULL, sys_name varchar(50) NOT NULL,
`value_int` int(11) UNSIGNED NOT NULL DEFAULT \'0\', value_int int(11) UNSIGNED NOT NULL DEFAULT \'0\',
`value_str` varchar(255) NOT NULL DEFAULT \'\' value_str varchar(128) NOT NULL DEFAULT \'\',
INDEX `sys_name_index` (`sys_name`)
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;'; ) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;';
$aQ[] = 'CREATE TABLE IF NOT EXISTS `rainloop_users` ( $aQ[] = 'CREATE TABLE IF NOT EXISTS rainloop_users (
`id_user` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, id_user int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`rl_email` varchar(255) NOT NULL, rl_email varchar(128) NOT NULL DEFAULT \'\',
UNIQUE `email_unique` (`rl_email`), PRIMARY KEY(`id_user`),
PRIMARY KEY(`id_user`) INDEX `rl_email_index` (`rl_email`)
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET ascii COLLATE ascii_general_ci */;'; ) /*!40000 ENGINE=INNODB */;';
}
else if ('postgres' === $this->sDbType)
{
$aQ[] = 'CREATE TABLE rainloop_system (
sys_name varchar(50) NOT NULL,
value_int integer NOT NULL DEFAULT 0,
value_str varchar(128) NOT NULL DEFAULT \'\'
);';
$aQ[] = 'CREATE INDEX sys_name_index ON rainloop_system (sys_name);';
$aQ[] = 'CREATE SEQUENCE rainloop_users_seq START WITH 1 INCREMENT BY 1 NO MAXVALUE NO MINVALUE CACHE 1;';
$aQ[] = 'CREATE TABLE rainloop_users (
id_user integer DEFAULT nextval(\'rainloop_users_seq\'::text) PRIMARY KEY,
rl_email varchar(128) NOT NULL DEFAULT \'\'
);';
$aQ[] = 'CREATE INDEX rl_email_index ON rainloop_users (rl_email);';
} }
if (0 < \count($aQ)) if (0 < \count($aQ))
@ -398,7 +428,7 @@ abstract class PdoAbstract
{ {
$oPdo->rollBack(); $oPdo->rollBack();
$this->oLogger->WriteException($oException); $this->writeLog($oException);
throw $oException; throw $oException;
} }
} }
@ -415,23 +445,38 @@ abstract class PdoAbstract
*/ */
protected function dataBaseUpgrade($sName, $aData = array()) protected function dataBaseUpgrade($sName, $aData = array())
{ {
$this->initSystemTables(); $iFromVersion = null;
try
$iFromVersion = $this->getVersion($sName);
$bResult = false;
$oPdo = $this->getPDO();
if ($oPdo)
{ {
$bResult = true; $iFromVersion = $this->getVersion($sName);
}
catch (\PDOException $oException)
{
$this->writeLog($oException);
$this->initSystemTables();
$iFromVersion = $this->getVersion($sName);
}
if (0 <= $iFromVersion)
{
$oPdo = false;
$bResult = false;
foreach ($aData as $iVersion => $aQuery) foreach ($aData as $iVersion => $aQuery)
{ {
if ($iFromVersion < $iVersion) if (!$oPdo)
{
$oPdo = $this->getPDO();
$bResult = true;
}
if ($iFromVersion < $iVersion && $oPdo)
{ {
try try
{ {
$oPdo->beginTransaction(); $oPdo->beginTransaction();
foreach ($aQuery as $sQuery) foreach ($aQuery as $sQuery)
{ {
$this->writeLog($sQuery); $this->writeLog($sQuery);
@ -461,7 +506,7 @@ abstract class PdoAbstract
{ {
break; break;
} }
$this->setVersion($sName, $iVersion); $this->setVersion($sName, $iVersion);
} }
} }

View file

@ -24,12 +24,13 @@ class PersonalAddressBook extends \RainLoop\Providers\AbstractProvider
} }
/** /**
* @return string * @return bool
*/ */
public function Version() public function Test()
{ {
\sleep(1);
return $this->oDriver instanceof \RainLoop\Providers\PersonalAddressBook\PersonalAddressBookInterface ? return $this->oDriver instanceof \RainLoop\Providers\PersonalAddressBook\PersonalAddressBookInterface ?
$this->oDriver->Version() : 'null'; $this->oDriver->Test() : false;
} }
/** /**
@ -77,16 +78,16 @@ class PersonalAddressBook extends \RainLoop\Providers\AbstractProvider
* @param int $iOffset = 0 * @param int $iOffset = 0
* @param type $iLimit = 20 * @param type $iLimit = 20
* @param string $sSearch = '' * @param string $sSearch = ''
* @param bool $bAutoOnly = false * @param int $iScopeType = \RainLoop\Providers\PersonalAddressBook\Enumerations\ScopeType::DEFAULT_
* @param int $iResultCount = 0 * @param int $iResultCount = 0
* *
* @return array * @return array
*/ */
public function GetContacts($oAccount, public function GetContacts($oAccount, $iOffset = 0, $iLimit = 20, $sSearch = '',
$iOffset = 0, $iLimit = 20, $sSearch = '', $bAutoOnly = false, &$iResultCount = 0) $iScopeType = \RainLoop\Providers\PersonalAddressBook\Enumerations\ScopeType::DEFAULT_, &$iResultCount = 0)
{ {
return $this->IsActive() ? $this->oDriver->GetContacts($oAccount, return $this->IsActive() ? $this->oDriver->GetContacts($oAccount,
$iOffset, $iLimit, $sSearch, $bAutoOnly, $iResultCount) : array(); $iOffset, $iLimit, $sSearch, $iScopeType, $iResultCount) : array();
} }
/** /**
@ -114,13 +115,4 @@ class PersonalAddressBook extends \RainLoop\Providers\AbstractProvider
{ {
return $this->IsActive() ? $this->oDriver->IncFrec($oAccount, $aEmails, $bCreateAuto) : false; return $this->IsActive() ? $this->oDriver->IncFrec($oAccount, $aEmails, $bCreateAuto) : false;
} }
}
/**
* @return bool
*/
public function SynchronizeStorage()
{
return $this->IsActive() && \method_exists($this->oDriver, 'SynchronizeStorage') &&
$this->oDriver->SynchronizeStorage();
}
}

View file

@ -25,25 +25,15 @@ class Contact
public $DisplayEmail; public $DisplayEmail;
/** /**
* @var bool * @var int
*/ */
public $Auto; public $ScopeType;
/**
* @var bool
*/
public $Shared;
/** /**
* @var int * @var int
*/ */
public $Changed; public $Changed;
/**
* @var array
*/
public $Tags;
/** /**
* @var int * @var int
*/ */
@ -66,10 +56,8 @@ class Contact
$this->Display = ''; $this->Display = '';
$this->DisplayName = ''; $this->DisplayName = '';
$this->DisplayEmail = ''; $this->DisplayEmail = '';
$this->Auto = false; $this->ScopeType = \RainLoop\Providers\PersonalAddressBook\Enumerations\ScopeType::DEFAULT_;
$this->Shared = false;
$this->Changed = \time(); $this->Changed = \time();
$this->Tags = array();
$this->IdPropertyFromSearch = 0; $this->IdPropertyFromSearch = 0;
$this->Properties = array(); $this->Properties = array();
} }
@ -83,6 +71,7 @@ class Contact
{ {
if ($oProperty) if ($oProperty)
{ {
$oProperty->ScopeType = $this->ScopeType;
$oProperty->UpdateDependentValues(); $oProperty->UpdateDependentValues();
if ('' === $sDisplayName && \RainLoop\Providers\PersonalAddressBook\Enumerations\PropertyType::FULLNAME === $oProperty->Type && if ('' === $sDisplayName && \RainLoop\Providers\PersonalAddressBook\Enumerations\PropertyType::FULLNAME === $oProperty->Type &&

View file

@ -16,6 +16,11 @@ class Property
*/ */
public $Type; public $Type;
/**
* @var int
*/
public $ScopeType;
/** /**
* @var string * @var string
*/ */
@ -46,6 +51,7 @@ class Property
$this->IdProperty = 0; $this->IdProperty = 0;
$this->Type = PropertyType::UNKNOWN; $this->Type = PropertyType::UNKNOWN;
$this->ScopeType = \RainLoop\Providers\PersonalAddressBook\Enumerations\ScopeType::DEFAULT_;
$this->TypeCustom = ''; $this->TypeCustom = '';
$this->Value = ''; $this->Value = '';

View file

@ -0,0 +1,10 @@
<?php
namespace RainLoop\Providers\PersonalAddressBook\Enumerations;
class ScopeType
{
const DEFAULT_ = 0;
const AUTO = 1;
const SHARE = 2;
}

View file

@ -4,7 +4,7 @@ namespace RainLoop\Providers\PersonalAddressBook;
use \RainLoop\Providers\PersonalAddressBook\Enumerations\PropertyType; use \RainLoop\Providers\PersonalAddressBook\Enumerations\PropertyType;
class MySqlPersonalAddressBook class PdoPersonalAddressBook
extends \RainLoop\Common\PdoAbstract extends \RainLoop\Common\PdoAbstract
implements \RainLoop\Providers\PersonalAddressBook\PersonalAddressBookInterface implements \RainLoop\Providers\PersonalAddressBook\PersonalAddressBookInterface
{ {
@ -49,7 +49,9 @@ class MySqlPersonalAddressBook
*/ */
public function ContactSave($oAccount, &$oContact) public function ContactSave($oAccount, &$oContact)
{ {
$this->Sync();
$iUserID = $this->getUserId($oAccount->ParentEmailHelper()); $iUserID = $this->getUserId($oAccount->ParentEmailHelper());
$iIdContact = \strlen($oContact->IdContact) && \is_numeric($oContact->IdContact) ? (int) $oContact->IdContact : 0; $iIdContact = \strlen($oContact->IdContact) && \is_numeric($oContact->IdContact) ? (int) $oContact->IdContact : 0;
$bUpdate = 0 < $iIdContact; $bUpdate = 0 < $iIdContact;
@ -57,7 +59,7 @@ class MySqlPersonalAddressBook
$oContact->UpdateDependentValues(); $oContact->UpdateDependentValues();
$oContact->Changed = \time(); $oContact->Changed = \time();
if (!$oContact->Auto) if (\RainLoop\Providers\PersonalAddressBook\Enumerations\ScopeType::AUTO !== $oContact->ScopeType)
{ {
$aEmail = $oContact->GetEmails(); $aEmail = $oContact->GetEmails();
if (0 < \count($aEmail)) if (0 < \count($aEmail))
@ -80,8 +82,9 @@ class MySqlPersonalAddressBook
// clear autocreated contacts // clear autocreated contacts
$this->prepareAndExecute( $this->prepareAndExecute(
'DELETE FROM `rainloop_pab_contacts` WHERE `id_user` = :id_user AND `auto` = 1 AND `display_email` IN ('.\implode(',', $aEmail).')', 'DELETE FROM rainloop_pab_contacts WHERE id_user = :id_user AND scope_type = :scope_type AND display_email IN ('.\implode(',', $aEmail).')',
array( array(
':scope_type' => array(\RainLoop\Providers\PersonalAddressBook\Enumerations\ScopeType::AUTO, \PDO::PARAM_INT),
':id_user' => array($iUserID, \PDO::PARAM_INT) ':id_user' => array($iUserID, \PDO::PARAM_INT)
) )
); );
@ -98,8 +101,8 @@ class MySqlPersonalAddressBook
{ {
$aFreq = $this->getContactFreq($iUserID, $iIdContact); $aFreq = $this->getContactFreq($iUserID, $iIdContact);
$sSql = 'UPDATE `rainloop_pab_contacts` SET `display` = :display, `display_name` = :display_name, `display_email` = :display_email, '. $sSql = 'UPDATE rainloop_pab_contacts SET display = :display, display_name = :display_name, display_email = :display_email, '.
'`auto` = :auto, `shared` = :shared, `changed` = :changed WHERE id_user = :id_user AND `id_contact` = :id_contact'; 'scope_type = :scope_type, changed = :changed WHERE id_user = :id_user AND id_contact = :id_contact';
$this->prepareAndExecute($sSql, $this->prepareAndExecute($sSql,
array( array(
@ -108,15 +111,14 @@ class MySqlPersonalAddressBook
':display' => array($oContact->Display, \PDO::PARAM_STR), ':display' => array($oContact->Display, \PDO::PARAM_STR),
':display_name' => array($oContact->DisplayName, \PDO::PARAM_STR), ':display_name' => array($oContact->DisplayName, \PDO::PARAM_STR),
':display_email' => array($oContact->DisplayEmail, \PDO::PARAM_STR), ':display_email' => array($oContact->DisplayEmail, \PDO::PARAM_STR),
':auto' => array($oContact->Auto, \PDO::PARAM_INT), ':scope_type' => array($oContact->ScopeType, \PDO::PARAM_INT),
':shared' => array($oContact->Shared, \PDO::PARAM_INT),
':changed' => array($oContact->Changed, \PDO::PARAM_INT), ':changed' => array($oContact->Changed, \PDO::PARAM_INT),
) )
); );
// clear previos props // clear previos props
$this->prepareAndExecute( $this->prepareAndExecute(
'DELETE FROM `rainloop_pab_properties` WHERE `id_user` = :id_user AND `id_contact` = :id_contact', 'DELETE FROM rainloop_pab_properties WHERE id_user = :id_user AND id_contact = :id_contact',
array( array(
':id_user' => array($iUserID, \PDO::PARAM_INT), ':id_user' => array($iUserID, \PDO::PARAM_INT),
':id_contact' => array($iIdContact, \PDO::PARAM_INT) ':id_contact' => array($iIdContact, \PDO::PARAM_INT)
@ -125,9 +127,9 @@ class MySqlPersonalAddressBook
} }
else else
{ {
$sSql = 'INSERT INTO `rainloop_pab_contacts` '. $sSql = 'INSERT INTO rainloop_pab_contacts '.
'(`id_user`, `display`, `display_name`, `display_email`, `auto`, `shared`, `changed`) VALUES '. '( id_user, display, display_name, display_email, scope_type, changed) VALUES '.
'(:id_user, :display, :display_name, :display_email, :auto, :shared, :changed)'; '(:id_user, :display, :display_name, :display_email, :scope_type, :changed)';
$this->prepareAndExecute($sSql, $this->prepareAndExecute($sSql,
array( array(
@ -135,8 +137,7 @@ class MySqlPersonalAddressBook
':display' => array($oContact->Display, \PDO::PARAM_STR), ':display' => array($oContact->Display, \PDO::PARAM_STR),
':display_name' => array($oContact->DisplayName, \PDO::PARAM_STR), ':display_name' => array($oContact->DisplayName, \PDO::PARAM_STR),
':display_email' => array($oContact->DisplayEmail, \PDO::PARAM_STR), ':display_email' => array($oContact->DisplayEmail, \PDO::PARAM_STR),
':auto' => array($oContact->Auto, \PDO::PARAM_INT), ':scope_type' => array($oContact->ScopeType, \PDO::PARAM_INT),
':shared' => array($oContact->Shared, \PDO::PARAM_INT),
':changed' => array($oContact->Changed, \PDO::PARAM_INT) ':changed' => array($oContact->Changed, \PDO::PARAM_INT)
) )
); );
@ -163,19 +164,18 @@ class MySqlPersonalAddressBook
$aParams[] = array( $aParams[] = array(
':id_contact' => array($iIdContact, \PDO::PARAM_INT), ':id_contact' => array($iIdContact, \PDO::PARAM_INT),
':id_user' => array($iUserID, \PDO::PARAM_INT), ':id_user' => array($iUserID, \PDO::PARAM_INT),
':type' => array($oProp->Type, \PDO::PARAM_INT), ':scope_type' => array($oContact->ScopeType, \PDO::PARAM_INT),
':type_custom' => array($oProp->TypeCustom, \PDO::PARAM_STR), ':prop_type' => array($oProp->Type, \PDO::PARAM_INT),
':value' => array($oProp->Value, \PDO::PARAM_STR), ':prop_type_custom' => array($oProp->TypeCustom, \PDO::PARAM_STR),
':value_custom' => array($oProp->ValueClear, \PDO::PARAM_STR), ':prop_value' => array($oProp->Value, \PDO::PARAM_STR),
':auto' => array($oContact->Auto, \PDO::PARAM_INT), ':prop_value_custom' => array($oProp->ValueClear, \PDO::PARAM_STR),
':shared' => array($oContact->Shared, \PDO::PARAM_INT), ':prop_frec' => array($iFreq, \PDO::PARAM_INT),
':frec' => array($iFreq, \PDO::PARAM_INT),
); );
} }
$sSql = 'INSERT INTO `rainloop_pab_properties` '. $sSql = 'INSERT INTO rainloop_pab_properties '.
'(`id_contact`, `id_user`, `type`, `type_custom`, `value`, `value_custom`, `auto`, `shared`, `frec`) VALUES '. '( id_contact, id_user, prop_type, prop_type_custom, prop_value, prop_value_custom, scope_type, prop_frec) VALUES '.
'(:id_contact, :id_user, :type, :type_custom, :value, :value_custom, :auto, :shared, :frec)'; '(:id_contact, :id_user, :prop_type, :prop_type_custom, :prop_value, :prop_value_custom, :scope_type, :prop_frec)';
$this->prepareAndExecute($sSql, $aParams, true); $this->prepareAndExecute($sSql, $aParams, true);
} }
@ -199,6 +199,7 @@ class MySqlPersonalAddressBook
*/ */
public function DeleteContacts($oAccount, $aContactIds) public function DeleteContacts($oAccount, $aContactIds)
{ {
$this->Sync();
$iUserID = $this->getUserId($oAccount->ParentEmailHelper()); $iUserID = $this->getUserId($oAccount->ParentEmailHelper());
$aContactIds = \array_filter($aContactIds, function (&$mItem) { $aContactIds = \array_filter($aContactIds, function (&$mItem) {
@ -214,9 +215,9 @@ class MySqlPersonalAddressBook
$sIDs = \implode(',', $aContactIds); $sIDs = \implode(',', $aContactIds);
$aParams = array(':id_user' => array($iUserID, \PDO::PARAM_INT)); $aParams = array(':id_user' => array($iUserID, \PDO::PARAM_INT));
$this->prepareAndExecute('DELETE FROM `rainloop_pab_tags_contacts` WHERE `id_contact` IN ('.$sIDs.')'); $this->prepareAndExecute('DELETE FROM rainloop_pab_tags_contacts WHERE id_contact IN ('.$sIDs.')');
$this->prepareAndExecute('DELETE FROM `rainloop_pab_properties` WHERE `id_user` = :id_user AND `id_contact` IN ('.$sIDs.')', $aParams); $this->prepareAndExecute('DELETE FROM rainloop_pab_properties WHERE id_user = :id_user AND id_contact IN ('.$sIDs.')', $aParams);
$this->prepareAndExecute('DELETE FROM `rainloop_pab_contacts` WHERE `id_user` = :id_user AND `id_contact` IN ('.$sIDs.')', $aParams); $this->prepareAndExecute('DELETE FROM rainloop_pab_contacts WHERE id_user = :id_user AND id_contact IN ('.$sIDs.')', $aParams);
return true; return true;
} }
@ -229,6 +230,7 @@ class MySqlPersonalAddressBook
*/ */
public function DeleteTags($oAccount, $aTagsIds) public function DeleteTags($oAccount, $aTagsIds)
{ {
$this->Sync();
$iUserID = $this->getUserId($oAccount->ParentEmailHelper()); $iUserID = $this->getUserId($oAccount->ParentEmailHelper());
$aTagsIds = \array_filter($aTagsIds, function (&$mItem) { $aTagsIds = \array_filter($aTagsIds, function (&$mItem) {
@ -244,8 +246,8 @@ class MySqlPersonalAddressBook
$sIDs = \implode(',', $aTagsIds); $sIDs = \implode(',', $aTagsIds);
$aParams = array(':id_user' => array($iUserID, \PDO::PARAM_INT)); $aParams = array(':id_user' => array($iUserID, \PDO::PARAM_INT));
$this->prepareAndExecute('DELETE FROM `rainloop_pab_tags_contacts` WHERE `id_tag` IN ('.$sIDs.')'); $this->prepareAndExecute('DELETE FROM rainloop_pab_tags_contacts WHERE id_tag IN ('.$sIDs.')');
$this->prepareAndExecute('DELETE FROM `rainloop_pab_tags` WHERE `id_user` = :id_user AND `id_tag` IN ('.$sIDs.')', $aParams); $this->prepareAndExecute('DELETE FROM rainloop_pab_tags WHERE id_user = :id_user AND id_tag IN ('.$sIDs.')', $aParams);
return true; return true;
} }
@ -255,13 +257,16 @@ class MySqlPersonalAddressBook
* @param int $iOffset = 0 * @param int $iOffset = 0
* @param int $iLimit = 20 * @param int $iLimit = 20
* @param string $sSearch = '' * @param string $sSearch = ''
* @param bool $bAutoOnly = false * @param bool $iScopeType = \RainLoop\Providers\PersonalAddressBook\Enumerations\ScopeType::DEFAULT_
* @param int $iResultCount = 0 * @param int $iResultCount = 0
* *
* @return array * @return array
*/ */
public function GetContacts($oAccount, $iOffset = 0, $iLimit = 20, $sSearch = '', $bAutoOnly = false, &$iResultCount = 0) public function GetContacts($oAccount, $iOffset = 0, $iLimit = 20, $sSearch = '',
$iScopeType = \RainLoop\Providers\PersonalAddressBook\Enumerations\ScopeType::DEFAULT_, &$iResultCount = 0)
{ {
$this->Sync();
$iOffset = 0 <= $iOffset ? $iOffset : 0; $iOffset = 0 <= $iOffset ? $iOffset : 0;
$iLimit = 0 < $iLimit ? (int) $iLimit : 20; $iLimit = 0 < $iLimit ? (int) $iLimit : 20;
$sSearch = \trim($sSearch); $sSearch = \trim($sSearch);
@ -274,10 +279,10 @@ class MySqlPersonalAddressBook
if (0 < \strlen($sSearch)) if (0 < \strlen($sSearch))
{ {
$sSql = 'SELECT `id_prop`, `id_contact` FROM `rainloop_pab_properties` WHERE `id_user` = :id_user AND `auto` = :auto AND `value` LIKE :search ESCAPE \'=\' GROUP BY `id_contact`'; $sSql = 'SELECT id_prop, id_contact FROM rainloop_pab_properties WHERE id_user = :id_user AND scope_type = :scope_type AND prop_value LIKE :search ESCAPE \'=\' GROUP BY id_contact';
$aParams = array( $aParams = array(
':id_user' => array($iUserID, \PDO::PARAM_INT), ':id_user' => array($iUserID, \PDO::PARAM_INT),
':auto' => array($bAutoOnly ? 1 : 0, \PDO::PARAM_INT), ':scope_type' => array($iScopeType, \PDO::PARAM_INT),
':search' => array($this->specialConvertSearchValue($sSearch, '='), \PDO::PARAM_STR) ':search' => array($this->specialConvertSearchValue($sSearch, '='), \PDO::PARAM_STR)
); );
@ -303,10 +308,10 @@ class MySqlPersonalAddressBook
} }
else else
{ {
$sSql = 'SELECT COUNT(DISTINCT `id_contact`) as `contact_count` FROM `rainloop_pab_properties` WHERE `id_user` = :id_user AND `auto` = :auto'; $sSql = 'SELECT COUNT(DISTINCT id_contact) as contact_count FROM rainloop_pab_properties WHERE id_user = :id_user AND scope_type = :scope_type';
$aParams = array( $aParams = array(
':id_user' => array($iUserID, \PDO::PARAM_INT), ':id_user' => array($iUserID, \PDO::PARAM_INT),
':auto' => array($bAutoOnly ? 1 : 0, \PDO::PARAM_INT) ':scope_type' => array($iScopeType, \PDO::PARAM_INT)
); );
$oStmt = $this->prepareAndExecute($sSql, $aParams); $oStmt = $this->prepareAndExecute($sSql, $aParams);
@ -324,18 +329,18 @@ class MySqlPersonalAddressBook
if (0 < $iCount) if (0 < $iCount)
{ {
$sSql = 'SELECT * FROM `rainloop_pab_contacts` WHERE id_user = :id_user AND `auto` = :auto'; $sSql = 'SELECT * FROM rainloop_pab_contacts WHERE id_user = :id_user AND scope_type = :scope_type';
$aParams = array( $aParams = array(
':id_user' => array($iUserID, \PDO::PARAM_INT), ':id_user' => array($iUserID, \PDO::PARAM_INT),
':auto' => array($bAutoOnly ? 1 : 0, \PDO::PARAM_INT) ':scope_type' => array($iScopeType, \PDO::PARAM_INT)
); );
if (0 < \count($aSearchIds)) if (0 < \count($aSearchIds))
{ {
$sSql .= ' AND `id_contact` IN ('.implode(',', $aSearchIds).')'; $sSql .= ' AND id_contact IN ('.implode(',', $aSearchIds).')';
} }
$sSql .= ' ORDER BY `display` ASC LIMIT :limit OFFSET :offset'; $sSql .= ' ORDER BY display ASC LIMIT :limit OFFSET :offset';
$aParams[':limit'] = array($iLimit, \PDO::PARAM_INT); $aParams[':limit'] = array($iLimit, \PDO::PARAM_INT);
$aParams[':offset'] = array($iOffset, \PDO::PARAM_INT); $aParams[':offset'] = array($iOffset, \PDO::PARAM_INT);
@ -360,8 +365,10 @@ class MySqlPersonalAddressBook
$oContact->Display = isset($aItem['display']) ? (string) $aItem['display'] : ''; $oContact->Display = isset($aItem['display']) ? (string) $aItem['display'] : '';
$oContact->DisplayName = isset($aItem['display_name']) ? (string) $aItem['display_name'] : ''; $oContact->DisplayName = isset($aItem['display_name']) ? (string) $aItem['display_name'] : '';
$oContact->DisplayEmail = isset($aItem['display_email']) ? (string) $aItem['display_email'] : ''; $oContact->DisplayEmail = isset($aItem['display_email']) ? (string) $aItem['display_email'] : '';
$oContact->Auto = isset($aItem['auto']) ? (bool) $aItem['auto'] : false; $oContact->ScopeType = isset($aItem['scope_type']) ? (int) $aItem['scope_type'] :
\RainLoop\Providers\PersonalAddressBook\Enumerations\ScopeType::DEFAULT_;
$oContact->Changed = isset($aItem['changed']) ? (int) $aItem['changed'] : 0; $oContact->Changed = isset($aItem['changed']) ? (int) $aItem['changed'] : 0;
$oContact->IdPropertyFromSearch = isset($aPropertyFromSearchIds[$iIdContact]) && $oContact->IdPropertyFromSearch = isset($aPropertyFromSearchIds[$iIdContact]) &&
0 < $aPropertyFromSearchIds[$iIdContact] ? $aPropertyFromSearchIds[$iIdContact] : 0; 0 < $aPropertyFromSearchIds[$iIdContact] ? $aPropertyFromSearchIds[$iIdContact] : 0;
@ -376,7 +383,7 @@ class MySqlPersonalAddressBook
{ {
$oStmt->closeCursor(); $oStmt->closeCursor();
$sSql = 'SELECT * FROM `rainloop_pab_properties` WHERE id_user = :id_user AND `id_contact` IN ('.\implode(',', $aIdContacts).')'; $sSql = 'SELECT * FROM rainloop_pab_properties WHERE id_user = :id_user AND id_contact IN ('.\implode(',', $aIdContacts).')';
$oStmt = $this->prepareAndExecute($sSql, array( $oStmt = $this->prepareAndExecute($sSql, array(
':id_user' => array($iUserID, \PDO::PARAM_INT) ':id_user' => array($iUserID, \PDO::PARAM_INT)
)); ));
@ -388,18 +395,20 @@ class MySqlPersonalAddressBook
{ {
foreach ($aFetch as $aItem) foreach ($aFetch as $aItem)
{ {
if ($aItem && isset($aItem['id_prop'], $aItem['id_contact'], $aItem['type'], $aItem['value'])) if ($aItem && isset($aItem['id_prop'], $aItem['id_contact'], $aItem['prop_type'], $aItem['prop_value']))
{ {
$iId = (int) $aItem['id_contact']; $iId = (int) $aItem['id_contact'];
if (0 < $iId && isset($aContacts[$iId])) if (0 < $iId && isset($aContacts[$iId]))
{ {
$oProperty = new \RainLoop\Providers\PersonalAddressBook\Classes\Property(); $oProperty = new \RainLoop\Providers\PersonalAddressBook\Classes\Property();
$oProperty->IdProperty = (int) $aItem['id_prop']; $oProperty->IdProperty = (int) $aItem['id_prop'];
$oProperty->Type = (int) $aItem['type']; $oProperty->ScopeType = isset($aItem['scope_type']) ? (int) $aItem['scope_type'] :
$oProperty->TypeCustom = isset($aItem['type_custom']) ? (string) $aItem['type_custom'] : ''; \RainLoop\Providers\PersonalAddressBook\Enumerations\ScopeType::DEFAULT_;
$oProperty->Value = (string) $aItem['value']; $oProperty->Type = (int) $aItem['prop_type'];
$oProperty->ValueClear = isset($aItem['value_clear']) ? (string) $aItem['value_clear'] : ''; $oProperty->TypeCustom = isset($aItem['prop_type_custom']) ? (string) $aItem['prop_type_custom'] : '';
$oProperty->Frec = isset($aItem['frec']) ? (int) $aItem['frec'] : 0; $oProperty->Value = (string) $aItem['prop_value'];
$oProperty->ValueClear = isset($aItem['prop_value_clear']) ? (string) $aItem['prop_value_clear'] : '';
$oProperty->Frec = isset($aItem['prop_frec']) ? (int) $aItem['prop_frec'] : 0;
$aContacts[$iId]->Properties[] = $oProperty; $aContacts[$iId]->Properties[] = $oProperty;
} }
@ -440,14 +449,15 @@ class MySqlPersonalAddressBook
throw new \InvalidArgumentException('Empty Search argument'); throw new \InvalidArgumentException('Empty Search argument');
} }
$this->Sync();
$iUserID = $this->getUserId($oAccount->ParentEmailHelper()); $iUserID = $this->getUserId($oAccount->ParentEmailHelper());
$sTypes = implode(',', array( $sTypes = implode(',', array(
PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES, PropertyType::EMAIl_OTHER, PropertyType::FULLNAME PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES, PropertyType::EMAIl_OTHER, PropertyType::FULLNAME
)); ));
$sSql = 'SELECT `id_contact`, `id_prop`, `type`, `value` FROM `rainloop_pab_properties` '. $sSql = 'SELECT id_contact, id_prop, prop_type, prop_value FROM rainloop_pab_properties '.
'WHERE id_user = :id_user AND `type` IN ('.$sTypes.') AND `value` LIKE :search ESCAPE \'=\''; 'WHERE id_user = :id_user AND prop_type IN ('.$sTypes.') AND prop_value LIKE :search ESCAPE \'=\'';
$aParams = array( $aParams = array(
':id_user' => array($iUserID, \PDO::PARAM_INT), ':id_user' => array($iUserID, \PDO::PARAM_INT),
@ -455,7 +465,7 @@ class MySqlPersonalAddressBook
':search' => array($this->specialConvertSearchValue($sSearch, '='), \PDO::PARAM_STR) ':search' => array($this->specialConvertSearchValue($sSearch, '='), \PDO::PARAM_STR)
); );
$sSql .= ' ORDER BY `frec` DESC'; $sSql .= ' ORDER BY prop_frec DESC';
$sSql .= ' LIMIT :limit'; $sSql .= ' LIMIT :limit';
$aResult = array(); $aResult = array();
@ -475,7 +485,7 @@ class MySqlPersonalAddressBook
if (0 < $iIdContact) if (0 < $iIdContact)
{ {
$aIdContacts[$iIdContact] = $iIdContact; $aIdContacts[$iIdContact] = $iIdContact;
$iType = isset($aItem['type']) ? (int) $aItem['type'] : PropertyType::UNKNOWN; $iType = isset($aItem['prop_type']) ? (int) $aItem['prop_type'] : PropertyType::UNKNOWN;
if (\in_array($iType, array(PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES, PropertyType::EMAIl_OTHER, PropertyType::FULLNAME))) if (\in_array($iType, array(PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES, PropertyType::EMAIl_OTHER, PropertyType::FULLNAME)))
{ {
@ -489,8 +499,8 @@ class MySqlPersonalAddressBook
$aFirstResult[] = array( $aFirstResult[] = array(
'id_prop' => isset($aItem['id_prop']) ? (int) $aItem['id_prop'] : 0, 'id_prop' => isset($aItem['id_prop']) ? (int) $aItem['id_prop'] : 0,
'id_contact' => $iIdContact, 'id_contact' => $iIdContact,
'value' => isset($aItem['value']) ? (string) $aItem['value'] : '', 'prop_value' => isset($aItem['prop_value']) ? (string) $aItem['prop_value'] : '',
'type' => $iType 'prop_type' => $iType
); );
} }
} }
@ -509,8 +519,8 @@ class MySqlPersonalAddressBook
PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES, PropertyType::EMAIl_OTHER, PropertyType::FULLNAME PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES, PropertyType::EMAIl_OTHER, PropertyType::FULLNAME
)); ));
$sSql = 'SELECT `id_prop`, `id_contact`, `type`, `value` FROM `rainloop_pab_properties` '. $sSql = 'SELECT id_prop, id_contact, prop_type, prop_value FROM rainloop_pab_properties '.
'WHERE id_user = :id_user AND `type` IN ('.$sTypes.') AND `id_contact` IN ('.\implode(',', $aIdContacts).')'; 'WHERE id_user = :id_user AND prop_type IN ('.$sTypes.') AND id_contact IN ('.\implode(',', $aIdContacts).')';
$oStmt = $this->prepareAndExecute($sSql, array( $oStmt = $this->prepareAndExecute($sSql, array(
':id_user' => array($iUserID, \PDO::PARAM_INT) ':id_user' => array($iUserID, \PDO::PARAM_INT)
@ -525,14 +535,14 @@ class MySqlPersonalAddressBook
foreach ($aFetch as $aItem) foreach ($aFetch as $aItem)
{ {
if ($aItem && isset($aItem['id_prop'], $aItem['id_contact'], $aItem['type'], $aItem['value'])) if ($aItem && isset($aItem['id_prop'], $aItem['id_contact'], $aItem['prop_type'], $aItem['prop_value']))
{ {
$iIdContact = (int) $aItem['id_contact']; $iIdContact = (int) $aItem['id_contact'];
$iType = (int) $aItem['type']; $iType = (int) $aItem['prop_type'];
if (PropertyType::FULLNAME === $iType) if (PropertyType::FULLNAME === $iType)
{ {
$aNames[$iIdContact] = $aItem['value']; $aNames[$iIdContact] = $aItem['prop_value'];
} }
else if (\in_array($iType, else if (\in_array($iType,
array(PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES, PropertyType::EMAIl_OTHER))) array(PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES, PropertyType::EMAIl_OTHER)))
@ -542,17 +552,17 @@ class MySqlPersonalAddressBook
$aEmails[$iIdContact] = array(); $aEmails[$iIdContact] = array();
} }
$aEmails[$iIdContact][] = $aItem['value']; $aEmails[$iIdContact][] = $aItem['prop_value'];
} }
} }
} }
foreach ($aFirstResult as $aItem) foreach ($aFirstResult as $aItem)
{ {
if ($aItem && !empty($aItem['value'])) if ($aItem && !empty($aItem['prop_value']))
{ {
$iIdContact = (int) $aItem['id_contact']; $iIdContact = (int) $aItem['id_contact'];
$iType = (int) $aItem['type']; $iType = (int) $aItem['prop_type'];
if (PropertyType::FULLNAME === $iType) if (PropertyType::FULLNAME === $iType)
{ {
@ -562,7 +572,7 @@ class MySqlPersonalAddressBook
{ {
if (!empty($sEmail)) if (!empty($sEmail))
{ {
$aResult[] = array($sEmail, (string) $aItem['value']); $aResult[] = array($sEmail, (string) $aItem['prop_value']);
} }
} }
} }
@ -570,7 +580,7 @@ class MySqlPersonalAddressBook
else if (\in_array($iType, else if (\in_array($iType,
array(PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES, PropertyType::EMAIl_OTHER))) array(PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES, PropertyType::EMAIl_OTHER)))
{ {
$aResult[] = array((string) $aItem['value'], $aResult[] = array((string) $aItem['prop_value'],
isset($aNames[$iIdContact]) ? (string) $aNames[$iIdContact] : ''); isset($aNames[$iIdContact]) ? (string) $aNames[$iIdContact] : '');
} }
} }
@ -601,8 +611,6 @@ class MySqlPersonalAddressBook
*/ */
public function IncFrec($oAccount, $aEmails, $bCreateAuto = true) public function IncFrec($oAccount, $aEmails, $bCreateAuto = true)
{ {
$iUserID = $this->getUserId($oAccount->ParentEmailHelper());
$self = $this; $self = $this;
$aEmailsObjects = \array_map(function ($mItem) { $aEmailsObjects = \array_map(function ($mItem) {
$oResult = null; $oResult = null;
@ -619,6 +627,9 @@ class MySqlPersonalAddressBook
throw new \InvalidArgumentException('Empty Emails argument'); throw new \InvalidArgumentException('Empty Emails argument');
} }
$this->Sync();
$iUserID = $this->getUserId($oAccount->ParentEmailHelper());
$sTypes = \implode(',', array( $sTypes = \implode(',', array(
PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES, PropertyType::EMAIl_OTHER PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES, PropertyType::EMAIl_OTHER
)); ));
@ -629,7 +640,7 @@ class MySqlPersonalAddressBook
if ($bCreateAuto) if ($bCreateAuto)
{ {
$sSql = 'SELECT `value` FROM `rainloop_pab_properties` WHERE id_user = :id_user AND `type` IN ('.$sTypes.')'; $sSql = 'SELECT prop_value FROM rainloop_pab_properties WHERE id_user = :id_user AND prop_type IN ('.$sTypes.')';
$oStmt = $this->prepareAndExecute($sSql, array( $oStmt = $this->prepareAndExecute($sSql, array(
':id_user' => array($iUserID, \PDO::PARAM_INT) ':id_user' => array($iUserID, \PDO::PARAM_INT)
)); ));
@ -641,9 +652,9 @@ class MySqlPersonalAddressBook
{ {
foreach ($aFetch as $aItem) foreach ($aFetch as $aItem)
{ {
if ($aItem && !empty($aItem['value'])) if ($aItem && !empty($aItem['prop_value']))
{ {
$aExists[] = \strtolower(\trim($aItem['value'])); $aExists[] = \strtolower(\trim($aItem['prop_value']));
} }
} }
} }
@ -685,11 +696,12 @@ class MySqlPersonalAddressBook
$oContact = new \RainLoop\Providers\PersonalAddressBook\Classes\Contact(); $oContact = new \RainLoop\Providers\PersonalAddressBook\Classes\Contact();
foreach ($aEmailsToCreate as $oEmail) foreach ($aEmailsToCreate as $oEmail)
{ {
$oContact->Auto = true; $oContact->ScopeType = \RainLoop\Providers\PersonalAddressBook\Enumerations\ScopeType::AUTO;
if ('' !== \trim($oEmail->GetEmail())) if ('' !== \trim($oEmail->GetEmail()))
{ {
$oPropEmail = new \RainLoop\Providers\PersonalAddressBook\Classes\Property(); $oPropEmail = new \RainLoop\Providers\PersonalAddressBook\Classes\Property();
$oPropEmail->ScopeType = $oContact->ScopeType;
$oPropEmail->Type = \RainLoop\Providers\PersonalAddressBook\Enumerations\PropertyType::EMAIl_PERSONAL; $oPropEmail->Type = \RainLoop\Providers\PersonalAddressBook\Enumerations\PropertyType::EMAIl_PERSONAL;
$oPropEmail->Value = \strtolower(\trim($oEmail->GetEmail())); $oPropEmail->Value = \strtolower(\trim($oEmail->GetEmail()));
@ -699,6 +711,7 @@ class MySqlPersonalAddressBook
if ('' !== \trim($oEmail->GetDisplayName())) if ('' !== \trim($oEmail->GetDisplayName()))
{ {
$oPropName = new \RainLoop\Providers\PersonalAddressBook\Classes\Property(); $oPropName = new \RainLoop\Providers\PersonalAddressBook\Classes\Property();
$oPropName->ScopeType = $oContact->ScopeType;
$oPropName->Type = \RainLoop\Providers\PersonalAddressBook\Enumerations\PropertyType::FULLNAME; $oPropName->Type = \RainLoop\Providers\PersonalAddressBook\Enumerations\PropertyType::FULLNAME;
$oPropName->Value = \trim($oEmail->GetDisplayName()); $oPropName->Value = \trim($oEmail->GetDisplayName());
@ -714,7 +727,7 @@ class MySqlPersonalAddressBook
} }
} }
$sSql = 'UPDATE `rainloop_pab_properties` SET `frec` = `frec` + 1 WHERE id_user = :id_user AND `type` IN ('.$sTypes; $sSql = 'UPDATE rainloop_pab_properties SET prop_frec = prop_frec + 1 WHERE id_user = :id_user AND prop_type IN ('.$sTypes;
$aEmailsQuoted = \array_map(function ($mItem) use ($self) { $aEmailsQuoted = \array_map(function ($mItem) use ($self) {
return $self->quoteValue($mItem); return $self->quoteValue($mItem);
@ -722,11 +735,11 @@ class MySqlPersonalAddressBook
if (1 === \count($aEmailsQuoted)) if (1 === \count($aEmailsQuoted))
{ {
$sSql .= ') AND `value` = '.$aEmailsQuoted[0]; $sSql .= ') AND prop_value = '.$aEmailsQuoted[0];
} }
else else
{ {
$sSql .= ') AND `value` IN ('.\implode(',', $aEmailsQuoted).')'; $sSql .= ') AND prop_value IN ('.\implode(',', $aEmailsQuoted).')';
} }
return !!$this->prepareAndExecute($sSql, array( return !!$this->prepareAndExecute($sSql, array(
@ -737,77 +750,78 @@ class MySqlPersonalAddressBook
/** /**
* @return string * @return string
*/ */
public function Version() public function Test()
{ {
return 'MySqlPersonalAddressBookDriver-v14'; $this->Sync();
return 0 < $this->getVersion('mysql-pab-version');
} }
/** /**
* @return bool * @return bool
*/ */
public function SynchronizeStorage() public function Sync()
{ {
return $this->dataBaseUpgrade('mysql-pab-version', array( return $this->dataBaseUpgrade('mysql-pab-version', array(
1 => array( 1 => array(
// -- rainloop_pab_contacts -- // -- rainloop_pab_contacts --
'CREATE TABLE IF NOT EXISTS `rainloop_pab_contacts` ( 'CREATE TABLE IF NOT EXISTS rainloop_pab_contacts (
`id_contact` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, id_contact int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`id_user` int(11) UNSIGNED NOT NULL, id_user int(11) UNSIGNED NOT NULL,
`display` varchar(255) NOT NULL DEFAULT \'\', scope_type int(4) UNSIGNED NOT NULL DEFAULT 0,
`display_name` varchar(255) NOT NULL DEFAULT \'\', display_name varchar(255) NOT NULL DEFAULT \'\',
`display_email` varchar(255) NOT NULL DEFAULT \'\', display_email varchar(255) NOT NULL DEFAULT \'\',
`auto` int(1) UNSIGNED NOT NULL DEFAULT \'0\', display varchar(255) NOT NULL DEFAULT \'\',
`shared` int(1) UNSIGNED NOT NULL DEFAULT \'0\', changed int(11) UNSIGNED NOT NULL DEFAULT 0,
`changed` int(11) UNSIGNED NOT NULL DEFAULT \'0\',
PRIMARY KEY(`id_contact`), PRIMARY KEY(id_contact),
INDEX `id_user_index` (`id_user`) INDEX id_user_scope_type_index (id_user, scope_type)
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;', )/*!40000 ENGINE=INNODB *//*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;',
// -- rainloop_pab_properties -- // -- rainloop_pab_properties --
'CREATE TABLE IF NOT EXISTS `rainloop_pab_properties` ( 'CREATE TABLE IF NOT EXISTS rainloop_pab_properties (
`id_prop` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, id_prop int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`id_contact` int(11) UNSIGNED NOT NULL, id_contact int(11) UNSIGNED NOT NULL,
`id_user` int(11) UNSIGNED NOT NULL, id_user int(11) UNSIGNED NOT NULL,
`type` int(11) UNSIGNED NOT NULL, scope_type int(4) UNSIGNED NOT NULL DEFAULT 0,
`type_custom` varchar(50) /*!40101 CHARACTER SET ascii COLLATE ascii_general_ci */ NOT NULL DEFAULT \'\', prop_type int(11) UNSIGNED NOT NULL,
`value` varchar(255) NOT NULL DEFAULT \'\', prop_type_custom varchar(50) /*!40101 CHARACTER SET ascii COLLATE ascii_general_ci */ NOT NULL DEFAULT \'\',
`value_custom` varchar(255) NOT NULL DEFAULT \'\', prop_value varchar(255) NOT NULL DEFAULT \'\',
`auto` int(1) UNSIGNED NOT NULL DEFAULT \'0\', prop_value_custom varchar(255) NOT NULL DEFAULT \'\',
`shared` int(1) UNSIGNED NOT NULL DEFAULT \'0\', prop_frec int(11) UNSIGNED NOT NULL DEFAULT 0,
`frec` int(11) UNSIGNED NOT NULL DEFAULT \'0\',
PRIMARY KEY(`id_prop`), PRIMARY KEY(id_prop),
INDEX `id_user_index` (`id_user`), INDEX id_user_index (id_user),
INDEX `id_user_id_contact_index` (`id_user`, `id_contact`) INDEX id_user_id_contact_scope_type_index (id_user, id_contact, scope_type)
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;', )/*!40000 ENGINE=INNODB *//*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;',
// -- rainloop_pab_tags -- // -- rainloop_pab_tags --
'CREATE TABLE IF NOT EXISTS `rainloop_pab_tags` ( 'CREATE TABLE IF NOT EXISTS rainloop_pab_tags (
`id_tag` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, id_tag int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`id_user` int(11) UNSIGNED NOT NULL, id_user int(11) UNSIGNED NOT NULL,
`name` varchar(255) NOT NULL, tag_name varchar(255) NOT NULL,
PRIMARY KEY(`id_tag`), PRIMARY KEY(id_tag),
INDEX `id_user_index` (`id_user`) INDEX id_user_index (id_user),
INDEX id_user_name_index (id_user, tag_name)
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;', )/*!40000 ENGINE=INNODB *//*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;',
// -- rainloop_pab_tags_contacts -- // -- rainloop_pab_tags_contacts --
'CREATE TABLE IF NOT EXISTS `rainloop_pab_tags_contacts` ( 'CREATE TABLE IF NOT EXISTS rainloop_pab_tags_contacts (
`id_tag` int(11) UNSIGNED NOT NULL, id_tag int(11) UNSIGNED NOT NULL,
`id_contact` int(11) UNSIGNED NOT NULL, id_contact int(11) UNSIGNED NOT NULL,
INDEX `id_contact_id_tag_index` (`id_contact`, `id_tag`) INDEX id_tag_index (id_tag),
INDEX id_contact_index (id_contact)
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;' )/*!40000 ENGINE=INNODB *//*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;'
))); )));
} }
@ -824,7 +838,7 @@ class MySqlPersonalAddressBook
PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES, PropertyType::EMAIl_OTHER PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES, PropertyType::EMAIl_OTHER
)); ));
$sSql = 'SELECT `value`, `frec` FROM `rainloop_pab_properties` WHERE id_user = :id_user AND `id_contact` = :id_contact AND `type` IN ('.$sTypes.')'; $sSql = 'SELECT prop_value, prop_frec FROM rainloop_pab_properties WHERE id_user = :id_user AND id_contact = :id_contact AND prop_type IN ('.$sTypes.')';
$aParams = array( $aParams = array(
':id_user' => array($iUserID, \PDO::PARAM_INT), ':id_user' => array($iUserID, \PDO::PARAM_INT),
':id_contact' => array($iIdContact, \PDO::PARAM_INT) ':id_contact' => array($iIdContact, \PDO::PARAM_INT)
@ -838,9 +852,9 @@ class MySqlPersonalAddressBook
{ {
foreach ($aFetch as $aItem) foreach ($aFetch as $aItem)
{ {
if ($aItem && !empty($aItem['value']) && !empty($aItem['frec'])) if ($aItem && !empty($aItem['prop_value']) && !empty($aItem['prop_frec']))
{ {
$aResult[$aItem['value']] = (int) $aItem['frec']; $aResult[$aItem['prop_value']] = (int) $aItem['prop_frec'];
} }
} }
} }

View file

@ -4,11 +4,6 @@ namespace RainLoop\Providers\PersonalAddressBook;
interface PersonalAddressBookInterface interface PersonalAddressBookInterface
{ {
/**
* @return string
*/
public function Version();
/** /**
* @return bool * @return bool
*/ */
@ -41,15 +36,15 @@ interface PersonalAddressBookInterface
/** /**
* @param \RainLoop\Account $oAccount * @param \RainLoop\Account $oAccount
* @param int $iOffset = 0 * @param int $iOffset = 0
* @param type $iLimit = 20 * @param int $iLimit = 20
* @param string $sSearch = '' * @param string $sSearch = ''
* @param bool $bAutoOnly = false * @param bool $iScopeType = \RainLoop\Providers\PersonalAddressBook\Enumerations\ScopeType::DEFAULT_
* @param int $iResultCount = 0 * @param int $iResultCount = 0
* *
* @return array * @return array
*/ */
public function GetContacts($oAccount, public function GetContacts($oAccount, $iOffset = 0, $iLimit = 20, $sSearch = '',
$iOffset = 0, $iLimit = 20, $sSearch = '', $bAutoOnly = false, &$iResultCount = 0); $iScopeType = \RainLoop\Providers\PersonalAddressBook\Enumerations\ScopeType::DEFAULT_, &$iResultCount = 0);
/** /**
* @param \RainLoop\Account $oAccount * @param \RainLoop\Account $oAccount

View file

@ -20,9 +20,12 @@
</label> </label>
</div> </div>
</div> </div>
<div class="legend">
PDO (MySQL)
</div>
<div class="control-group"> <div class="control-group">
<label class="control-label"> <label class="control-label">
PDO dsn Dsn
</label> </label>
<div class="controls"> <div class="controls">
<input type="text" class="span6" data-bind="value: pdoDsn, saveTrigger: pdoDsnTrigger" /> <input type="text" class="span6" data-bind="value: pdoDsn, saveTrigger: pdoDsnTrigger" />
@ -31,7 +34,7 @@
</div> </div>
<div class="control-group"> <div class="control-group">
<label class="control-label"> <label class="control-label">
PDO user User
</label> </label>
<div class="controls"> <div class="controls">
<input type="text" data-bind="value: pdoUser, saveTrigger: pdoUserTrigger" /> <input type="text" data-bind="value: pdoUser, saveTrigger: pdoUserTrigger" />
@ -40,12 +43,21 @@
</div> </div>
<div class="control-group"> <div class="control-group">
<label class="control-label"> <label class="control-label">
PDO password Password
</label> </label>
<div class="controls"> <div class="controls">
<input type="password" data-bind="value: pdoPassword, saveTrigger: pdoPasswordTrigger" /> <input type="password" data-bind="value: pdoPassword, saveTrigger: pdoPasswordTrigger" />
<div data-bind="saveTrigger: pdoPasswordTrigger"></div> <div data-bind="saveTrigger: pdoPasswordTrigger"></div>
</div> </div>
</div> </div>
<div class="control-group">
<div class="controls">
<a class="btn" data-bind="command: testContactsCommand, css: { 'btn-success': testContactsSuccess, 'btn-danger': testContactsError }">
<i data-bind="css: {'icon-info': !testing(), 'icon-spinner-2 animated': testing(), 'icon-white': testContactsSuccess() || testContactsError() }"></i>
&nbsp;&nbsp;
Test
</a>
</div>
</div>
</div> </div>
</div> </div>

View file

@ -2,6 +2,11 @@
<div class="messageList g-ui-user-select-none" data-bind="css: {'message-selected': isMessageSelected, 'loading': messageListCompleteLoadingThrottle, 'hideMessageListCheckbox': !useCheckboxesInList() }"> <div class="messageList g-ui-user-select-none" data-bind="css: {'message-selected': isMessageSelected, 'loading': messageListCompleteLoadingThrottle, 'hideMessageListCheckbox': !useCheckboxesInList() }">
<div class="toolbar"> <div class="toolbar">
<div class="btn-toolbar"> <div class="btn-toolbar">
<div class="btn-group">
<a class="btn buttonReload" data-placement="bottom" data-bind="command: reloadCommand, tooltip: 'MESSAGE_LIST/BUTTON_RELOAD'">
<i class="icon-spinner-2" data-bind="css: {'animated': messageListCompleteLoadingThrottle}"></i>
</a>
</div>
<div class="btn-group"> <div class="btn-group">
<a class="btn dropdown-toggle buttonMove" data-toggle="dropdown" data-placement="bottom" data-bind="command: moveCommand, tooltip: 'MESSAGE_LIST/BUTTON_MOVE_TO'"> <a class="btn dropdown-toggle buttonMove" data-toggle="dropdown" data-placement="bottom" data-bind="command: moveCommand, tooltip: 'MESSAGE_LIST/BUTTON_MOVE_TO'">
<i class="icon-legacyfilemanager"></i> <i class="icon-legacyfilemanager"></i>
@ -101,8 +106,11 @@
<span class="caret"></span> <span class="caret"></span>
</a> </a>
</div> </div>
<i class="checkboxCkeckAll" data-bind="css: checkAll() ? (isIncompleteChecked() ? 'icon-checkbox-partial' : 'icon-checkbox-checked') : 'icon-checkbox-unchecked'"></i>
<!--
<i class="checkboxCkeckAll" data-bind="css: checkAll() ? (isIncompleteChecked() ? 'icon-checkbox-partial' : 'icon-checkbox-checked') : 'icon-checkbox-unchecked', visible: !messageListCompleteLoadingThrottle()"></i> <i class="checkboxCkeckAll" data-bind="css: checkAll() ? (isIncompleteChecked() ? 'icon-checkbox-partial' : 'icon-checkbox-checked') : 'icon-checkbox-unchecked', visible: !messageListCompleteLoadingThrottle()"></i>
<i class="icon-spinner-2 animated" style="margin-top: 4px;" data-bind="visible: messageListCompleteLoadingThrottle"></i> <i class="icon-spinner-2 animated" style="margin-top: 4px;" data-bind="visible: messageListCompleteLoadingThrottle"></i>
-->
</div> </div>
</div> </div>
<div class="mainDelimiter toolbarDelimiter"></div> <div class="mainDelimiter toolbarDelimiter"></div>
@ -144,9 +152,11 @@
</div> </div>
<div class="mainDelimiter footerDelimiter"></div> <div class="mainDelimiter footerDelimiter"></div>
<div class="b-footer thm-message-list-bottom-toolbar"> <div class="b-footer thm-message-list-bottom-toolbar">
<!--
<a class="btn buttonReload" data-placement="right" data-bind="command: reloadCommand, tooltip: 'MESSAGE_LIST/BUTTON_RELOAD'"> <a class="btn buttonReload" data-placement="right" data-bind="command: reloadCommand, tooltip: 'MESSAGE_LIST/BUTTON_RELOAD'">
<i class="icon-spinner-2" data-bind="css: {'animated': messageListCompleteLoadingThrottle}"></i> <i class="icon-spinner-2" data-bind="css: {'animated': messageListCompleteLoadingThrottle}"></i>
</a> </a>
-->
<span data-bind="visible: 0 < userUsageProc(), tooltip2: quotaTooltip" class="e-quota"> <span data-bind="visible: 0 < userUsageProc(), tooltip2: quotaTooltip" class="e-quota">
<span data-bind="text: userUsageProc"></span>% <span data-bind="text: userUsageProc"></span>%
</span> </span>

View file

@ -5638,6 +5638,9 @@ html.no-rgba .modal {
.inputosaurus-container li a:hover { .inputosaurus-container li a:hover {
color: #666; color: #666;
} }
.inputosaurus-container li span {
padding-right: 3px;
}
.inputosaurus-container li.inputosaurus-required { .inputosaurus-container li.inputosaurus-required {
padding-rigth: 5px; padding-rigth: 5px;
} }
@ -6334,7 +6337,7 @@ html.rl-no-preview-pane .messageList.message-selected {
} }
.messageList .b-footer .e-quota { .messageList .b-footer .e-quota {
display: inline-block; display: inline-block;
margin-left: 10px; margin-top: 5px;
font-size: 18px; font-size: 18px;
cursor: help; cursor: help;
} }

File diff suppressed because one or more lines are too long

View file

@ -3483,6 +3483,9 @@ html.no-rgba .modal {
.inputosaurus-container li a:hover { .inputosaurus-container li a:hover {
color: #666; color: #666;
} }
.inputosaurus-container li span {
padding-right: 3px;
}
.inputosaurus-container li.inputosaurus-required { .inputosaurus-container li.inputosaurus-required {
padding-rigth: 5px; padding-rigth: 5px;
} }
@ -4179,7 +4182,7 @@ html.rl-no-preview-pane .messageList.message-selected {
} }
.messageList .b-footer .e-quota { .messageList .b-footer .e-quota {
display: inline-block; display: inline-block;
margin-left: 10px; margin-top: 5px;
font-size: 18px; font-size: 18px;
cursor: help; cursor: help;
} }

View file

@ -1013,9 +1013,10 @@ Utils.removeSelection = function ()
/** /**
* @param {string} sPrefix * @param {string} sPrefix
* @param {string} sSubject * @param {string} sSubject
* @param {boolean=} bFixLongSubject = true
* @return {string} * @return {string}
*/ */
Utils.replySubjectAdd = function (sPrefix, sSubject) Utils.replySubjectAdd = function (sPrefix, sSubject, bFixLongSubject)
{ {
var var
oMatch = null, oMatch = null,
@ -1037,7 +1038,47 @@ Utils.replySubjectAdd = function (sPrefix, sSubject)
sResult = sPrefix + ': ' + sSubject; sResult = sPrefix + ': ' + sSubject;
} }
return sResult; sResult = sResult.replace(/[\s]+/g, ' ');
return (Utils.isUnd(bFixLongSubject) ? true : bFixLongSubject) ? Utils.fixLongSubject(sResult) : sResult;
};
/**
* @param {string} sSubject
* @return {string}
*/
Utils.fixLongSubject = function (sSubject)
{
var
iCounter = 0,
oMatch = null
;
sSubject = Utils.trim(sSubject.replace(/[\s]+/, ' '));
do
{
oMatch = /^Re(\[([\d]+)\]|):[\s]{0,3}Re(\[([\d]+)\]|):/ig.exec(sSubject);
window.console.log(sSubject);
window.console.log(oMatch);
if (!oMatch || Utils.isUnd(oMatch[0]))
{
oMatch = null;
}
if (oMatch)
{
iCounter = 0;
iCounter += Utils.isUnd(oMatch[2]) ? 1 : 0 + Utils.pInt(oMatch[2]);
iCounter += Utils.isUnd(oMatch[4]) ? 1 : 0 + Utils.pInt(oMatch[4]);
sSubject = sSubject.replace(/^Re(\[[\d]+\]|):[\s]{0,3}Re(\[[\d]+\]|):/gi, 'Re' + (0 < iCounter ? '[' + iCounter + ']' : '') + ':');
}
}
while (oMatch);
sSubject = sSubject.replace(/[\s]+/, ' ');
return sSubject;
}; };
/** /**
@ -5216,10 +5257,52 @@ function AdminContacts()
this.pdoDsnTrigger = ko.observable(Enums.SaveSettingsStep.Idle); this.pdoDsnTrigger = ko.observable(Enums.SaveSettingsStep.Idle);
this.pdoUserTrigger = ko.observable(Enums.SaveSettingsStep.Idle); this.pdoUserTrigger = ko.observable(Enums.SaveSettingsStep.Idle);
this.pdoPasswordTrigger = ko.observable(Enums.SaveSettingsStep.Idle); this.pdoPasswordTrigger = ko.observable(Enums.SaveSettingsStep.Idle);
this.testing = ko.observable(false);
this.testContactsSuccess = ko.observable(false);
this.testContactsError = ko.observable(false);
this.testContactsCommand = Utils.createCommand(this, function () {
this.testContactsSuccess(false);
this.testContactsError(false);
this.testing(true);
RL.remote().testContacts(this.onTestContactsResponse, {
'ContactsPdoDsn': this.pdoDsn(),
'ContactsPdoUser': this.pdoUser(),
'ContactsPdoPassword': this.pdoPassword()
});
}, function () {
return '' !== this.pdoDsn() && '' !== this.pdoUser();
});
this.onTestContactsResponse = _.bind(this.onTestContactsResponse, this);
} }
Utils.addSettingsViewModel(AdminContacts, 'AdminSettingsContacts', 'Contacts', 'contacts'); Utils.addSettingsViewModel(AdminContacts, 'AdminSettingsContacts', 'Contacts', 'contacts');
AdminContacts.prototype.onTestContactsResponse = function (sResult, oData)
{
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
{
this.testContactsSuccess(true);
}
else
{
this.testContactsError(true);
}
this.testing(false);
};
AdminContacts.prototype.onShow = function ()
{
this.testContactsSuccess(false);
this.testContactsError(false);
};
AdminContacts.prototype.onBuild = function () AdminContacts.prototype.onBuild = function ()
{ {
var self = this; var self = this;
@ -5371,8 +5454,6 @@ function AdminSecurity()
this.adminPasswordUpdateSuccess(false); this.adminPasswordUpdateSuccess(false);
}, this); }, this);
this.onNewAdminPasswordResponse = _.bind(this.onNewAdminPasswordResponse, this);
this.saveNewAdminPasswordCommand = Utils.createCommand(this, function () { this.saveNewAdminPasswordCommand = Utils.createCommand(this, function () {
this.adminPasswordUpdateError(false); this.adminPasswordUpdateError(false);
@ -5386,6 +5467,8 @@ function AdminSecurity()
}, function () { }, function () {
return '' !== this.adminPassword() && '' !== this.adminPasswordNew(); return '' !== this.adminPassword() && '' !== this.adminPasswordNew();
}); });
this.onNewAdminPasswordResponse = _.bind(this.onNewAdminPasswordResponse, this);
} }
Utils.addSettingsViewModel(AdminSecurity, 'AdminSettingsSecurity', 'Security', 'security'); Utils.addSettingsViewModel(AdminSecurity, 'AdminSettingsSecurity', 'Security', 'security');
@ -6371,6 +6454,15 @@ AdminAjaxRemoteStorage.prototype.testConnectionForDomain = function (fCallback,
}); });
}; };
/**
* @param {?Function} fCallback
* @param {?} oData
*/
AdminAjaxRemoteStorage.prototype.testContacts = function (fCallback, oData)
{
this.defaultRequest(fCallback, 'AdminContactsTest', oData);
};
/** /**
* @param {?Function} fCallback * @param {?Function} fCallback
* @param {?} oData * @param {?} oData

File diff suppressed because one or more lines are too long

View file

@ -1013,9 +1013,10 @@ Utils.removeSelection = function ()
/** /**
* @param {string} sPrefix * @param {string} sPrefix
* @param {string} sSubject * @param {string} sSubject
* @param {boolean=} bFixLongSubject = true
* @return {string} * @return {string}
*/ */
Utils.replySubjectAdd = function (sPrefix, sSubject) Utils.replySubjectAdd = function (sPrefix, sSubject, bFixLongSubject)
{ {
var var
oMatch = null, oMatch = null,
@ -1037,7 +1038,47 @@ Utils.replySubjectAdd = function (sPrefix, sSubject)
sResult = sPrefix + ': ' + sSubject; sResult = sPrefix + ': ' + sSubject;
} }
return sResult; sResult = sResult.replace(/[\s]+/g, ' ');
return (Utils.isUnd(bFixLongSubject) ? true : bFixLongSubject) ? Utils.fixLongSubject(sResult) : sResult;
};
/**
* @param {string} sSubject
* @return {string}
*/
Utils.fixLongSubject = function (sSubject)
{
var
iCounter = 0,
oMatch = null
;
sSubject = Utils.trim(sSubject.replace(/[\s]+/, ' '));
do
{
oMatch = /^Re(\[([\d]+)\]|):[\s]{0,3}Re(\[([\d]+)\]|):/ig.exec(sSubject);
window.console.log(sSubject);
window.console.log(oMatch);
if (!oMatch || Utils.isUnd(oMatch[0]))
{
oMatch = null;
}
if (oMatch)
{
iCounter = 0;
iCounter += Utils.isUnd(oMatch[2]) ? 1 : 0 + Utils.pInt(oMatch[2]);
iCounter += Utils.isUnd(oMatch[4]) ? 1 : 0 + Utils.pInt(oMatch[4]);
sSubject = sSubject.replace(/^Re(\[[\d]+\]|):[\s]{0,3}Re(\[[\d]+\]|):/gi, 'Re' + (0 < iCounter ? '[' + iCounter + ']' : '') + ':');
}
}
while (oMatch);
sSubject = sSubject.replace(/[\s]+/, ' ');
return sSubject;
}; };
/** /**

File diff suppressed because one or more lines are too long