diff --git a/dev/Settings/Admin/About.js b/dev/Settings/Admin/About.js index 0c8fb7a3e..acba4c6b4 100644 --- a/dev/Settings/Admin/About.js +++ b/dev/Settings/Admin/About.js @@ -35,6 +35,7 @@ this.coreVersionCompare = CoreStore.coreVersionCompare; this.coreRemoteVersionHtmlDesc = ko.computed(function () { + Translator.trigger(); return Translator.i18n('TAB_ABOUT/HTML_NEW_VERSION', {'VERSION': this.coreRemoteVersion()}); }, this); 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 c86096688..5f2fdb26d 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php @@ -235,74 +235,77 @@ class Actions */ private function fabrica($sName, $oAccount = null) { - $oResult = null; + $mResult = null; $this->Plugins() - ->RunHook('main.fabrica', array($sName, &$oResult), false) - ->RunHook('main.fabrica[2]', array($sName, &$oResult, $oAccount), false) + ->RunHook('main.fabrica', array($sName, &$mResult), false) + ->RunHook('main.fabrica[2]', array($sName, &$mResult, $oAccount), false) ; - if (null === $oResult) + if (null === $mResult) { switch ($sName) { case 'files': // RainLoop\Providers\Files\IFiles - $oResult = new \RainLoop\Providers\Files\FileStorage(APP_PRIVATE_DATA.'storage/files'); + $mResult = new \RainLoop\Providers\Files\FileStorage(APP_PRIVATE_DATA.'storage/files'); break; case 'storage': case 'storage-local': // RainLoop\Providers\Storage\IStorage - $oResult = new \RainLoop\Providers\Storage\FileStorage( + $mResult = new \RainLoop\Providers\Storage\FileStorage( APP_PRIVATE_DATA.'storage', 'storage-local' === $sName); break; case 'settings': case 'settings-local': // RainLoop\Providers\Settings\ISettings - $oResult = new \RainLoop\Providers\Settings\DefaultSettings( + $mResult = new \RainLoop\Providers\Settings\DefaultSettings( $this->StorageProvider('settings-local' === $sName)); break; case 'login': // \RainLoop\Providers\Login\LoginInterface - $oResult = new \RainLoop\Providers\Login\DefaultLogin(); + $mResult = new \RainLoop\Providers\Login\DefaultLogin(); break; case 'domain': // \RainLoop\Providers\Domain\DomainAdminInterface - $oResult = new \RainLoop\Providers\Domain\DefaultDomain(APP_PRIVATE_DATA.'domains', $this->Cacher()); + $mResult = new \RainLoop\Providers\Domain\DefaultDomain(APP_PRIVATE_DATA.'domains', $this->Cacher()); break; case 'filters': // \RainLoop\Providers\Filters\FiltersInterface - $oResult = new \RainLoop\Providers\Filters\SieveStorage( + $mResult = new \RainLoop\Providers\Filters\SieveStorage( $this->Plugins(), $this->Config() ); break; case 'address-book': // \RainLoop\Providers\AddressBook\AddressBookInterface - if (!\RainLoop\Utils::IsOwnCloud()) // disabled for ownCloud - { - $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', ''); - $sDsnType = $this->ValidateContactPdoType(\trim($this->Config()->Get('contacts', 'type', 'sqlite'))); - if ('sqlite' === $sDsnType) - { - $oResult = new \RainLoop\Providers\AddressBook\PdoAddressBook( - 'sqlite:'.APP_PRIVATE_DATA.'AddressBook.sqlite', '', '', 'sqlite'); - } - else - { - $oResult = new \RainLoop\Providers\AddressBook\PdoAddressBook($sDsn, $sUser, $sPassword, $sDsnType); - } + $sDsnType = $this->ValidateContactPdoType(\trim($this->Config()->Get('contacts', 'type', 'sqlite'))); + if ('sqlite' === $sDsnType) + { + $mResult = new \RainLoop\Providers\AddressBook\PdoAddressBook( + 'sqlite:'.APP_PRIVATE_DATA.'AddressBook.sqlite', '', '', 'sqlite'); + } + else + { + $mResult = new \RainLoop\Providers\AddressBook\PdoAddressBook($sDsn, $sUser, $sPassword, $sDsnType); } break; case 'suggestions': - // \RainLoop\Providers\Suggestions\ISuggestions -// $oResult = new \RainLoop\Providers\Suggestions\TestSuggestions(); - if (\RainLoop\Utils::IsOwnCloud()) + if (null === $mResult) { - $oResult = new \RainLoop\Providers\Suggestions\OwnCloudSuggestions(); + $mResult = array(); + } + + // \RainLoop\Providers\Suggestions\ISuggestions +// $mResult[] = new \RainLoop\Providers\Suggestions\TestSuggestions(); + + if (\is_array($mResult) && \RainLoop\Utils::IsOwnCloud()) + { + $mResult[] = new \RainLoop\Providers\Suggestions\OwnCloudSuggestions(); } break; @@ -311,19 +314,22 @@ class Actions break; case 'two-factor-auth': // \RainLoop\Providers\TwoFactorAuth\TwoFactorAuthInterface - $oResult = new \RainLoop\Providers\TwoFactorAuth\GoogleTwoFactorAuth(); + $mResult = new \RainLoop\Providers\TwoFactorAuth\GoogleTwoFactorAuth(); break; } } - if ($oResult && \method_exists($oResult, 'SetLogger')) + foreach (\is_array($mResult) ? $mResult : array($mResult) as $oItem) { - $oResult->SetLogger($this->Logger()); + if ($oItem && \method_exists($oItem, 'SetLogger')) + { + $oItem->SetLogger($this->Logger()); + } } - $this->Plugins()->RunHook('filter.fabrica', array($sName, &$oResult, $oAccount), false); + $this->Plugins()->RunHook('filter.fabrica', array($sName, &$mResult, $oAccount), false); - return $oResult; + return $mResult; } /** @@ -827,7 +833,8 @@ class Actions { if (null === $this->oSuggestionsProvider) { - $this->oSuggestionsProvider = new \RainLoop\Providers\Suggestions($this->fabrica('suggestions')); + $this->oSuggestionsProvider = new \RainLoop\Providers\Suggestions( + $this->fabrica('suggestions')); } return $this->oSuggestionsProvider; @@ -7071,8 +7078,7 @@ class Actions $oSuggestionsProvider = $this->SuggestionsProvider(); if ($oSuggestionsProvider && $oSuggestionsProvider->IsActive()) { - $iSuggestionLimit = $iLimit - \count($aResult); - $aSuggestionsProviderResult = $oSuggestionsProvider->Process($oAccount, $sQuery, $iSuggestionLimit); + $aSuggestionsProviderResult = $oSuggestionsProvider->Process($oAccount, $sQuery, $iLimit); if (\is_array($aSuggestionsProviderResult) && 0 < \count($aSuggestionsProviderResult)) { $aResult = \array_merge($aResult, $aSuggestionsProviderResult); diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/Suggestions.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/Suggestions.php index d4b5b27bc..13cc8cbe9 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/Suggestions.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/Suggestions.php @@ -5,31 +5,72 @@ namespace RainLoop\Providers; class Suggestions extends \RainLoop\Providers\AbstractProvider { /** - * @var \RainLoop\Providers\Suggestions\ISuggestions + * @var \RainLoop\Providers\Suggestions\ISuggestions[] */ - private $oDriver; + private $aDrivers; /** - * @param \RainLoop\Providers\Suggestions\ISuggestions|null $oDriver = null + * @param \RainLoop\Providers\Suggestions\ISuggestions[]|null $aDriver = null * * @return void */ - public function __construct($oDriver = null) + public function __construct($aDriver = null) { - $this->oDriver = $oDriver; + if (\is_array($aDriver)) + { + $aDriver = \array_filter($aDriver, function ($oDriver) { + return $oDriver instanceof \RainLoop\Providers\Suggestions\ISuggestions; + }); + } + + $this->aDrivers = \is_array($aDriver) && 0 < \count($aDriver) ? $aDriver : null; } /** - * @param \RainLoop\Account $oAccount + * @param \RainLoop\Model\Account $oAccount * @param string $sQuery * @param int $iLimit = 20 * * @return array */ - public function Process(\RainLoop\Account $oAccount, $sQuery, $iLimit = 20) + public function Process($oAccount, $sQuery, $iLimit = 20) { - return $this->oDriver && $this->IsActive() && 0 < \strlen($sQuery) ? - $this->oDriver->Process($oAccount, $sQuery, $iLimit = 20) : array(); + $aResult = array(); + $aSuggestions = array(); + if ($oAccount instanceof \RainLoop\Model\Account && + $this->IsActive() && \is_array($this->aDrivers) && 0 < \strlen($sQuery)) + { + foreach ($this->aDrivers as $oDriver) + { + $aSubs = null; + if ($oDriver) + { + $aSubs = $oDriver->Process($oAccount, $sQuery, $iLimit); + if (\is_array($aSubs) && 0 < \count($aSubs)) + { + $aSuggestions = \array_merge($aSuggestions, $aSubs); + } + } + } + } + + $aCache = array(); + foreach ($aSuggestions as $aItem) // remove duplicates + { + $sLine = \implode('~~', $aItem); + if (!isset($aCache[$sLine])) + { + $aCache[$sLine] = true; + $aResult[] = $aItem; + } + } + + if ($iLimit < \count($aResult)) + { + $aResult = \array_slice($aResult, 0, $iLimit); + } + + return $aResult; } /** @@ -37,6 +78,6 @@ class Suggestions extends \RainLoop\Providers\AbstractProvider */ public function IsActive() { - return $this->oDriver instanceof \RainLoop\Providers\Suggestions\ISuggestions; + return \is_array($this->aDrivers) && 0 < \count($this->aDrivers); } } \ No newline at end of file diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/Suggestions/ISuggestions.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/Suggestions/ISuggestions.php index cbb8130d2..93050fbce 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/Suggestions/ISuggestions.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/Suggestions/ISuggestions.php @@ -9,7 +9,7 @@ interface ISuggestions * @param string $sQuery * @param int $iLimit = 20 * - * @return array + * @return array [['email@1', 'name_1'], ['email@2', 'name_2']] */ public function Process($oAccount, $sQuery, $iLimit = 20); } \ No newline at end of file diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/Suggestions/TestSuggestions.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/Suggestions/TestSuggestions.php index fd9cbfc9c..f1c640c46 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/Suggestions/TestSuggestions.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/Suggestions/TestSuggestions.php @@ -15,7 +15,7 @@ class TestSuggestions implements \RainLoop\Providers\Suggestions\ISuggestions { return array( array($oAccount->Email(), ''), - array('xxx@xxx', 'xxx') + array('email@domain.com', 'name') ); } }