diff --git a/dev/Admin/Contacts.js b/dev/Admin/Contacts.js index 3cee6be7e..f494848b4 100644 --- a/dev/Admin/Contacts.js +++ b/dev/Admin/Contacts.js @@ -17,10 +17,52 @@ function AdminContacts() this.pdoDsnTrigger = ko.observable(Enums.SaveSettingsStep.Idle); this.pdoUserTrigger = 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'); +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 () { var self = this; diff --git a/dev/Admin/Security.js b/dev/Admin/Security.js index 2511343a3..3c7f3f38f 100644 --- a/dev/Admin/Security.js +++ b/dev/Admin/Security.js @@ -24,8 +24,6 @@ function AdminSecurity() this.adminPasswordUpdateSuccess(false); }, this); - this.onNewAdminPasswordResponse = _.bind(this.onNewAdminPasswordResponse, this); - this.saveNewAdminPasswordCommand = Utils.createCommand(this, function () { this.adminPasswordUpdateError(false); @@ -39,6 +37,8 @@ function AdminSecurity() }, function () { return '' !== this.adminPassword() && '' !== this.adminPasswordNew(); }); + + this.onNewAdminPasswordResponse = _.bind(this.onNewAdminPasswordResponse, this); } Utils.addSettingsViewModel(AdminSecurity, 'AdminSettingsSecurity', 'Security', 'security'); diff --git a/dev/Common/Utils.js b/dev/Common/Utils.js index e7e0b6664..7fa5ea747 100644 --- a/dev/Common/Utils.js +++ b/dev/Common/Utils.js @@ -492,7 +492,7 @@ Utils.fixLongSubject = function (sSubject) sSubject = sSubject.replace(/[\s]+/, ' '); return sSubject; -} +}; /** * @param {number} iNum diff --git a/dev/Storages/AdminAjaxRemote.js b/dev/Storages/AdminAjaxRemote.js index 661449869..0349e6602 100644 --- a/dev/Storages/AdminAjaxRemote.js +++ b/dev/Storages/AdminAjaxRemote.js @@ -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 {?} oData diff --git a/dev/Styles/MessageList.less b/dev/Styles/MessageList.less index 93a2403c1..a3ab09df9 100644 --- a/dev/Styles/MessageList.less +++ b/dev/Styles/MessageList.less @@ -36,7 +36,7 @@ html.rl-no-preview-pane { .e-quota { display: inline-block; - margin-left: 10px; + margin-top: 5px; font-size: 18px; cursor: help; } diff --git a/dev/Styles/_InputosaurusFix.less b/dev/Styles/_InputosaurusFix.less index ae5fbcab0..c8b9ab275 100644 --- a/dev/Styles/_InputosaurusFix.less +++ b/dev/Styles/_InputosaurusFix.less @@ -32,6 +32,10 @@ } } + span { + padding-right: 3px; + } + &.inputosaurus-required { padding-rigth: 5px; } diff --git a/rainloop/v/0.0.0/app/libraries/MailSo/Log/Logger.php b/rainloop/v/0.0.0/app/libraries/MailSo/Log/Logger.php index cdb01ce8e..9e50fd30d 100644 --- a/rainloop/v/0.0.0/app/libraries/MailSo/Log/Logger.php +++ b/rainloop/v/0.0.0/app/libraries/MailSo/Log/Logger.php @@ -222,7 +222,7 @@ class Logger extends \MailSo\Base\Collection */ 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 ($mData instanceof \Exception) diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php index c5a2977c3..5b81994c0 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php @@ -228,15 +228,13 @@ class Actions break; case 'personal-address-book': // \RainLoop\Providers\PersonalAddressBook\PersonalAddressBookInterface - if ($this->Config()->Get('contacts', 'enable', false)) - { - $sDsn = \trim($this->Config()->Get('contacts', 'pdo_dsn', '')); - $sUser = \trim($this->Config()->Get('contacts', 'pdo_user', '')); - $sPassword = (string) $this->Config()->Get('contacts', 'pdo_password', ''); + + $sDsn = \trim($this->Config()->Get('contacts', 'pdo_dsn', '')); + $sUser = \trim($this->Config()->Get('contacts', 'pdo_user', '')); + $sPassword = (string) $this->Config()->Get('contacts', 'pdo_password', ''); - $oResult = new \RainLoop\Providers\PersonalAddressBook\MySqlPersonalAddressBook($sDsn, $sUser, $sPassword); - $oResult->SetLogger($this->Logger()); - } + $oResult = new \RainLoop\Providers\PersonalAddressBook\PdoPersonalAddressBook($sDsn, $sUser, $sPassword); + $oResult->SetLogger($this->Logger()); break; case 'suggestions': // \RainLoop\Providers\Suggestions\SuggestionsInterface @@ -541,31 +539,19 @@ class Actions } /** + * @param \RainLoop\Account $oAccount = null + * @param bool $bForceEnable = false + * * @return \RainLoop\Providers\PersonalAddressBook */ - public function PersonalAddressBookProvider($oAccount = null) + public function PersonalAddressBookProvider($oAccount = null, $bForceEnable = false) { if (null === $this->oPersonalAddressBookProvider) { $this->oPersonalAddressBookProvider = new \RainLoop\Providers\PersonalAddressBook( - $this->fabrica('personal-address-book', $oAccount)); - - $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); - } - } + $this->Config()->Get('contacts', 'enable', false) || $bForceEnable ? $this->fabrica('personal-address-book', $oAccount) : null); } - - if ($oAccount) + else if ($oAccount && $this->oPersonalAddressBookProvider->IsSupported()) { $this->oPersonalAddressBookProvider->SetAccount($oAccount); } @@ -1035,7 +1021,7 @@ class Actions $aResult['DesktopNotifications'] = false; $aResult['UseThreads'] = false; $aResult['ReplySameFolder'] = false; - $aResult['UsePreviewPane'] = true; + $aResult['UsePreviewPane'] = (bool) $oConfig->Get('webmail', 'use_preview_pane', true); $aResult['UseCheckboxesInList'] = true; $aResult['DisplayName'] = ''; $aResult['ReplyTo'] = ''; @@ -1941,6 +1927,22 @@ class Actions 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 */ @@ -4026,7 +4028,7 @@ class Actions { $iCount = 0; $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( diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Common/PdoAbstract.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Common/PdoAbstract.php index 7d9ef2e68..f8e989c8c 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Common/PdoAbstract.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Common/PdoAbstract.php @@ -209,13 +209,14 @@ abstract class PdoAbstract { 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 bool $bSkipInsert = false + * @param bool $bSkipUpdateTables = false * * @return int */ @@ -226,7 +227,7 @@ abstract class PdoAbstract { throw new \InvalidArgumentException('Empty Email argument'); } - + $oStmt = $this->prepareAndExecute('SELECT id_user FROM rainloop_users WHERE rl_email = :rl_email', array(':rl_email' => array($sEmail, \PDO::PARAM_STR))); @@ -271,17 +272,28 @@ abstract class PdoAbstract $oPdo = $this->getPDO(); 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); $oStmt = $oPdo->prepare($sQuery); if ($oStmt->execute(array($sName))) { $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 bool $bReturnIntValue = true * * @return int|string|bool */ @@ -356,18 +367,37 @@ abstract class PdoAbstract $aQ = array(); if ('mysql' === $this->sDbType) { - $aQ[] = 'CREATE TABLE IF NOT EXISTS `rainloop_system` ( - `sys_name` varchar(50) NOT NULL, - `value_int` int(11) UNSIGNED NOT NULL DEFAULT \'0\', - `value_str` varchar(255) NOT NULL DEFAULT \'\' + $aQ[] = 'CREATE TABLE IF NOT EXISTS rainloop_system ( + sys_name varchar(50) NOT NULL, + value_int int(11) UNSIGNED NOT NULL DEFAULT \'0\', + value_str varchar(128) NOT NULL DEFAULT \'\', + INDEX `sys_name_index` (`sys_name`) ) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;'; - $aQ[] = 'CREATE TABLE IF NOT EXISTS `rainloop_users` ( - `id_user` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, - `rl_email` varchar(255) NOT NULL, - UNIQUE `email_unique` (`rl_email`), - PRIMARY KEY(`id_user`) -) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET ascii COLLATE ascii_general_ci */;'; + $aQ[] = 'CREATE TABLE IF NOT EXISTS rainloop_users ( + id_user int(11) UNSIGNED NOT NULL AUTO_INCREMENT, + rl_email varchar(128) NOT NULL DEFAULT \'\', + PRIMARY KEY(`id_user`), + INDEX `rl_email_index` (`rl_email`) +) /*!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)) @@ -398,7 +428,7 @@ abstract class PdoAbstract { $oPdo->rollBack(); - $this->oLogger->WriteException($oException); + $this->writeLog($oException); throw $oException; } } @@ -415,23 +445,38 @@ abstract class PdoAbstract */ protected function dataBaseUpgrade($sName, $aData = array()) { - $this->initSystemTables(); - - $iFromVersion = $this->getVersion($sName); - - $bResult = false; - $oPdo = $this->getPDO(); - if ($oPdo) + $iFromVersion = null; + try { - $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) { - if ($iFromVersion < $iVersion) + if (!$oPdo) + { + $oPdo = $this->getPDO(); + $bResult = true; + } + + if ($iFromVersion < $iVersion && $oPdo) { try { $oPdo->beginTransaction(); - + foreach ($aQuery as $sQuery) { $this->writeLog($sQuery); @@ -461,7 +506,7 @@ abstract class PdoAbstract { break; } - + $this->setVersion($sName, $iVersion); } } diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/PersonalAddressBook.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/PersonalAddressBook.php index d84922d36..c00fe194a 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/PersonalAddressBook.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/PersonalAddressBook.php @@ -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 ? - $this->oDriver->Version() : 'null'; + $this->oDriver->Test() : false; } /** @@ -77,16 +78,16 @@ class PersonalAddressBook extends \RainLoop\Providers\AbstractProvider * @param int $iOffset = 0 * @param type $iLimit = 20 * @param string $sSearch = '' - * @param bool $bAutoOnly = false + * @param int $iScopeType = \RainLoop\Providers\PersonalAddressBook\Enumerations\ScopeType::DEFAULT_ * @param int $iResultCount = 0 * * @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) { 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 bool - */ - public function SynchronizeStorage() - { - return $this->IsActive() && \method_exists($this->oDriver, 'SynchronizeStorage') && - $this->oDriver->SynchronizeStorage(); - } -} \ No newline at end of file +} diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/PersonalAddressBook/Classes/Contact.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/PersonalAddressBook/Classes/Contact.php index ad04a092c..24d85c58a 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/PersonalAddressBook/Classes/Contact.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/PersonalAddressBook/Classes/Contact.php @@ -25,25 +25,15 @@ class Contact public $DisplayEmail; /** - * @var bool + * @var int */ - public $Auto; - - /** - * @var bool - */ - public $Shared; + public $ScopeType; /** * @var int */ public $Changed; - /** - * @var array - */ - public $Tags; - /** * @var int */ @@ -66,10 +56,8 @@ class Contact $this->Display = ''; $this->DisplayName = ''; $this->DisplayEmail = ''; - $this->Auto = false; - $this->Shared = false; + $this->ScopeType = \RainLoop\Providers\PersonalAddressBook\Enumerations\ScopeType::DEFAULT_; $this->Changed = \time(); - $this->Tags = array(); $this->IdPropertyFromSearch = 0; $this->Properties = array(); } @@ -83,6 +71,7 @@ class Contact { if ($oProperty) { + $oProperty->ScopeType = $this->ScopeType; $oProperty->UpdateDependentValues(); if ('' === $sDisplayName && \RainLoop\Providers\PersonalAddressBook\Enumerations\PropertyType::FULLNAME === $oProperty->Type && diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/PersonalAddressBook/Classes/Property.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/PersonalAddressBook/Classes/Property.php index e258d9aeb..919ebfc77 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/PersonalAddressBook/Classes/Property.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/PersonalAddressBook/Classes/Property.php @@ -16,6 +16,11 @@ class Property */ public $Type; + /** + * @var int + */ + public $ScopeType; + /** * @var string */ @@ -46,6 +51,7 @@ class Property $this->IdProperty = 0; $this->Type = PropertyType::UNKNOWN; + $this->ScopeType = \RainLoop\Providers\PersonalAddressBook\Enumerations\ScopeType::DEFAULT_; $this->TypeCustom = ''; $this->Value = ''; diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/PersonalAddressBook/Enumerations/ScopeType.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/PersonalAddressBook/Enumerations/ScopeType.php new file mode 100644 index 000000000..d4d31a23e --- /dev/null +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/PersonalAddressBook/Enumerations/ScopeType.php @@ -0,0 +1,10 @@ +Sync(); $iUserID = $this->getUserId($oAccount->ParentEmailHelper()); + $iIdContact = \strlen($oContact->IdContact) && \is_numeric($oContact->IdContact) ? (int) $oContact->IdContact : 0; $bUpdate = 0 < $iIdContact; @@ -57,7 +59,7 @@ class MySqlPersonalAddressBook $oContact->UpdateDependentValues(); $oContact->Changed = \time(); - if (!$oContact->Auto) + if (\RainLoop\Providers\PersonalAddressBook\Enumerations\ScopeType::AUTO !== $oContact->ScopeType) { $aEmail = $oContact->GetEmails(); if (0 < \count($aEmail)) @@ -80,8 +82,9 @@ class MySqlPersonalAddressBook // clear autocreated contacts $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( + ':scope_type' => array(\RainLoop\Providers\PersonalAddressBook\Enumerations\ScopeType::AUTO, \PDO::PARAM_INT), ':id_user' => array($iUserID, \PDO::PARAM_INT) ) ); @@ -98,8 +101,8 @@ class MySqlPersonalAddressBook { $aFreq = $this->getContactFreq($iUserID, $iIdContact); - $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'; + $sSql = 'UPDATE rainloop_pab_contacts SET display = :display, display_name = :display_name, display_email = :display_email, '. + 'scope_type = :scope_type, changed = :changed WHERE id_user = :id_user AND id_contact = :id_contact'; $this->prepareAndExecute($sSql, array( @@ -108,15 +111,14 @@ class MySqlPersonalAddressBook ':display' => array($oContact->Display, \PDO::PARAM_STR), ':display_name' => array($oContact->DisplayName, \PDO::PARAM_STR), ':display_email' => array($oContact->DisplayEmail, \PDO::PARAM_STR), - ':auto' => array($oContact->Auto, \PDO::PARAM_INT), - ':shared' => array($oContact->Shared, \PDO::PARAM_INT), + ':scope_type' => array($oContact->ScopeType, \PDO::PARAM_INT), ':changed' => array($oContact->Changed, \PDO::PARAM_INT), ) ); // clear previos props $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( ':id_user' => array($iUserID, \PDO::PARAM_INT), ':id_contact' => array($iIdContact, \PDO::PARAM_INT) @@ -125,9 +127,9 @@ class MySqlPersonalAddressBook } else { - $sSql = 'INSERT INTO `rainloop_pab_contacts` '. - '(`id_user`, `display`, `display_name`, `display_email`, `auto`, `shared`, `changed`) VALUES '. - '(:id_user, :display, :display_name, :display_email, :auto, :shared, :changed)'; + $sSql = 'INSERT INTO rainloop_pab_contacts '. + '( id_user, display, display_name, display_email, scope_type, changed) VALUES '. + '(:id_user, :display, :display_name, :display_email, :scope_type, :changed)'; $this->prepareAndExecute($sSql, array( @@ -135,8 +137,7 @@ class MySqlPersonalAddressBook ':display' => array($oContact->Display, \PDO::PARAM_STR), ':display_name' => array($oContact->DisplayName, \PDO::PARAM_STR), ':display_email' => array($oContact->DisplayEmail, \PDO::PARAM_STR), - ':auto' => array($oContact->Auto, \PDO::PARAM_INT), - ':shared' => array($oContact->Shared, \PDO::PARAM_INT), + ':scope_type' => array($oContact->ScopeType, \PDO::PARAM_INT), ':changed' => array($oContact->Changed, \PDO::PARAM_INT) ) ); @@ -163,19 +164,18 @@ class MySqlPersonalAddressBook $aParams[] = array( ':id_contact' => array($iIdContact, \PDO::PARAM_INT), ':id_user' => array($iUserID, \PDO::PARAM_INT), - ':type' => array($oProp->Type, \PDO::PARAM_INT), - ':type_custom' => array($oProp->TypeCustom, \PDO::PARAM_STR), - ':value' => array($oProp->Value, \PDO::PARAM_STR), - ':value_custom' => array($oProp->ValueClear, \PDO::PARAM_STR), - ':auto' => array($oContact->Auto, \PDO::PARAM_INT), - ':shared' => array($oContact->Shared, \PDO::PARAM_INT), - ':frec' => array($iFreq, \PDO::PARAM_INT), + ':scope_type' => array($oContact->ScopeType, \PDO::PARAM_INT), + ':prop_type' => array($oProp->Type, \PDO::PARAM_INT), + ':prop_type_custom' => array($oProp->TypeCustom, \PDO::PARAM_STR), + ':prop_value' => array($oProp->Value, \PDO::PARAM_STR), + ':prop_value_custom' => array($oProp->ValueClear, \PDO::PARAM_STR), + ':prop_frec' => array($iFreq, \PDO::PARAM_INT), ); } - $sSql = 'INSERT INTO `rainloop_pab_properties` '. - '(`id_contact`, `id_user`, `type`, `type_custom`, `value`, `value_custom`, `auto`, `shared`, `frec`) VALUES '. - '(:id_contact, :id_user, :type, :type_custom, :value, :value_custom, :auto, :shared, :frec)'; + $sSql = 'INSERT INTO rainloop_pab_properties '. + '( id_contact, id_user, prop_type, prop_type_custom, prop_value, prop_value_custom, scope_type, prop_frec) VALUES '. + '(:id_contact, :id_user, :prop_type, :prop_type_custom, :prop_value, :prop_value_custom, :scope_type, :prop_frec)'; $this->prepareAndExecute($sSql, $aParams, true); } @@ -199,6 +199,7 @@ class MySqlPersonalAddressBook */ public function DeleteContacts($oAccount, $aContactIds) { + $this->Sync(); $iUserID = $this->getUserId($oAccount->ParentEmailHelper()); $aContactIds = \array_filter($aContactIds, function (&$mItem) { @@ -214,9 +215,9 @@ class MySqlPersonalAddressBook $sIDs = \implode(',', $aContactIds); $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_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_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_contacts WHERE id_user = :id_user AND id_contact IN ('.$sIDs.')', $aParams); return true; } @@ -229,6 +230,7 @@ class MySqlPersonalAddressBook */ public function DeleteTags($oAccount, $aTagsIds) { + $this->Sync(); $iUserID = $this->getUserId($oAccount->ParentEmailHelper()); $aTagsIds = \array_filter($aTagsIds, function (&$mItem) { @@ -244,8 +246,8 @@ class MySqlPersonalAddressBook $sIDs = \implode(',', $aTagsIds); $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` WHERE `id_user` = :id_user AND `id_tag` IN ('.$sIDs.')', $aParams); + $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); return true; } @@ -255,13 +257,16 @@ class MySqlPersonalAddressBook * @param int $iOffset = 0 * @param int $iLimit = 20 * @param string $sSearch = '' - * @param bool $bAutoOnly = false + * @param bool $iScopeType = \RainLoop\Providers\PersonalAddressBook\Enumerations\ScopeType::DEFAULT_ * @param int $iResultCount = 0 * * @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; $iLimit = 0 < $iLimit ? (int) $iLimit : 20; $sSearch = \trim($sSearch); @@ -274,10 +279,10 @@ class MySqlPersonalAddressBook 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( ':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) ); @@ -303,10 +308,10 @@ class MySqlPersonalAddressBook } 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( ':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); @@ -324,18 +329,18 @@ class MySqlPersonalAddressBook 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( ':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)) { - $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[':offset'] = array($iOffset, \PDO::PARAM_INT); @@ -360,8 +365,10 @@ class MySqlPersonalAddressBook $oContact->Display = isset($aItem['display']) ? (string) $aItem['display'] : ''; $oContact->DisplayName = isset($aItem['display_name']) ? (string) $aItem['display_name'] : ''; $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->IdPropertyFromSearch = isset($aPropertyFromSearchIds[$iIdContact]) && 0 < $aPropertyFromSearchIds[$iIdContact] ? $aPropertyFromSearchIds[$iIdContact] : 0; @@ -376,7 +383,7 @@ class MySqlPersonalAddressBook { $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( ':id_user' => array($iUserID, \PDO::PARAM_INT) )); @@ -388,18 +395,20 @@ class MySqlPersonalAddressBook { 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']; if (0 < $iId && isset($aContacts[$iId])) { $oProperty = new \RainLoop\Providers\PersonalAddressBook\Classes\Property(); $oProperty->IdProperty = (int) $aItem['id_prop']; - $oProperty->Type = (int) $aItem['type']; - $oProperty->TypeCustom = isset($aItem['type_custom']) ? (string) $aItem['type_custom'] : ''; - $oProperty->Value = (string) $aItem['value']; - $oProperty->ValueClear = isset($aItem['value_clear']) ? (string) $aItem['value_clear'] : ''; - $oProperty->Frec = isset($aItem['frec']) ? (int) $aItem['frec'] : 0; + $oProperty->ScopeType = isset($aItem['scope_type']) ? (int) $aItem['scope_type'] : + \RainLoop\Providers\PersonalAddressBook\Enumerations\ScopeType::DEFAULT_; + $oProperty->Type = (int) $aItem['prop_type']; + $oProperty->TypeCustom = isset($aItem['prop_type_custom']) ? (string) $aItem['prop_type_custom'] : ''; + $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; } @@ -440,14 +449,15 @@ class MySqlPersonalAddressBook throw new \InvalidArgumentException('Empty Search argument'); } + $this->Sync(); $iUserID = $this->getUserId($oAccount->ParentEmailHelper()); $sTypes = implode(',', array( PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES, PropertyType::EMAIl_OTHER, PropertyType::FULLNAME )); - $sSql = 'SELECT `id_contact`, `id_prop`, `type`, `value` FROM `rainloop_pab_properties` '. - 'WHERE id_user = :id_user AND `type` IN ('.$sTypes.') AND `value` LIKE :search ESCAPE \'=\''; + $sSql = 'SELECT id_contact, id_prop, prop_type, prop_value FROM rainloop_pab_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), @@ -455,7 +465,7 @@ class MySqlPersonalAddressBook ':search' => array($this->specialConvertSearchValue($sSearch, '='), \PDO::PARAM_STR) ); - $sSql .= ' ORDER BY `frec` DESC'; + $sSql .= ' ORDER BY prop_frec DESC'; $sSql .= ' LIMIT :limit'; $aResult = array(); @@ -475,7 +485,7 @@ class MySqlPersonalAddressBook if (0 < $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))) { @@ -489,8 +499,8 @@ class MySqlPersonalAddressBook $aFirstResult[] = array( 'id_prop' => isset($aItem['id_prop']) ? (int) $aItem['id_prop'] : 0, 'id_contact' => $iIdContact, - 'value' => isset($aItem['value']) ? (string) $aItem['value'] : '', - 'type' => $iType + 'prop_value' => isset($aItem['prop_value']) ? (string) $aItem['prop_value'] : '', + 'prop_type' => $iType ); } } @@ -509,8 +519,8 @@ class MySqlPersonalAddressBook PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES, PropertyType::EMAIl_OTHER, PropertyType::FULLNAME )); - $sSql = 'SELECT `id_prop`, `id_contact`, `type`, `value` FROM `rainloop_pab_properties` '. - 'WHERE id_user = :id_user AND `type` IN ('.$sTypes.') AND `id_contact` IN ('.\implode(',', $aIdContacts).')'; + $sSql = 'SELECT id_prop, id_contact, prop_type, prop_value FROM rainloop_pab_properties '. + 'WHERE id_user = :id_user AND prop_type IN ('.$sTypes.') AND id_contact IN ('.\implode(',', $aIdContacts).')'; $oStmt = $this->prepareAndExecute($sSql, array( ':id_user' => array($iUserID, \PDO::PARAM_INT) @@ -525,14 +535,14 @@ class MySqlPersonalAddressBook 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']; - $iType = (int) $aItem['type']; + $iType = (int) $aItem['prop_type']; if (PropertyType::FULLNAME === $iType) { - $aNames[$iIdContact] = $aItem['value']; + $aNames[$iIdContact] = $aItem['prop_value']; } else if (\in_array($iType, array(PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES, PropertyType::EMAIl_OTHER))) @@ -542,17 +552,17 @@ class MySqlPersonalAddressBook $aEmails[$iIdContact] = array(); } - $aEmails[$iIdContact][] = $aItem['value']; + $aEmails[$iIdContact][] = $aItem['prop_value']; } } } foreach ($aFirstResult as $aItem) { - if ($aItem && !empty($aItem['value'])) + if ($aItem && !empty($aItem['prop_value'])) { $iIdContact = (int) $aItem['id_contact']; - $iType = (int) $aItem['type']; + $iType = (int) $aItem['prop_type']; if (PropertyType::FULLNAME === $iType) { @@ -562,7 +572,7 @@ class MySqlPersonalAddressBook { 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, 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] : ''); } } @@ -601,8 +611,6 @@ class MySqlPersonalAddressBook */ public function IncFrec($oAccount, $aEmails, $bCreateAuto = true) { - $iUserID = $this->getUserId($oAccount->ParentEmailHelper()); - $self = $this; $aEmailsObjects = \array_map(function ($mItem) { $oResult = null; @@ -619,6 +627,9 @@ class MySqlPersonalAddressBook throw new \InvalidArgumentException('Empty Emails argument'); } + $this->Sync(); + $iUserID = $this->getUserId($oAccount->ParentEmailHelper()); + $sTypes = \implode(',', array( PropertyType::EMAIl_PERSONAL, PropertyType::EMAIl_BUSSINES, PropertyType::EMAIl_OTHER )); @@ -629,7 +640,7 @@ class MySqlPersonalAddressBook 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( ':id_user' => array($iUserID, \PDO::PARAM_INT) )); @@ -641,9 +652,9 @@ class MySqlPersonalAddressBook { 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(); foreach ($aEmailsToCreate as $oEmail) { - $oContact->Auto = true; + $oContact->ScopeType = \RainLoop\Providers\PersonalAddressBook\Enumerations\ScopeType::AUTO; if ('' !== \trim($oEmail->GetEmail())) { $oPropEmail = new \RainLoop\Providers\PersonalAddressBook\Classes\Property(); + $oPropEmail->ScopeType = $oContact->ScopeType; $oPropEmail->Type = \RainLoop\Providers\PersonalAddressBook\Enumerations\PropertyType::EMAIl_PERSONAL; $oPropEmail->Value = \strtolower(\trim($oEmail->GetEmail())); @@ -699,6 +711,7 @@ class MySqlPersonalAddressBook if ('' !== \trim($oEmail->GetDisplayName())) { $oPropName = new \RainLoop\Providers\PersonalAddressBook\Classes\Property(); + $oPropName->ScopeType = $oContact->ScopeType; $oPropName->Type = \RainLoop\Providers\PersonalAddressBook\Enumerations\PropertyType::FULLNAME; $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) { return $self->quoteValue($mItem); @@ -722,11 +735,11 @@ class MySqlPersonalAddressBook if (1 === \count($aEmailsQuoted)) { - $sSql .= ') AND `value` = '.$aEmailsQuoted[0]; + $sSql .= ') AND prop_value = '.$aEmailsQuoted[0]; } else { - $sSql .= ') AND `value` IN ('.\implode(',', $aEmailsQuoted).')'; + $sSql .= ') AND prop_value IN ('.\implode(',', $aEmailsQuoted).')'; } return !!$this->prepareAndExecute($sSql, array( @@ -737,77 +750,78 @@ class MySqlPersonalAddressBook /** * @return string */ - public function Version() + public function Test() { - return 'MySqlPersonalAddressBookDriver-v14'; + $this->Sync(); + return 0 < $this->getVersion('mysql-pab-version'); } - + /** * @return bool */ - public function SynchronizeStorage() + public function Sync() { return $this->dataBaseUpgrade('mysql-pab-version', array( 1 => array( // -- 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_user` int(11) UNSIGNED NOT NULL, - `display` varchar(255) NOT NULL DEFAULT \'\', - `display_name` varchar(255) NOT NULL DEFAULT \'\', - `display_email` varchar(255) NOT NULL DEFAULT \'\', - `auto` int(1) UNSIGNED NOT NULL DEFAULT \'0\', - `shared` int(1) UNSIGNED NOT NULL DEFAULT \'0\', - `changed` int(11) UNSIGNED NOT NULL DEFAULT \'0\', + id_contact int(11) UNSIGNED NOT NULL AUTO_INCREMENT, + id_user int(11) UNSIGNED NOT NULL, + scope_type int(4) UNSIGNED NOT NULL DEFAULT 0, + display_name varchar(255) NOT NULL DEFAULT \'\', + display_email varchar(255) NOT NULL DEFAULT \'\', + display varchar(255) NOT NULL DEFAULT \'\', + changed int(11) UNSIGNED NOT NULL DEFAULT 0, - PRIMARY KEY(`id_contact`), - INDEX `id_user_index` (`id_user`) + PRIMARY KEY(id_contact), + 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 -- -'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_contact` int(11) UNSIGNED NOT NULL, - `id_user` int(11) UNSIGNED NOT NULL, - `type` int(11) UNSIGNED NOT NULL, - `type_custom` varchar(50) /*!40101 CHARACTER SET ascii COLLATE ascii_general_ci */ NOT NULL DEFAULT \'\', - `value` varchar(255) NOT NULL DEFAULT \'\', - `value_custom` varchar(255) NOT NULL DEFAULT \'\', - `auto` int(1) UNSIGNED NOT NULL DEFAULT \'0\', - `shared` int(1) UNSIGNED NOT NULL DEFAULT \'0\', - `frec` int(11) UNSIGNED NOT NULL DEFAULT \'0\', + id_prop int(11) UNSIGNED NOT NULL AUTO_INCREMENT, + id_contact int(11) UNSIGNED NOT NULL, + id_user int(11) UNSIGNED NOT NULL, + scope_type int(4) UNSIGNED NOT NULL DEFAULT 0, + prop_type int(11) UNSIGNED NOT NULL, + prop_type_custom varchar(50) /*!40101 CHARACTER SET ascii COLLATE ascii_general_ci */ NOT NULL DEFAULT \'\', + prop_value varchar(255) NOT NULL DEFAULT \'\', + prop_value_custom varchar(255) NOT NULL DEFAULT \'\', + prop_frec int(11) UNSIGNED NOT NULL DEFAULT 0, - PRIMARY KEY(`id_prop`), - INDEX `id_user_index` (`id_user`), - INDEX `id_user_id_contact_index` (`id_user`, `id_contact`) + PRIMARY KEY(id_prop), + INDEX id_user_index (id_user), + 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 -- -'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_user` int(11) UNSIGNED NOT NULL, - `name` varchar(255) NOT NULL, + id_tag int(11) UNSIGNED NOT NULL AUTO_INCREMENT, + id_user int(11) UNSIGNED NOT NULL, + tag_name varchar(255) NOT NULL, - PRIMARY KEY(`id_tag`), - INDEX `id_user_index` (`id_user`) + PRIMARY KEY(id_tag), + 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 -- -'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_contact` int(11) UNSIGNED NOT NULL, + id_tag 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 )); - $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( ':id_user' => array($iUserID, \PDO::PARAM_INT), ':id_contact' => array($iIdContact, \PDO::PARAM_INT) @@ -838,9 +852,9 @@ class MySqlPersonalAddressBook { 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']; } } } diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/PersonalAddressBook/PersonalAddressBookInterface.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/PersonalAddressBook/PersonalAddressBookInterface.php index 82eb513b1..c8f5887f4 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/PersonalAddressBook/PersonalAddressBookInterface.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/PersonalAddressBook/PersonalAddressBookInterface.php @@ -4,11 +4,6 @@ namespace RainLoop\Providers\PersonalAddressBook; interface PersonalAddressBookInterface { - /** - * @return string - */ - public function Version(); - /** * @return bool */ @@ -41,15 +36,15 @@ interface PersonalAddressBookInterface /** * @param \RainLoop\Account $oAccount * @param int $iOffset = 0 - * @param type $iLimit = 20 + * @param int $iLimit = 20 * @param string $sSearch = '' - * @param bool $bAutoOnly = false + * @param bool $iScopeType = \RainLoop\Providers\PersonalAddressBook\Enumerations\ScopeType::DEFAULT_ * @param int $iResultCount = 0 * * @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); /** * @param \RainLoop\Account $oAccount diff --git a/rainloop/v/0.0.0/app/templates/Views/AdminSettingsContacts.html b/rainloop/v/0.0.0/app/templates/Views/AdminSettingsContacts.html index 05cd37709..7d3cacc1e 100644 --- a/rainloop/v/0.0.0/app/templates/Views/AdminSettingsContacts.html +++ b/rainloop/v/0.0.0/app/templates/Views/AdminSettingsContacts.html @@ -20,9 +20,12 @@ +
+ PDO (MySQL) +
@@ -31,7 +34,7 @@
@@ -40,12 +43,21 @@
+
\ No newline at end of file diff --git a/rainloop/v/0.0.0/app/templates/Views/MailMessageList.html b/rainloop/v/0.0.0/app/templates/Views/MailMessageList.html index bc8b917e4..1a044196f 100644 --- a/rainloop/v/0.0.0/app/templates/Views/MailMessageList.html +++ b/rainloop/v/0.0.0/app/templates/Views/MailMessageList.html @@ -2,6 +2,11 @@
@@ -144,9 +152,11 @@