mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-08-29 20:19:22 +03:00
Add pluggable identity system
This commit is contained in:
parent
0ec37b7e90
commit
5414ec542d
8 changed files with 418 additions and 185 deletions
|
|
@ -4,6 +4,9 @@ namespace RainLoop;
|
|||
|
||||
use RainLoop\Enumerations\UploadError;
|
||||
use RainLoop\Enumerations\UploadClientError;
|
||||
use RainLoop\Model\Identity;
|
||||
use RainLoop\Providers\Identities;
|
||||
use RainLoop\Providers\Storage\Enumerations\StorageType;
|
||||
|
||||
class Actions
|
||||
{
|
||||
|
|
@ -55,6 +58,11 @@ class Actions
|
|||
*/
|
||||
private $aCachers;
|
||||
|
||||
/**
|
||||
* @var Providers\Identities
|
||||
*/
|
||||
private $oIdentitiesProvider;
|
||||
|
||||
/**
|
||||
* @var \RainLoop\Providers\Storage
|
||||
*/
|
||||
|
|
@ -282,12 +290,6 @@ class Actions
|
|||
}
|
||||
break;
|
||||
case 'suggestions':
|
||||
|
||||
if (null === $mResult)
|
||||
{
|
||||
$mResult = array();
|
||||
}
|
||||
|
||||
break;
|
||||
case 'two-factor-auth':
|
||||
// Providers\TwoFactorAuth\TwoFactorAuthInterface
|
||||
|
|
@ -296,6 +298,12 @@ class Actions
|
|||
}
|
||||
}
|
||||
|
||||
// Always give the file provider as last for identities, it is the override
|
||||
if($sName === 'identities') {
|
||||
if($mResult === null) $mResult = [];
|
||||
$mResult[] = new Providers\Identities\FileIdentities($this->StorageProvider(true));
|
||||
}
|
||||
|
||||
foreach (\is_array($mResult) ? $mResult : array($mResult) as $oItem)
|
||||
{
|
||||
if ($oItem && \method_exists($oItem, 'SetLogger'))
|
||||
|
|
@ -633,10 +641,17 @@ class Actions
|
|||
|
||||
return $this->oStorageProvider;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function IdentitiesProvider() : Identities
|
||||
{
|
||||
if(null === $this->oIdentitiesProvider) {
|
||||
$this->oIdentitiesProvider = new Providers\Identities($this->fabrica('identities'));
|
||||
}
|
||||
|
||||
return $this->oIdentitiesProvider;
|
||||
}
|
||||
|
||||
public function SettingsProvider(bool $bLocal = false) : Providers\Settings
|
||||
{
|
||||
if ($bLocal)
|
||||
|
|
@ -659,8 +674,6 @@ class Actions
|
|||
|
||||
return $this->oSettingsProvider;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function FilesProvider() : Providers\Files
|
||||
|
|
@ -1867,88 +1880,6 @@ NewThemeLink IncludeCss TemplatesLink LangLink IncludeBackground PluginsLink Aut
|
|||
return $aAccounts;
|
||||
}
|
||||
|
||||
public function GetIdentities(Model\Account $oAccount) : array
|
||||
{
|
||||
$bAllowIdentities = $this->GetCapa(false, false,
|
||||
Enumerations\Capa::IDENTITIES, $oAccount);
|
||||
|
||||
$aIdentities = array();
|
||||
if ($oAccount)
|
||||
{
|
||||
$aSubIdentities = array();
|
||||
|
||||
$sData = $this->StorageProvider(true)->Get($oAccount,
|
||||
Providers\Storage\Enumerations\StorageType::CONFIG,
|
||||
'identities'
|
||||
);
|
||||
|
||||
if ('' !== $sData && '[' === \substr($sData, 0, 1))
|
||||
{
|
||||
$aSubIdentities = \json_decode($sData, true);
|
||||
}
|
||||
|
||||
$bHasAccountIdentity = false;
|
||||
|
||||
if (\is_array($aSubIdentities) && 0 < \count($aSubIdentities))
|
||||
{
|
||||
foreach ($aSubIdentities as $aItem)
|
||||
{
|
||||
$oItem = new Model\Identity();
|
||||
$oItem->FromJSON($aItem);
|
||||
|
||||
if ($oItem && $oItem->Validate())
|
||||
{
|
||||
if ($oItem->IsAccountIdentities())
|
||||
{
|
||||
$oItem->SetEmail($oAccount->Email());
|
||||
$bHasAccountIdentity = true;
|
||||
|
||||
\array_push($aIdentities, $oItem);
|
||||
}
|
||||
else if ($bAllowIdentities)
|
||||
{
|
||||
\array_push($aIdentities, $oItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$bHasAccountIdentity)
|
||||
{
|
||||
\array_unshift($aIdentities,
|
||||
new Model\Identity('', $oAccount->Email()));
|
||||
}
|
||||
|
||||
if (1 < \count($aIdentities) && $bAllowIdentities)
|
||||
{
|
||||
$sOrder = $this->StorageProvider()->Get($oAccount,
|
||||
Providers\Storage\Enumerations\StorageType::CONFIG,
|
||||
'accounts_identities_order'
|
||||
);
|
||||
|
||||
$aOrder = empty($sOrder) ? array() : \json_decode($sOrder, true);
|
||||
if (isset($aOrder['Identities']) && \is_array($aOrder['Identities']) &&
|
||||
1 < \count($aOrder['Identities']))
|
||||
{
|
||||
$aList = $aOrder['Identities'];
|
||||
foreach ($aList as $iIndex => $sItem)
|
||||
{
|
||||
if ('' === $sItem)
|
||||
{
|
||||
$aList[$iIndex] = '---';
|
||||
}
|
||||
}
|
||||
|
||||
\usort($aIdentities, function ($a, $b) use ($aList) {
|
||||
return \array_search($a->Id(true), $aList) < \array_search($b->Id(true), $aList) ? -1 : 1;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $aIdentities;
|
||||
}
|
||||
|
||||
public function GetIdentityByID(Model\Account $oAccount, string $sID, bool $bFirstOnEmpty = false) : ?Model\Identity
|
||||
{
|
||||
$aIdentities = $this->GetIdentities($oAccount);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,11 @@ namespace RainLoop\Actions;
|
|||
|
||||
use \RainLoop\Enumerations\Capa;
|
||||
use \RainLoop\Exceptions\ClientException;
|
||||
use \RainLoop\Model\Account;
|
||||
use \RainLoop\Model\Identity;
|
||||
use \RainLoop\Notifications;
|
||||
use RainLoop\Providers\Storage\Enumerations\StorageType;
|
||||
use function trim;
|
||||
|
||||
trait Accounts
|
||||
{
|
||||
|
|
@ -25,7 +29,7 @@ trait Accounts
|
|||
|
||||
$aAccounts = $this->GetAccounts($oAccount);
|
||||
|
||||
$sEmail = \trim($this->GetActionParam('Email', ''));
|
||||
$sEmail = trim($this->GetActionParam('Email', ''));
|
||||
$sPassword = $this->GetActionParam('Password', '');
|
||||
$bNew = '1' === (string) $this->GetActionParam('New', '1');
|
||||
|
||||
|
|
@ -65,7 +69,7 @@ trait Accounts
|
|||
}
|
||||
|
||||
$sParentEmail = $oAccount->ParentEmailHelper();
|
||||
$sEmailToDelete = \trim($this->GetActionParam('EmailToDelete', ''));
|
||||
$sEmailToDelete = trim($this->GetActionParam('EmailToDelete', ''));
|
||||
$sEmailToDelete = \MailSo\Base\Utils::IdnToAscii($sEmailToDelete, true);
|
||||
|
||||
$aAccounts = $this->GetAccounts($oAccount);
|
||||
|
|
@ -104,32 +108,8 @@ trait Accounts
|
|||
throw new ClientException(Notifications::InvalidInputArgument);
|
||||
}
|
||||
|
||||
$aIdentities = $this->GetIdentities($oAccount);
|
||||
|
||||
$bAdded = false;
|
||||
$aIdentitiesForSave = array();
|
||||
foreach ($aIdentities as $oItem)
|
||||
{
|
||||
if ($oItem)
|
||||
{
|
||||
if ($oItem->Id() === $oIdentity->Id())
|
||||
{
|
||||
$aIdentitiesForSave[] = $oIdentity;
|
||||
$bAdded = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aIdentitiesForSave[] = $oItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$bAdded)
|
||||
{
|
||||
$aIdentitiesForSave[] = $oIdentity;
|
||||
}
|
||||
|
||||
return $this->DefaultResponse(__FUNCTION__, $this->SetIdentities($oAccount, $aIdentitiesForSave));
|
||||
$this->IdentitiesProvider()->UpdateIdentity($oAccount, $oIdentity);
|
||||
return $this->DefaultResponse(__FUNCTION__, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -144,24 +124,14 @@ trait Accounts
|
|||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
||||
$sId = \trim($this->GetActionParam('IdToDelete', ''));
|
||||
$sId = trim($this->GetActionParam('IdToDelete', ''));
|
||||
if (empty($sId))
|
||||
{
|
||||
throw new ClientException(Notifications::UnknownError);
|
||||
}
|
||||
|
||||
$aNew = array();
|
||||
$aIdentities = $this->GetIdentities($oAccount);
|
||||
|
||||
foreach ($aIdentities as $oItem)
|
||||
{
|
||||
if ($oItem && $sId !== $oItem->Id())
|
||||
{
|
||||
$aNew[] = $oItem;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->DefaultResponse(__FUNCTION__, $this->SetIdentities($oAccount, $aNew));
|
||||
$this->IdentitiesProvider()->DeleteIdentity($oAccount, $sId);
|
||||
return $this->DefaultResponse(__FUNCTION__, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -214,26 +184,35 @@ trait Accounts
|
|||
));
|
||||
}
|
||||
|
||||
private function SetIdentities(\RainLoop\Model\Account $oAccount, array $aIdentities = array()) : bool
|
||||
{
|
||||
$bAllowIdentities = $this->GetCapa(false, false, Capa::IDENTITIES, $oAccount);
|
||||
/**
|
||||
* @param Account $account
|
||||
* @return Identity[]
|
||||
*/
|
||||
public function GetIdentities(Account $account) : array
|
||||
{
|
||||
if(!$account) return [];
|
||||
|
||||
$aResult = array();
|
||||
foreach ($aIdentities as $oItem)
|
||||
{
|
||||
if (!$bAllowIdentities && $oItem && !$oItem->IsAccountIdentities())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// A custom name for a single identity is also stored in this system
|
||||
$allowMultipleIdentities = $this->GetCapa(false, false, Capa::IDENTITIES, $account);
|
||||
|
||||
$aResult[] = $oItem->ToSimpleJSON();
|
||||
}
|
||||
// Get all identities
|
||||
$identities = $this->IdentitiesProvider()->GetIdentities($account, $allowMultipleIdentities);
|
||||
|
||||
return $this->StorageProvider(true)->Put($oAccount,
|
||||
\RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG,
|
||||
'identities',
|
||||
\json_encode($aResult)
|
||||
);
|
||||
}
|
||||
// Sort identities
|
||||
$orderString = $this->StorageProvider()->Get($account, StorageType::CONFIG, 'accounts_identities_order');
|
||||
$order = json_decode($orderString, true) ?? [];
|
||||
if(isset($order['Identities']) && is_array($order['Identities']) && count($order['Identities']) > 1) {
|
||||
$list = array_map(function($item) {
|
||||
if('' === $item) $item = '---';
|
||||
return $item;
|
||||
}, $order['Identities']);
|
||||
|
||||
usort($identities, function($a, $b) use ($list) {
|
||||
return array_search($a->Id(true), $list) < array_search($b->Id(true), $list) ? -1 : 1;
|
||||
});
|
||||
}
|
||||
|
||||
return $identities;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,42 +2,45 @@
|
|||
|
||||
namespace RainLoop\Model;
|
||||
|
||||
class Identity implements \JsonSerializable
|
||||
use JsonSerializable;
|
||||
use MailSo\Base\Utils;
|
||||
|
||||
class Identity implements JsonSerializable
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sId;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sId;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sEmail;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sEmail;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sName;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sReplyTo;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sReplyTo;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sBcc;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sBcc;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sSignature;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sSignature;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bSignatureInsertBefore;
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bSignatureInsertBefore;
|
||||
|
||||
function __construct(string $sId = '', string $sEmail = '')
|
||||
{
|
||||
|
|
@ -92,12 +95,48 @@ class Identity implements \JsonSerializable
|
|||
return $this->bSignatureInsertBefore;
|
||||
}
|
||||
|
||||
public function SetId(string $sId): Identity
|
||||
{
|
||||
$this->sId = $sId;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function SetName(string $sName): Identity
|
||||
{
|
||||
$this->sName = $sName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function SetReplyTo(string $sReplyTo): Identity
|
||||
{
|
||||
$this->sReplyTo = $sReplyTo;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function SetBcc(string $sBcc): Identity
|
||||
{
|
||||
$this->sBcc = $sBcc;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function SetSignature(string $sSignature): Identity
|
||||
{
|
||||
$this->sSignature = $sSignature;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function SetSignatureInsertBefore(bool $bSignatureInsertBefore): Identity
|
||||
{
|
||||
$this->bSignatureInsertBefore = $bSignatureInsertBefore;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function FromJSON(array $aData, bool $bAjax = false) : bool
|
||||
{
|
||||
if (!empty($aData['Email']))
|
||||
{
|
||||
$this->sId = !empty($aData['Id']) ? $aData['Id'] : '';
|
||||
$this->sEmail = $bAjax ? \MailSo\Base\Utils::IdnToAscii($aData['Email'], true) : $aData['Email'];
|
||||
$this->sEmail = $bAjax ? Utils::IdnToAscii($aData['Email'], true) : $aData['Email'];
|
||||
$this->sName = isset($aData['Name']) ? $aData['Name'] : '';
|
||||
$this->sReplyTo = !empty($aData['ReplyTo']) ? $aData['ReplyTo'] : '';
|
||||
$this->sBcc = !empty($aData['Bcc']) ? $aData['Bcc'] : '';
|
||||
|
|
@ -127,9 +166,8 @@ class Identity implements \JsonSerializable
|
|||
public function jsonSerialize()
|
||||
{
|
||||
return array(
|
||||
// '@Object' => 'Object/Identity',
|
||||
'Id' => $this->Id(),
|
||||
'Email' => \MailSo\Base\Utils::IdnToUtf8($this->Email()),
|
||||
'Email' => Utils::IdnToUtf8($this->Email()),
|
||||
'Name' => $this->Name(),
|
||||
'ReplyTo' => $this->ReplyTo(),
|
||||
'Bcc' => $this->Bcc(),
|
||||
|
|
|
|||
136
snappymail/v/0.0.0/app/libraries/RainLoop/Providers/Identities.php
Executable file
136
snappymail/v/0.0.0/app/libraries/RainLoop/Providers/Identities.php
Executable file
|
|
@ -0,0 +1,136 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers;
|
||||
|
||||
use RainLoop\Model\Account;
|
||||
use RainLoop\Model\Identity;
|
||||
use RainLoop\Providers\Identities\IIdentities;
|
||||
|
||||
class Identities extends AbstractProvider
|
||||
{
|
||||
/** @var IIdentities[] */
|
||||
private $drivers;
|
||||
|
||||
/** @var Identity[][][] */
|
||||
private $identitiesPerDriverPerAccount;
|
||||
|
||||
/**
|
||||
* Identities constructor.
|
||||
* @param IIdentities[] $drivers
|
||||
*/
|
||||
public function __construct(?array $drivers = null)
|
||||
{
|
||||
if($drivers === null) $drivers = [];
|
||||
|
||||
$this->drivers = array_filter($drivers, function($driver) {
|
||||
return $driver instanceof IIdentities;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param bool $allowMultipleIdentities
|
||||
* @return Identity[]
|
||||
*/
|
||||
public function GetIdentities(Account $account, bool $allowMultipleIdentities) : array {
|
||||
// Find all identities stored in the system
|
||||
$identities = $this->MergeIdentitiesPerDriver($this->GetIdentiesPerDriver($account));
|
||||
|
||||
file_put_contents('php://stderr', print_r($this->identitiesPerDriverPerAccount, TRUE));
|
||||
|
||||
// Find the primary identity
|
||||
$primaryIdentity = array_filter($identities, function($identity) {
|
||||
return $identity->IsAccountIdentities();
|
||||
})[0];
|
||||
|
||||
// If no primary identity is found, generate default one from account info
|
||||
if($primaryIdentity === null)
|
||||
$identities[] = $primaryIdentity = new Identity('', $account->Email());
|
||||
|
||||
// Return only primary identity or all identities
|
||||
return $allowMultipleIdentities ? $identities : [$primaryIdentity];
|
||||
}
|
||||
|
||||
public function UpdateIdentity(Account $account, Identity $identity) {
|
||||
// Find all identities in the system
|
||||
$identities = &$this->GetIdentiesPerDriver($account);
|
||||
|
||||
$isNew = true;
|
||||
foreach($this->drivers as $driver) {
|
||||
if(!$driver->SupportsStore()) continue;
|
||||
|
||||
$driverIdentities = &$identities[$driver->Name()];
|
||||
if(!isset($driverIdentities[$identity->Id(true)]))
|
||||
continue;
|
||||
|
||||
// We update the identity in all writeable stores
|
||||
$driverIdentities[$identity->Id(true)] = $identity;
|
||||
$isNew = false;
|
||||
|
||||
$driver->SetIdentities($account, $driverIdentities);
|
||||
}
|
||||
|
||||
// If it is a new identity we add it to any storage driver
|
||||
if($isNew) {
|
||||
// Pick any storage driver to store the result, typically only file storage
|
||||
$storageDriver = array_filter($this->drivers, function($driver) {
|
||||
return $driver->SupportsStore();
|
||||
})[0];
|
||||
|
||||
$identities[$storageDriver->Name()][$identity->Id(true)] = $identity;
|
||||
$storageDriver->SetIdentities($account, $identities[$storageDriver->Name()]);
|
||||
}
|
||||
}
|
||||
|
||||
public function DeleteIdentity(Account $account, string $identityId) {
|
||||
// On deletion, we remove the identity from all drivers if they are writeable.
|
||||
$identities = &$this->GetIdentiesPerDriver($account);
|
||||
|
||||
foreach($this->drivers as $driver) {
|
||||
if(!$driver->SupportsStore()) continue;
|
||||
|
||||
$driverIdentities = &$identities[$driver->Name()];
|
||||
if(!isset($driverIdentities[$identityId]))
|
||||
continue;
|
||||
|
||||
// We found it, so remove and update storage if relevant
|
||||
$identity = $driverIdentities[$identityId];
|
||||
if($identity->IsAccountIdentities()) continue; // never remove the primary identity
|
||||
|
||||
unset($driverIdentities[$identityId]);
|
||||
$driver->SetIdentities($account, $driverIdentities);
|
||||
}
|
||||
}
|
||||
|
||||
private function &GetIdentiesPerDriver(Account $account) : array {
|
||||
if(isset($this->identitiesPerDriverPerAccount[$account->Email()]))
|
||||
return $this->identitiesPerDriverPerAccount[$account->Email()];
|
||||
|
||||
$identitiesPerDriver = [];
|
||||
foreach($this->drivers as $driver) {
|
||||
$driverIdentities = $driver->GetIdentities($account);
|
||||
|
||||
foreach($driverIdentities as $identity)
|
||||
$identitiesPerDriver[$driver->Name()][$identity->Id(true)] = $identity;
|
||||
}
|
||||
|
||||
$this->identitiesPerDriverPerAccount[$account->Email()] = $identitiesPerDriver;
|
||||
return $this->identitiesPerDriverPerAccount[$account->Email()];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Identity[][] $identitiesPerDriver
|
||||
* @return Identity[]
|
||||
*/
|
||||
private function MergeIdentitiesPerDriver(array $identitiesPerDriver) : array {
|
||||
// Merge logic for the identities
|
||||
$identities = [];
|
||||
foreach($this->drivers as $driver) {
|
||||
// Merge and replace by key
|
||||
foreach($identitiesPerDriver[$driver->Name()] as $identity)
|
||||
$identities[$identity->Id(true)] = $identity;
|
||||
}
|
||||
|
||||
return array_values($identities);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers\Identities;
|
||||
|
||||
use RainLoop\Model\Account;
|
||||
use RainLoop\Model\Identity;
|
||||
use RainLoop\Providers\Storage;
|
||||
|
||||
class FileIdentities implements IIdentities
|
||||
{
|
||||
/**
|
||||
* @var Storage
|
||||
*/
|
||||
private $localStorageProvider;
|
||||
|
||||
/**
|
||||
* FileIdentities constructor.
|
||||
* @param Storage $localStorageProvider
|
||||
*/
|
||||
public function __construct(Storage $localStorageProvider)
|
||||
{
|
||||
$this->localStorageProvider = $localStorageProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetIdentities(Account $account): array
|
||||
{
|
||||
if(!$account) return [];
|
||||
|
||||
$data = $this->localStorageProvider->Get($account, Storage\Enumerations\StorageType::CONFIG, 'identities');
|
||||
$subIdentities = json_decode($data, true) ?? [];
|
||||
$result = [];
|
||||
|
||||
foreach($subIdentities as $subIdentity) {
|
||||
$identity = new Identity();
|
||||
$identity->FromJSON($subIdentity);
|
||||
|
||||
if(!$identity->Validate()) continue;
|
||||
if($identity->IsAccountIdentities()) $identity->SetEmail($account->Email());
|
||||
$result[] = $identity;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function SetIdentities(Account $account, array $identities)
|
||||
{
|
||||
$jsons = array_map(function($identity) { return $identity->ToSimpleJSON(); }, $identities);
|
||||
$this->localStorageProvider->Put($account, Storage\Enumerations\StorageType::CONFIG, 'identities', json_encode($jsons));
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function SupportsStore() : bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function Name(): string
|
||||
{
|
||||
return "File";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers\Identities;
|
||||
|
||||
use RainLoop\Model\Account;
|
||||
use RainLoop\Model\Identity;
|
||||
|
||||
interface IIdentities
|
||||
{
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return Identity[]
|
||||
*/
|
||||
public function GetIdentities(Account $account) : array;
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Identity[] $identities
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function SetIdentities(Account $account, array $identities);
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function SupportsStore() : bool;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Name() : string;
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop\Providers\Identities;
|
||||
|
||||
use RainLoop\Exceptions\Exception;
|
||||
use RainLoop\Model\Account;
|
||||
use RainLoop\Model\Identity;
|
||||
|
||||
class TestIdentities implements IIdentities
|
||||
{
|
||||
/**
|
||||
* @param Account $account
|
||||
* @return Identity[]
|
||||
*/
|
||||
public function GetIdentities(Account $account): array
|
||||
{
|
||||
$oIdentity = new Identity('', $account->Email());
|
||||
$oIdentity->SetName("Test Name");
|
||||
|
||||
return [$oIdentity];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Identity[] $identities
|
||||
*
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
public function SetIdentities(Account $account, array $identities)
|
||||
{
|
||||
throw new Exception("Not implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function SupportsStore() : bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function Name() : string { return "Test"; }
|
||||
}
|
||||
|
|
@ -2,9 +2,11 @@
|
|||
|
||||
namespace RainLoop\Providers\Suggestions;
|
||||
|
||||
class TestSuggestions implements \RainLoop\Providers\Suggestions\ISuggestions
|
||||
use RainLoop\Model\Account;
|
||||
|
||||
class TestSuggestions implements ISuggestions
|
||||
{
|
||||
public function Process(\RainLoop\Model\Account $oAccount, string $sQuery, int $iLimit = 20) : array
|
||||
public function Process(Account $oAccount, string $sQuery, int $iLimit = 20) : array
|
||||
{
|
||||
return array(
|
||||
array($oAccount->Email(), ''),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue